ag-ui-validate 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +229 -0
  3. package/dist/catalog-BglXBNbL.js +472 -0
  4. package/dist/catalog-BglXBNbL.js.map +1 -0
  5. package/dist/catalog-Ci9dqc1a.cjs +495 -0
  6. package/dist/catalog-Ci9dqc1a.cjs.map +1 -0
  7. package/dist/cli.js +2783 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/index-Hmqj3r_r.d.cts +52 -0
  10. package/dist/index-oNG1kOp9.d.ts +52 -0
  11. package/dist/index.cjs +14 -0
  12. package/dist/index.d.cts +3 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.js +3 -0
  15. package/dist/report.cjs +139 -0
  16. package/dist/report.cjs.map +1 -0
  17. package/dist/report.d.cts +85 -0
  18. package/dist/report.d.ts +85 -0
  19. package/dist/report.js +134 -0
  20. package/dist/report.js.map +1 -0
  21. package/dist/src-HmI-kxef.cjs +1596 -0
  22. package/dist/src-HmI-kxef.cjs.map +1 -0
  23. package/dist/src-rGZ2G4qA.js +1555 -0
  24. package/dist/src-rGZ2G4qA.js.map +1 -0
  25. package/dist/transport.cjs +329 -0
  26. package/dist/transport.cjs.map +1 -0
  27. package/dist/transport.d.cts +89 -0
  28. package/dist/transport.d.ts +89 -0
  29. package/dist/transport.js +323 -0
  30. package/dist/transport.js.map +1 -0
  31. package/dist/types-oH_QTnn2.d.cts +148 -0
  32. package/dist/types-oH_QTnn2.d.ts +148 -0
  33. package/dist/vitest.d.ts +28 -0
  34. package/dist/vitest.js +2089 -0
  35. package/dist/vitest.js.map +1 -0
  36. package/package.json +127 -0
  37. package/src/cli-args.ts +202 -0
  38. package/src/cli.ts +147 -0
  39. package/src/index.ts +465 -0
  40. package/src/protocol/event-table.ts +316 -0
  41. package/src/protocol/jsonpatch.ts +220 -0
  42. package/src/report/index.ts +10 -0
  43. package/src/report/json.ts +20 -0
  44. package/src/report/junit.ts +56 -0
  45. package/src/report/pretty.ts +59 -0
  46. package/src/report/sarif.ts +109 -0
  47. package/src/rules/catalog.json +431 -0
  48. package/src/rules/catalog.ts +84 -0
  49. package/src/rules/checks/context.ts +117 -0
  50. package/src/rules/checks/lifecycle.ts +59 -0
  51. package/src/rules/checks/reasoning.ts +97 -0
  52. package/src/rules/checks/state.ts +72 -0
  53. package/src/rules/checks/text.ts +109 -0
  54. package/src/rules/checks/toolcalls.ts +167 -0
  55. package/src/rules/checks/transport.ts +17 -0
  56. package/src/transport/index.ts +331 -0
  57. package/src/transport/ndjson.ts +25 -0
  58. package/src/transport/sse.ts +126 -0
  59. package/src/types.ts +136 -0
  60. package/src/vitest/index.ts +19 -0
  61. package/src/vitest/matcher.ts +77 -0
@@ -0,0 +1,139 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_catalog = require("./catalog-Ci9dqc1a.cjs");
3
+ //#region src/report/pretty.ts
4
+ const SYMBOL = {
5
+ error: "✖",
6
+ warning: "⚠",
7
+ info: "ℹ"
8
+ };
9
+ const SGR = {
10
+ error: "31",
11
+ warning: "33",
12
+ info: "36"
13
+ };
14
+ function paint(code, s, on) {
15
+ return on ? `\x1b[${code}m${s}\x1b[0m` : s;
16
+ }
17
+ function formatDiagnosticLine(d, opts) {
18
+ const where = d.eventIndex >= 0 ? `event ${d.eventIndex}` : "—";
19
+ const head = paint(SGR[d.severity], `${SYMBOL[d.severity]} ${d.rule}`, opts.color);
20
+ const meta = paint("2", `${d.severity.padEnd(7)} ${where.padEnd(10)}`, opts.color);
21
+ const cite = paint("2", ` ↳ ${d.specUrl}`, opts.color);
22
+ return `${head} ${meta} ${d.message}\n${cite}`;
23
+ }
24
+ function count(n, noun) {
25
+ return `${n} ${noun}${n === 1 ? "" : "s"}`;
26
+ }
27
+ function formatReportSummary(report, opts) {
28
+ const { errors, warnings, info } = report.summary;
29
+ const lines = [];
30
+ if (errors + warnings + info === 0) lines.push(paint("32", `✔ no conformance violations across ${count(report.eventCount, "event")}`, opts.color));
31
+ else lines.push(`${count(errors, "error")}, ${count(warnings, "warning")}, ${info} info across ${count(report.eventCount, "event")}`);
32
+ const features = Object.entries(report.features);
33
+ const exercised = features.filter(([, s]) => s === "exercised").map(([f]) => f);
34
+ const suffix = exercised.length > 0 ? `: ${exercised.join(", ")}` : "";
35
+ lines.push(`${exercised.length} of ${features.length} AG-UI features exercised${suffix}`);
36
+ if (report.skipped.length > 0) {
37
+ lines.push(`${count(report.skipped.length, "rule")} not evaluated:`);
38
+ for (const s of report.skipped) lines.push(paint("2", ` – ${s.rule}: ${s.reason}`, opts.color));
39
+ }
40
+ for (const e of report.internalErrors) lines.push(paint("31", `! internal validator error: ${e}`, opts.color));
41
+ return lines.join("\n");
42
+ }
43
+ //#endregion
44
+ //#region src/report/json.ts
45
+ function toJsonReport(report, opts) {
46
+ const doc = {
47
+ tool: opts.tool,
48
+ ...report
49
+ };
50
+ if (opts.target !== void 0) doc.target = opts.target;
51
+ return doc;
52
+ }
53
+ //#endregion
54
+ //#region src/report/sarif.ts
55
+ const LEVEL = {
56
+ error: "error",
57
+ warning: "warning",
58
+ info: "note"
59
+ };
60
+ function toSarif(report, opts) {
61
+ const rules = /* @__PURE__ */ new Map();
62
+ for (const d of report.diagnostics) {
63
+ if (rules.has(d.rule)) continue;
64
+ const entry = {
65
+ id: d.rule,
66
+ helpUri: d.specUrl
67
+ };
68
+ const catalog = require_catalog.RULES.get(d.rule);
69
+ if (catalog !== void 0) {
70
+ entry.shortDescription = { text: catalog.title };
71
+ entry.defaultConfiguration = { level: LEVEL[catalog.severity] };
72
+ }
73
+ rules.set(d.rule, entry);
74
+ }
75
+ const results = report.diagnostics.map((d) => ({
76
+ ruleId: d.rule,
77
+ level: LEVEL[d.severity],
78
+ message: { text: d.message },
79
+ locations: opts.artifactUri !== void 0 && d.eventIndex >= 0 ? [{ physicalLocation: {
80
+ artifactLocation: { uri: opts.artifactUri },
81
+ region: { startLine: d.eventIndex + 1 }
82
+ } }] : []
83
+ }));
84
+ return {
85
+ $schema: "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json",
86
+ version: "2.1.0",
87
+ runs: [{
88
+ tool: { driver: {
89
+ name: "ag-ui-validate",
90
+ version: opts.toolVersion,
91
+ informationUri: "https://github.com/langport-dev/ag-ui-validate",
92
+ rules: [...rules.values()]
93
+ } },
94
+ results
95
+ }]
96
+ };
97
+ }
98
+ //#endregion
99
+ //#region src/report/junit.ts
100
+ function esc(s) {
101
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
102
+ }
103
+ function toJUnit(report, opts) {
104
+ const lines = ["<?xml version=\"1.0\" encoding=\"UTF-8\"?>"];
105
+ const suite = esc(opts.name);
106
+ if (report.diagnostics.length === 0) {
107
+ lines.push("<testsuites name=\"ag-ui-validate\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\">");
108
+ lines.push(` <testsuite name="${suite}" tests="1" failures="0" errors="0" skipped="0">`);
109
+ lines.push(` <testcase name="AG-UI conformance: no violations across ${report.eventCount} events" classname="${suite}"/>`);
110
+ lines.push(" </testsuite>");
111
+ lines.push("</testsuites>");
112
+ return `${lines.join("\n")}\n`;
113
+ }
114
+ const failures = report.diagnostics.filter((d) => d.severity === "error").length;
115
+ const skipped = report.diagnostics.length - failures;
116
+ const counts = `tests="${report.diagnostics.length}" failures="${failures}" errors="0" skipped="${skipped}"`;
117
+ lines.push(`<testsuites name="ag-ui-validate" ${counts}>`);
118
+ lines.push(` <testsuite name="${suite}" ${counts}>`);
119
+ for (const d of report.diagnostics) {
120
+ const where = d.eventIndex >= 0 ? `event ${d.eventIndex}` : "stream";
121
+ const name = esc(`${d.rule} (${where})`);
122
+ lines.push(` <testcase name="${name}" classname="${suite}">`);
123
+ const body = `${esc(d.message)}\n${esc(d.specUrl)}`;
124
+ if (d.severity === "error") lines.push(` <failure message="${esc(d.message)}">${body}</failure>`);
125
+ else lines.push(` <skipped message="${esc(`${d.severity}: ${d.message}`)}">${body}</skipped>`);
126
+ lines.push(" </testcase>");
127
+ }
128
+ lines.push(" </testsuite>");
129
+ lines.push("</testsuites>");
130
+ return `${lines.join("\n")}\n`;
131
+ }
132
+ //#endregion
133
+ exports.formatDiagnosticLine = formatDiagnosticLine;
134
+ exports.formatReportSummary = formatReportSummary;
135
+ exports.toJUnit = toJUnit;
136
+ exports.toJsonReport = toJsonReport;
137
+ exports.toSarif = toSarif;
138
+
139
+ //# sourceMappingURL=report.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.cjs","names":["RULES"],"sources":["../src/report/pretty.ts","../src/report/json.ts","../src/report/sarif.ts","../src/report/junit.ts"],"sourcesContent":["// Human-readable output. Pure string formatting — the CLI decides where it\n// goes and whether a TTY wants color.\nimport type { Diagnostic, Report, Severity } from \"../types.js\"\n\nexport interface PrettyOptions {\n color: boolean\n}\n\nconst SYMBOL: Record<Severity, string> = { error: \"✖\", warning: \"⚠\", info: \"ℹ\" }\nconst SGR: Record<Severity, string> = { error: \"31\", warning: \"33\", info: \"36\" }\n\nfunction paint(code: string, s: string, on: boolean): string {\n return on ? `\\x1b[${code}m${s}\\x1b[0m` : s\n}\n\nexport function formatDiagnosticLine(d: Diagnostic, opts: PrettyOptions): string {\n const where = d.eventIndex >= 0 ? `event ${d.eventIndex}` : \"—\"\n const head = paint(SGR[d.severity], `${SYMBOL[d.severity]} ${d.rule}`, opts.color)\n const meta = paint(\"2\", `${d.severity.padEnd(7)} ${where.padEnd(10)}`, opts.color)\n const cite = paint(\"2\", ` ↳ ${d.specUrl}`, opts.color)\n return `${head} ${meta} ${d.message}\\n${cite}`\n}\n\nfunction count(n: number, noun: string): string {\n return `${n} ${noun}${n === 1 ? \"\" : \"s\"}`\n}\n\nexport function formatReportSummary(report: Report, opts: PrettyOptions): string {\n const { errors, warnings, info } = report.summary\n const lines: string[] = []\n\n if (errors + warnings + info === 0) {\n lines.push(\n paint(\"32\", `✔ no conformance violations across ${count(report.eventCount, \"event\")}`, opts.color),\n )\n } else {\n lines.push(\n `${count(errors, \"error\")}, ${count(warnings, \"warning\")}, ${info} info across ${count(report.eventCount, \"event\")}`,\n )\n }\n\n const features = Object.entries(report.features)\n const exercised = features.filter(([, s]) => s === \"exercised\").map(([f]) => f)\n const suffix = exercised.length > 0 ? `: ${exercised.join(\", \")}` : \"\"\n lines.push(`${exercised.length} of ${features.length} AG-UI features exercised${suffix}`)\n\n if (report.skipped.length > 0) {\n lines.push(`${count(report.skipped.length, \"rule\")} not evaluated:`)\n for (const s of report.skipped) {\n lines.push(paint(\"2\", ` – ${s.rule}: ${s.reason}`, opts.color))\n }\n }\n\n for (const e of report.internalErrors) {\n lines.push(paint(\"31\", `! internal validator error: ${e}`, opts.color))\n }\n\n return lines.join(\"\\n\")\n}\n","// Machine-readable report: the core Report plus tool identification, so a\n// stored document is self-describing.\nimport type { Report } from \"../types.js\"\n\nexport interface JsonReportOptions {\n tool: { name: string; version: string }\n /** What was validated: URL, file path, or \"stdin\". */\n target?: string\n}\n\nexport interface JsonReportDocument extends Report {\n tool: { name: string; version: string }\n target?: string\n}\n\nexport function toJsonReport(report: Report, opts: JsonReportOptions): JsonReportDocument {\n const doc: JsonReportDocument = { tool: opts.tool, ...report }\n if (opts.target !== undefined) doc.target = opts.target\n return doc\n}\n","// SARIF 2.1.0 output for code-scanning integrations (e.g. GitHub).\n// Level mapping: error→error, warning→warning, info→note. When the input was a\n// line-oriented file (JSONL/captured SSE fed line-per-event is not guaranteed,\n// so only the caller knows), event N is reported at line N+1 via artifactUri.\nimport { RULES } from \"../rules/catalog.js\"\nimport type { Diagnostic, Report } from \"../types.js\"\n\nexport interface SarifOptions {\n toolVersion: string\n /** URI of the validated artifact; enables line-based locations. */\n artifactUri?: string\n}\n\nexport type SarifLevel = \"error\" | \"warning\" | \"note\"\n\nexport interface SarifResult {\n ruleId: string\n level: SarifLevel\n message: { text: string }\n locations: Array<{\n physicalLocation: {\n artifactLocation: { uri: string }\n region: { startLine: number }\n }\n }>\n}\n\nexport interface SarifLog {\n $schema: string\n version: \"2.1.0\"\n runs: Array<{\n tool: {\n driver: {\n name: string\n version: string\n informationUri: string\n rules: Array<{\n id: string\n helpUri: string\n shortDescription?: { text: string }\n defaultConfiguration?: { level: SarifLevel }\n }>\n }\n }\n results: SarifResult[]\n }>\n}\n\nconst LEVEL: Record<Diagnostic[\"severity\"], SarifLevel> = {\n error: \"error\",\n warning: \"warning\",\n info: \"note\",\n}\n\ntype SarifRule = {\n id: string\n helpUri: string\n shortDescription?: { text: string }\n defaultConfiguration?: { level: SarifLevel }\n}\n\nexport function toSarif(report: Report, opts: SarifOptions): SarifLog {\n const rules = new Map<string, SarifRule>()\n for (const d of report.diagnostics) {\n if (rules.has(d.rule)) continue\n const entry: SarifRule = { id: d.rule, helpUri: d.specUrl }\n const catalog = RULES.get(d.rule)\n if (catalog !== undefined) {\n entry.shortDescription = { text: catalog.title }\n entry.defaultConfiguration = { level: LEVEL[catalog.severity] }\n }\n rules.set(d.rule, entry)\n }\n\n const results: SarifResult[] = report.diagnostics.map((d) => ({\n ruleId: d.rule,\n level: LEVEL[d.severity],\n message: { text: d.message },\n locations:\n opts.artifactUri !== undefined && d.eventIndex >= 0\n ? [\n {\n physicalLocation: {\n artifactLocation: { uri: opts.artifactUri },\n region: { startLine: d.eventIndex + 1 },\n },\n },\n ]\n : [],\n }))\n\n return {\n $schema: \"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json\",\n version: \"2.1.0\",\n runs: [\n {\n tool: {\n driver: {\n name: \"ag-ui-validate\",\n version: opts.toolVersion,\n informationUri: \"https://github.com/langport-dev/ag-ui-validate\",\n rules: [...rules.values()],\n },\n },\n results,\n },\n ],\n }\n}\n","// JUnit XML output for CI systems. One testcase per finding: errors are\n// <failure>, warnings and info are <skipped> (visible but not build-breaking —\n// the exit code, not the XML, decides pass/fail). A clean report is a single\n// passing testcase so the suite is never empty.\nimport type { Report } from \"../types.js\"\n\nexport interface JUnitOptions {\n /** Suite name — typically the validated target. */\n name: string\n}\n\nfunction esc(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\")\n}\n\nexport function toJUnit(report: Report, opts: JUnitOptions): string {\n const lines: string[] = ['<?xml version=\"1.0\" encoding=\"UTF-8\"?>']\n const suite = esc(opts.name)\n\n if (report.diagnostics.length === 0) {\n lines.push('<testsuites name=\"ag-ui-validate\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\">')\n lines.push(` <testsuite name=\"${suite}\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\">`)\n lines.push(\n ` <testcase name=\"AG-UI conformance: no violations across ${report.eventCount} events\" classname=\"${suite}\"/>`,\n )\n lines.push(\" </testsuite>\")\n lines.push(\"</testsuites>\")\n return `${lines.join(\"\\n\")}\\n`\n }\n\n const failures = report.diagnostics.filter((d) => d.severity === \"error\").length\n const skipped = report.diagnostics.length - failures\n const counts = `tests=\"${report.diagnostics.length}\" failures=\"${failures}\" errors=\"0\" skipped=\"${skipped}\"`\n lines.push(`<testsuites name=\"ag-ui-validate\" ${counts}>`)\n lines.push(` <testsuite name=\"${suite}\" ${counts}>`)\n for (const d of report.diagnostics) {\n const where = d.eventIndex >= 0 ? `event ${d.eventIndex}` : \"stream\"\n const name = esc(`${d.rule} (${where})`)\n lines.push(` <testcase name=\"${name}\" classname=\"${suite}\">`)\n const body = `${esc(d.message)}\\n${esc(d.specUrl)}`\n if (d.severity === \"error\") {\n lines.push(` <failure message=\"${esc(d.message)}\">${body}</failure>`)\n } else {\n lines.push(` <skipped message=\"${esc(`${d.severity}: ${d.message}`)}\">${body}</skipped>`)\n }\n lines.push(\" </testcase>\")\n }\n lines.push(\" </testsuite>\")\n lines.push(\"</testsuites>\")\n return `${lines.join(\"\\n\")}\\n`\n}\n"],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ import { o as Report, r as Diagnostic } from "./types-oH_QTnn2.cjs";
2
+ //#region src/report/pretty.d.ts
3
+ interface PrettyOptions {
4
+ color: boolean;
5
+ }
6
+ declare function formatDiagnosticLine(d: Diagnostic, opts: PrettyOptions): string;
7
+ declare function formatReportSummary(report: Report, opts: PrettyOptions): string;
8
+ //#endregion
9
+ //#region src/report/json.d.ts
10
+ interface JsonReportOptions {
11
+ tool: {
12
+ name: string;
13
+ version: string;
14
+ };
15
+ /** What was validated: URL, file path, or "stdin". */
16
+ target?: string;
17
+ }
18
+ interface JsonReportDocument extends Report {
19
+ tool: {
20
+ name: string;
21
+ version: string;
22
+ };
23
+ target?: string;
24
+ }
25
+ declare function toJsonReport(report: Report, opts: JsonReportOptions): JsonReportDocument;
26
+ //#endregion
27
+ //#region src/report/sarif.d.ts
28
+ interface SarifOptions {
29
+ toolVersion: string;
30
+ /** URI of the validated artifact; enables line-based locations. */
31
+ artifactUri?: string;
32
+ }
33
+ type SarifLevel = "error" | "warning" | "note";
34
+ interface SarifResult {
35
+ ruleId: string;
36
+ level: SarifLevel;
37
+ message: {
38
+ text: string;
39
+ };
40
+ locations: Array<{
41
+ physicalLocation: {
42
+ artifactLocation: {
43
+ uri: string;
44
+ };
45
+ region: {
46
+ startLine: number;
47
+ };
48
+ };
49
+ }>;
50
+ }
51
+ interface SarifLog {
52
+ $schema: string;
53
+ version: "2.1.0";
54
+ runs: Array<{
55
+ tool: {
56
+ driver: {
57
+ name: string;
58
+ version: string;
59
+ informationUri: string;
60
+ rules: Array<{
61
+ id: string;
62
+ helpUri: string;
63
+ shortDescription?: {
64
+ text: string;
65
+ };
66
+ defaultConfiguration?: {
67
+ level: SarifLevel;
68
+ };
69
+ }>;
70
+ };
71
+ };
72
+ results: SarifResult[];
73
+ }>;
74
+ }
75
+ declare function toSarif(report: Report, opts: SarifOptions): SarifLog;
76
+ //#endregion
77
+ //#region src/report/junit.d.ts
78
+ interface JUnitOptions {
79
+ /** Suite name — typically the validated target. */
80
+ name: string;
81
+ }
82
+ declare function toJUnit(report: Report, opts: JUnitOptions): string;
83
+ //#endregion
84
+ export { type JUnitOptions, type JsonReportDocument, type JsonReportOptions, type PrettyOptions, type SarifLevel, type SarifLog, type SarifOptions, type SarifResult, formatDiagnosticLine, formatReportSummary, toJUnit, toJsonReport, toSarif };
85
+ //# sourceMappingURL=report.d.cts.map
@@ -0,0 +1,85 @@
1
+ import { o as Report, r as Diagnostic } from "./types-oH_QTnn2.js";
2
+ //#region src/report/pretty.d.ts
3
+ interface PrettyOptions {
4
+ color: boolean;
5
+ }
6
+ declare function formatDiagnosticLine(d: Diagnostic, opts: PrettyOptions): string;
7
+ declare function formatReportSummary(report: Report, opts: PrettyOptions): string;
8
+ //#endregion
9
+ //#region src/report/json.d.ts
10
+ interface JsonReportOptions {
11
+ tool: {
12
+ name: string;
13
+ version: string;
14
+ };
15
+ /** What was validated: URL, file path, or "stdin". */
16
+ target?: string;
17
+ }
18
+ interface JsonReportDocument extends Report {
19
+ tool: {
20
+ name: string;
21
+ version: string;
22
+ };
23
+ target?: string;
24
+ }
25
+ declare function toJsonReport(report: Report, opts: JsonReportOptions): JsonReportDocument;
26
+ //#endregion
27
+ //#region src/report/sarif.d.ts
28
+ interface SarifOptions {
29
+ toolVersion: string;
30
+ /** URI of the validated artifact; enables line-based locations. */
31
+ artifactUri?: string;
32
+ }
33
+ type SarifLevel = "error" | "warning" | "note";
34
+ interface SarifResult {
35
+ ruleId: string;
36
+ level: SarifLevel;
37
+ message: {
38
+ text: string;
39
+ };
40
+ locations: Array<{
41
+ physicalLocation: {
42
+ artifactLocation: {
43
+ uri: string;
44
+ };
45
+ region: {
46
+ startLine: number;
47
+ };
48
+ };
49
+ }>;
50
+ }
51
+ interface SarifLog {
52
+ $schema: string;
53
+ version: "2.1.0";
54
+ runs: Array<{
55
+ tool: {
56
+ driver: {
57
+ name: string;
58
+ version: string;
59
+ informationUri: string;
60
+ rules: Array<{
61
+ id: string;
62
+ helpUri: string;
63
+ shortDescription?: {
64
+ text: string;
65
+ };
66
+ defaultConfiguration?: {
67
+ level: SarifLevel;
68
+ };
69
+ }>;
70
+ };
71
+ };
72
+ results: SarifResult[];
73
+ }>;
74
+ }
75
+ declare function toSarif(report: Report, opts: SarifOptions): SarifLog;
76
+ //#endregion
77
+ //#region src/report/junit.d.ts
78
+ interface JUnitOptions {
79
+ /** Suite name — typically the validated target. */
80
+ name: string;
81
+ }
82
+ declare function toJUnit(report: Report, opts: JUnitOptions): string;
83
+ //#endregion
84
+ export { type JUnitOptions, type JsonReportDocument, type JsonReportOptions, type PrettyOptions, type SarifLevel, type SarifLog, type SarifOptions, type SarifResult, formatDiagnosticLine, formatReportSummary, toJUnit, toJsonReport, toSarif };
85
+ //# sourceMappingURL=report.d.ts.map
package/dist/report.js ADDED
@@ -0,0 +1,134 @@
1
+ import { n as RULES } from "./catalog-BglXBNbL.js";
2
+ //#region src/report/pretty.ts
3
+ const SYMBOL = {
4
+ error: "✖",
5
+ warning: "⚠",
6
+ info: "ℹ"
7
+ };
8
+ const SGR = {
9
+ error: "31",
10
+ warning: "33",
11
+ info: "36"
12
+ };
13
+ function paint(code, s, on) {
14
+ return on ? `\x1b[${code}m${s}\x1b[0m` : s;
15
+ }
16
+ function formatDiagnosticLine(d, opts) {
17
+ const where = d.eventIndex >= 0 ? `event ${d.eventIndex}` : "—";
18
+ const head = paint(SGR[d.severity], `${SYMBOL[d.severity]} ${d.rule}`, opts.color);
19
+ const meta = paint("2", `${d.severity.padEnd(7)} ${where.padEnd(10)}`, opts.color);
20
+ const cite = paint("2", ` ↳ ${d.specUrl}`, opts.color);
21
+ return `${head} ${meta} ${d.message}\n${cite}`;
22
+ }
23
+ function count(n, noun) {
24
+ return `${n} ${noun}${n === 1 ? "" : "s"}`;
25
+ }
26
+ function formatReportSummary(report, opts) {
27
+ const { errors, warnings, info } = report.summary;
28
+ const lines = [];
29
+ if (errors + warnings + info === 0) lines.push(paint("32", `✔ no conformance violations across ${count(report.eventCount, "event")}`, opts.color));
30
+ else lines.push(`${count(errors, "error")}, ${count(warnings, "warning")}, ${info} info across ${count(report.eventCount, "event")}`);
31
+ const features = Object.entries(report.features);
32
+ const exercised = features.filter(([, s]) => s === "exercised").map(([f]) => f);
33
+ const suffix = exercised.length > 0 ? `: ${exercised.join(", ")}` : "";
34
+ lines.push(`${exercised.length} of ${features.length} AG-UI features exercised${suffix}`);
35
+ if (report.skipped.length > 0) {
36
+ lines.push(`${count(report.skipped.length, "rule")} not evaluated:`);
37
+ for (const s of report.skipped) lines.push(paint("2", ` – ${s.rule}: ${s.reason}`, opts.color));
38
+ }
39
+ for (const e of report.internalErrors) lines.push(paint("31", `! internal validator error: ${e}`, opts.color));
40
+ return lines.join("\n");
41
+ }
42
+ //#endregion
43
+ //#region src/report/json.ts
44
+ function toJsonReport(report, opts) {
45
+ const doc = {
46
+ tool: opts.tool,
47
+ ...report
48
+ };
49
+ if (opts.target !== void 0) doc.target = opts.target;
50
+ return doc;
51
+ }
52
+ //#endregion
53
+ //#region src/report/sarif.ts
54
+ const LEVEL = {
55
+ error: "error",
56
+ warning: "warning",
57
+ info: "note"
58
+ };
59
+ function toSarif(report, opts) {
60
+ const rules = /* @__PURE__ */ new Map();
61
+ for (const d of report.diagnostics) {
62
+ if (rules.has(d.rule)) continue;
63
+ const entry = {
64
+ id: d.rule,
65
+ helpUri: d.specUrl
66
+ };
67
+ const catalog = RULES.get(d.rule);
68
+ if (catalog !== void 0) {
69
+ entry.shortDescription = { text: catalog.title };
70
+ entry.defaultConfiguration = { level: LEVEL[catalog.severity] };
71
+ }
72
+ rules.set(d.rule, entry);
73
+ }
74
+ const results = report.diagnostics.map((d) => ({
75
+ ruleId: d.rule,
76
+ level: LEVEL[d.severity],
77
+ message: { text: d.message },
78
+ locations: opts.artifactUri !== void 0 && d.eventIndex >= 0 ? [{ physicalLocation: {
79
+ artifactLocation: { uri: opts.artifactUri },
80
+ region: { startLine: d.eventIndex + 1 }
81
+ } }] : []
82
+ }));
83
+ return {
84
+ $schema: "https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json",
85
+ version: "2.1.0",
86
+ runs: [{
87
+ tool: { driver: {
88
+ name: "ag-ui-validate",
89
+ version: opts.toolVersion,
90
+ informationUri: "https://github.com/langport-dev/ag-ui-validate",
91
+ rules: [...rules.values()]
92
+ } },
93
+ results
94
+ }]
95
+ };
96
+ }
97
+ //#endregion
98
+ //#region src/report/junit.ts
99
+ function esc(s) {
100
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
101
+ }
102
+ function toJUnit(report, opts) {
103
+ const lines = ["<?xml version=\"1.0\" encoding=\"UTF-8\"?>"];
104
+ const suite = esc(opts.name);
105
+ if (report.diagnostics.length === 0) {
106
+ lines.push("<testsuites name=\"ag-ui-validate\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\">");
107
+ lines.push(` <testsuite name="${suite}" tests="1" failures="0" errors="0" skipped="0">`);
108
+ lines.push(` <testcase name="AG-UI conformance: no violations across ${report.eventCount} events" classname="${suite}"/>`);
109
+ lines.push(" </testsuite>");
110
+ lines.push("</testsuites>");
111
+ return `${lines.join("\n")}\n`;
112
+ }
113
+ const failures = report.diagnostics.filter((d) => d.severity === "error").length;
114
+ const skipped = report.diagnostics.length - failures;
115
+ const counts = `tests="${report.diagnostics.length}" failures="${failures}" errors="0" skipped="${skipped}"`;
116
+ lines.push(`<testsuites name="ag-ui-validate" ${counts}>`);
117
+ lines.push(` <testsuite name="${suite}" ${counts}>`);
118
+ for (const d of report.diagnostics) {
119
+ const where = d.eventIndex >= 0 ? `event ${d.eventIndex}` : "stream";
120
+ const name = esc(`${d.rule} (${where})`);
121
+ lines.push(` <testcase name="${name}" classname="${suite}">`);
122
+ const body = `${esc(d.message)}\n${esc(d.specUrl)}`;
123
+ if (d.severity === "error") lines.push(` <failure message="${esc(d.message)}">${body}</failure>`);
124
+ else lines.push(` <skipped message="${esc(`${d.severity}: ${d.message}`)}">${body}</skipped>`);
125
+ lines.push(" </testcase>");
126
+ }
127
+ lines.push(" </testsuite>");
128
+ lines.push("</testsuites>");
129
+ return `${lines.join("\n")}\n`;
130
+ }
131
+ //#endregion
132
+ export { formatDiagnosticLine, formatReportSummary, toJUnit, toJsonReport, toSarif };
133
+
134
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","names":[],"sources":["../src/report/pretty.ts","../src/report/json.ts","../src/report/sarif.ts","../src/report/junit.ts"],"sourcesContent":["// Human-readable output. Pure string formatting — the CLI decides where it\n// goes and whether a TTY wants color.\nimport type { Diagnostic, Report, Severity } from \"../types.js\"\n\nexport interface PrettyOptions {\n color: boolean\n}\n\nconst SYMBOL: Record<Severity, string> = { error: \"✖\", warning: \"⚠\", info: \"ℹ\" }\nconst SGR: Record<Severity, string> = { error: \"31\", warning: \"33\", info: \"36\" }\n\nfunction paint(code: string, s: string, on: boolean): string {\n return on ? `\\x1b[${code}m${s}\\x1b[0m` : s\n}\n\nexport function formatDiagnosticLine(d: Diagnostic, opts: PrettyOptions): string {\n const where = d.eventIndex >= 0 ? `event ${d.eventIndex}` : \"—\"\n const head = paint(SGR[d.severity], `${SYMBOL[d.severity]} ${d.rule}`, opts.color)\n const meta = paint(\"2\", `${d.severity.padEnd(7)} ${where.padEnd(10)}`, opts.color)\n const cite = paint(\"2\", ` ↳ ${d.specUrl}`, opts.color)\n return `${head} ${meta} ${d.message}\\n${cite}`\n}\n\nfunction count(n: number, noun: string): string {\n return `${n} ${noun}${n === 1 ? \"\" : \"s\"}`\n}\n\nexport function formatReportSummary(report: Report, opts: PrettyOptions): string {\n const { errors, warnings, info } = report.summary\n const lines: string[] = []\n\n if (errors + warnings + info === 0) {\n lines.push(\n paint(\"32\", `✔ no conformance violations across ${count(report.eventCount, \"event\")}`, opts.color),\n )\n } else {\n lines.push(\n `${count(errors, \"error\")}, ${count(warnings, \"warning\")}, ${info} info across ${count(report.eventCount, \"event\")}`,\n )\n }\n\n const features = Object.entries(report.features)\n const exercised = features.filter(([, s]) => s === \"exercised\").map(([f]) => f)\n const suffix = exercised.length > 0 ? `: ${exercised.join(\", \")}` : \"\"\n lines.push(`${exercised.length} of ${features.length} AG-UI features exercised${suffix}`)\n\n if (report.skipped.length > 0) {\n lines.push(`${count(report.skipped.length, \"rule\")} not evaluated:`)\n for (const s of report.skipped) {\n lines.push(paint(\"2\", ` – ${s.rule}: ${s.reason}`, opts.color))\n }\n }\n\n for (const e of report.internalErrors) {\n lines.push(paint(\"31\", `! internal validator error: ${e}`, opts.color))\n }\n\n return lines.join(\"\\n\")\n}\n","// Machine-readable report: the core Report plus tool identification, so a\n// stored document is self-describing.\nimport type { Report } from \"../types.js\"\n\nexport interface JsonReportOptions {\n tool: { name: string; version: string }\n /** What was validated: URL, file path, or \"stdin\". */\n target?: string\n}\n\nexport interface JsonReportDocument extends Report {\n tool: { name: string; version: string }\n target?: string\n}\n\nexport function toJsonReport(report: Report, opts: JsonReportOptions): JsonReportDocument {\n const doc: JsonReportDocument = { tool: opts.tool, ...report }\n if (opts.target !== undefined) doc.target = opts.target\n return doc\n}\n","// SARIF 2.1.0 output for code-scanning integrations (e.g. GitHub).\n// Level mapping: error→error, warning→warning, info→note. When the input was a\n// line-oriented file (JSONL/captured SSE fed line-per-event is not guaranteed,\n// so only the caller knows), event N is reported at line N+1 via artifactUri.\nimport { RULES } from \"../rules/catalog.js\"\nimport type { Diagnostic, Report } from \"../types.js\"\n\nexport interface SarifOptions {\n toolVersion: string\n /** URI of the validated artifact; enables line-based locations. */\n artifactUri?: string\n}\n\nexport type SarifLevel = \"error\" | \"warning\" | \"note\"\n\nexport interface SarifResult {\n ruleId: string\n level: SarifLevel\n message: { text: string }\n locations: Array<{\n physicalLocation: {\n artifactLocation: { uri: string }\n region: { startLine: number }\n }\n }>\n}\n\nexport interface SarifLog {\n $schema: string\n version: \"2.1.0\"\n runs: Array<{\n tool: {\n driver: {\n name: string\n version: string\n informationUri: string\n rules: Array<{\n id: string\n helpUri: string\n shortDescription?: { text: string }\n defaultConfiguration?: { level: SarifLevel }\n }>\n }\n }\n results: SarifResult[]\n }>\n}\n\nconst LEVEL: Record<Diagnostic[\"severity\"], SarifLevel> = {\n error: \"error\",\n warning: \"warning\",\n info: \"note\",\n}\n\ntype SarifRule = {\n id: string\n helpUri: string\n shortDescription?: { text: string }\n defaultConfiguration?: { level: SarifLevel }\n}\n\nexport function toSarif(report: Report, opts: SarifOptions): SarifLog {\n const rules = new Map<string, SarifRule>()\n for (const d of report.diagnostics) {\n if (rules.has(d.rule)) continue\n const entry: SarifRule = { id: d.rule, helpUri: d.specUrl }\n const catalog = RULES.get(d.rule)\n if (catalog !== undefined) {\n entry.shortDescription = { text: catalog.title }\n entry.defaultConfiguration = { level: LEVEL[catalog.severity] }\n }\n rules.set(d.rule, entry)\n }\n\n const results: SarifResult[] = report.diagnostics.map((d) => ({\n ruleId: d.rule,\n level: LEVEL[d.severity],\n message: { text: d.message },\n locations:\n opts.artifactUri !== undefined && d.eventIndex >= 0\n ? [\n {\n physicalLocation: {\n artifactLocation: { uri: opts.artifactUri },\n region: { startLine: d.eventIndex + 1 },\n },\n },\n ]\n : [],\n }))\n\n return {\n $schema: \"https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/schemas/sarif-schema-2.1.0.json\",\n version: \"2.1.0\",\n runs: [\n {\n tool: {\n driver: {\n name: \"ag-ui-validate\",\n version: opts.toolVersion,\n informationUri: \"https://github.com/langport-dev/ag-ui-validate\",\n rules: [...rules.values()],\n },\n },\n results,\n },\n ],\n }\n}\n","// JUnit XML output for CI systems. One testcase per finding: errors are\n// <failure>, warnings and info are <skipped> (visible but not build-breaking —\n// the exit code, not the XML, decides pass/fail). A clean report is a single\n// passing testcase so the suite is never empty.\nimport type { Report } from \"../types.js\"\n\nexport interface JUnitOptions {\n /** Suite name — typically the validated target. */\n name: string\n}\n\nfunction esc(s: string): string {\n return s\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&apos;\")\n}\n\nexport function toJUnit(report: Report, opts: JUnitOptions): string {\n const lines: string[] = ['<?xml version=\"1.0\" encoding=\"UTF-8\"?>']\n const suite = esc(opts.name)\n\n if (report.diagnostics.length === 0) {\n lines.push('<testsuites name=\"ag-ui-validate\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\">')\n lines.push(` <testsuite name=\"${suite}\" tests=\"1\" failures=\"0\" errors=\"0\" skipped=\"0\">`)\n lines.push(\n ` <testcase name=\"AG-UI conformance: no violations across ${report.eventCount} events\" classname=\"${suite}\"/>`,\n )\n lines.push(\" </testsuite>\")\n lines.push(\"</testsuites>\")\n return `${lines.join(\"\\n\")}\\n`\n }\n\n const failures = report.diagnostics.filter((d) => d.severity === \"error\").length\n const skipped = report.diagnostics.length - failures\n const counts = `tests=\"${report.diagnostics.length}\" failures=\"${failures}\" errors=\"0\" skipped=\"${skipped}\"`\n lines.push(`<testsuites name=\"ag-ui-validate\" ${counts}>`)\n lines.push(` <testsuite name=\"${suite}\" ${counts}>`)\n for (const d of report.diagnostics) {\n const where = d.eventIndex >= 0 ? `event ${d.eventIndex}` : \"stream\"\n const name = esc(`${d.rule} (${where})`)\n lines.push(` <testcase name=\"${name}\" classname=\"${suite}\">`)\n const body = `${esc(d.message)}\\n${esc(d.specUrl)}`\n if (d.severity === \"error\") {\n lines.push(` <failure message=\"${esc(d.message)}\">${body}</failure>`)\n } else {\n lines.push(` <skipped message=\"${esc(`${d.severity}: ${d.message}`)}\">${body}</skipped>`)\n }\n lines.push(\" </testcase>\")\n }\n lines.push(\" </testsuite>\")\n lines.push(\"</testsuites>\")\n return `${lines.join(\"\\n\")}\\n`\n}\n"],"mappings":"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"}