@kevinrabun/judges 3.4.0 → 3.6.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 (97) hide show
  1. package/README.md +189 -4
  2. package/dist/api.d.ts +17 -0
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +18 -0
  5. package/dist/api.js.map +1 -1
  6. package/dist/calibration.d.ts +58 -0
  7. package/dist/calibration.d.ts.map +1 -0
  8. package/dist/calibration.js +125 -0
  9. package/dist/calibration.js.map +1 -0
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +334 -12
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/baseline.d.ts +2 -0
  14. package/dist/commands/baseline.d.ts.map +1 -0
  15. package/dist/commands/baseline.js +126 -0
  16. package/dist/commands/baseline.js.map +1 -0
  17. package/dist/commands/benchmark.d.ts +100 -0
  18. package/dist/commands/benchmark.d.ts.map +1 -0
  19. package/dist/commands/benchmark.js +663 -0
  20. package/dist/commands/benchmark.js.map +1 -0
  21. package/dist/commands/completions.d.ts +2 -0
  22. package/dist/commands/completions.d.ts.map +1 -0
  23. package/dist/commands/completions.js +226 -0
  24. package/dist/commands/completions.js.map +1 -0
  25. package/dist/commands/config-share.d.ts +49 -0
  26. package/dist/commands/config-share.d.ts.map +1 -0
  27. package/dist/commands/config-share.js +181 -0
  28. package/dist/commands/config-share.js.map +1 -0
  29. package/dist/commands/deps.d.ts +6 -0
  30. package/dist/commands/deps.d.ts.map +1 -0
  31. package/dist/commands/deps.js +123 -0
  32. package/dist/commands/deps.js.map +1 -0
  33. package/dist/commands/diff.d.ts +7 -0
  34. package/dist/commands/diff.d.ts.map +1 -0
  35. package/dist/commands/diff.js +209 -0
  36. package/dist/commands/diff.js.map +1 -0
  37. package/dist/commands/docs.d.ts +2 -0
  38. package/dist/commands/docs.d.ts.map +1 -0
  39. package/dist/commands/docs.js +157 -0
  40. package/dist/commands/docs.js.map +1 -0
  41. package/dist/commands/feedback.d.ts +87 -0
  42. package/dist/commands/feedback.d.ts.map +1 -0
  43. package/dist/commands/feedback.js +320 -0
  44. package/dist/commands/feedback.js.map +1 -0
  45. package/dist/commands/language-packs.d.ts +43 -0
  46. package/dist/commands/language-packs.d.ts.map +1 -0
  47. package/dist/commands/language-packs.js +151 -0
  48. package/dist/commands/language-packs.js.map +1 -0
  49. package/dist/commands/rule.d.ts +50 -0
  50. package/dist/commands/rule.d.ts.map +1 -0
  51. package/dist/commands/rule.js +202 -0
  52. package/dist/commands/rule.js.map +1 -0
  53. package/dist/commands/smart-output.d.ts +39 -0
  54. package/dist/commands/smart-output.d.ts.map +1 -0
  55. package/dist/commands/smart-output.js +176 -0
  56. package/dist/commands/smart-output.js.map +1 -0
  57. package/dist/commands/watch.js.map +1 -1
  58. package/dist/comparison.d.ts +68 -0
  59. package/dist/comparison.d.ts.map +1 -0
  60. package/dist/comparison.js +254 -0
  61. package/dist/comparison.js.map +1 -0
  62. package/dist/fingerprint.d.ts +40 -0
  63. package/dist/fingerprint.d.ts.map +1 -0
  64. package/dist/fingerprint.js +180 -0
  65. package/dist/fingerprint.js.map +1 -0
  66. package/dist/fix-history.d.ts +72 -0
  67. package/dist/fix-history.d.ts.map +1 -0
  68. package/dist/fix-history.js +127 -0
  69. package/dist/fix-history.js.map +1 -0
  70. package/dist/formatters/badge.d.ts +17 -0
  71. package/dist/formatters/badge.d.ts.map +1 -0
  72. package/dist/formatters/badge.js +79 -0
  73. package/dist/formatters/badge.js.map +1 -0
  74. package/dist/formatters/codeclimate.d.ts +25 -0
  75. package/dist/formatters/codeclimate.d.ts.map +1 -0
  76. package/dist/formatters/codeclimate.js +81 -0
  77. package/dist/formatters/codeclimate.js.map +1 -0
  78. package/dist/formatters/diagnostics.d.ts +82 -0
  79. package/dist/formatters/diagnostics.d.ts.map +1 -0
  80. package/dist/formatters/diagnostics.js +153 -0
  81. package/dist/formatters/diagnostics.js.map +1 -0
  82. package/dist/formatters/junit.d.ts +7 -0
  83. package/dist/formatters/junit.d.ts.map +1 -0
  84. package/dist/formatters/junit.js +69 -0
  85. package/dist/formatters/junit.js.map +1 -0
  86. package/dist/index.js +23 -2
  87. package/dist/index.js.map +1 -1
  88. package/dist/plugins.d.ts +103 -0
  89. package/dist/plugins.d.ts.map +1 -0
  90. package/dist/plugins.js +187 -0
  91. package/dist/plugins.js.map +1 -0
  92. package/dist/presets.d.ts +22 -0
  93. package/dist/presets.d.ts.map +1 -0
  94. package/dist/presets.js +115 -0
  95. package/dist/presets.js.map +1 -0
  96. package/judgesrc.schema.json +74 -0
  97. package/package.json +30 -1
@@ -0,0 +1,69 @@
1
+ // ─── JUnit XML Formatter ─────────────────────────────────────────────────────
2
+ // Converts a TribunalVerdict into JUnit XML format for CI/CD integration.
3
+ // Compatible with Jenkins, Azure DevOps, GitHub Actions, GitLab CI, etc.
4
+ // ──────────────────────────────────────────────────────────────────────────────
5
+ function escapeXml(str) {
6
+ return str
7
+ .replace(/&/g, "&")
8
+ .replace(/</g, "&lt;")
9
+ .replace(/>/g, "&gt;")
10
+ .replace(/"/g, "&quot;")
11
+ .replace(/'/g, "&apos;");
12
+ }
13
+ /**
14
+ * Convert a TribunalVerdict into JUnit XML format.
15
+ * Each judge becomes a test suite; each finding becomes a test case failure.
16
+ */
17
+ export function verdictToJUnit(verdict, filePath) {
18
+ const lines = [];
19
+ const timestamp = new Date().toISOString();
20
+ const totalTests = verdict.evaluations.reduce((s, e) => s + Math.max(e.findings.length, 1), 0);
21
+ const totalFailures = verdict.evaluations.reduce((s, e) => s + e.findings.filter((f) => f.severity === "critical" || f.severity === "high").length, 0);
22
+ const totalErrors = 0;
23
+ const suiteName = filePath ? `judges:${filePath}` : "judges";
24
+ lines.push('<?xml version="1.0" encoding="UTF-8"?>');
25
+ lines.push(`<testsuites name="${escapeXml(suiteName)}" tests="${totalTests}" failures="${totalFailures}" errors="${totalErrors}" timestamp="${timestamp}">`);
26
+ for (const evaluation of verdict.evaluations) {
27
+ const suiteFailures = evaluation.findings.filter((f) => f.severity === "critical" || f.severity === "high").length;
28
+ const suiteTests = Math.max(evaluation.findings.length, 1);
29
+ lines.push(` <testsuite name="${escapeXml(evaluation.judgeName)}" tests="${suiteTests}" failures="${suiteFailures}" errors="0">`);
30
+ if (evaluation.findings.length === 0) {
31
+ // No findings = passing test
32
+ lines.push(` <testcase name="${escapeXml(evaluation.judgeName)}: pass" classname="${escapeXml(evaluation.judgeName)}" />`);
33
+ }
34
+ else {
35
+ for (const finding of evaluation.findings) {
36
+ const testName = `${finding.ruleId}: ${finding.title}`;
37
+ const className = evaluation.judgeName;
38
+ const isFail = finding.severity === "critical" || finding.severity === "high";
39
+ lines.push(` <testcase name="${escapeXml(testName)}" classname="${escapeXml(className)}">`);
40
+ if (isFail) {
41
+ lines.push(` <failure message="${escapeXml(finding.title)}" type="${escapeXml(finding.severity)}">`);
42
+ lines.push(escapeXml(formatFindingMessage(finding)));
43
+ lines.push(" </failure>");
44
+ }
45
+ else {
46
+ // medium/low/info become system-out warnings rather than failures
47
+ lines.push(" <system-out>");
48
+ lines.push(escapeXml(formatFindingMessage(finding)));
49
+ lines.push(" </system-out>");
50
+ }
51
+ lines.push(" </testcase>");
52
+ }
53
+ }
54
+ lines.push(" </testsuite>");
55
+ }
56
+ lines.push("</testsuites>");
57
+ return lines.join("\n");
58
+ }
59
+ function formatFindingMessage(f) {
60
+ const parts = [`[${f.severity.toUpperCase()}] ${f.ruleId}: ${f.title}`, f.description];
61
+ if (f.lineNumbers && f.lineNumbers.length > 0) {
62
+ parts.push(`Lines: ${f.lineNumbers.join(", ")}`);
63
+ }
64
+ parts.push(`Recommendation: ${f.recommendation}`);
65
+ if (f.reference)
66
+ parts.push(`Reference: ${f.reference}`);
67
+ return parts.join("\n");
68
+ }
69
+ //# sourceMappingURL=junit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"junit.js","sourceRoot":"","sources":["../../src/formatters/junit.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -18,7 +18,28 @@
18
18
  */
19
19
  // ─── CLI Detection ──────────────────────────────────────────────────────────
20
20
  // If the user passed a subcommand or flag, run as CLI instead of MCP server.
21
- const cliCommands = new Set(["eval", "list", "evaluate", "init", "fix", "watch", "report", "hook"]);
21
+ const cliCommands = new Set([
22
+ "eval",
23
+ "list",
24
+ "evaluate",
25
+ "init",
26
+ "fix",
27
+ "watch",
28
+ "report",
29
+ "hook",
30
+ "diff",
31
+ "deps",
32
+ "baseline",
33
+ "ci-templates",
34
+ "completions",
35
+ "docs",
36
+ "feedback",
37
+ "benchmark",
38
+ "rule",
39
+ "pack",
40
+ "config",
41
+ "compare",
42
+ ]);
22
43
  const cliFlags = new Set(["--help", "-h", "--file", "-f", "--version", "-v"]);
23
44
  const firstArg = process.argv[2];
24
45
  if (firstArg && (cliCommands.has(firstArg) || cliFlags.has(firstArg))) {
@@ -39,7 +60,7 @@ else {
39
60
  const { registerPrompts } = await import("./tools/prompts.js");
40
61
  const server = new McpServer({
41
62
  name: "judges",
42
- version: "3.4.0",
63
+ version: "3.6.0",
43
64
  });
44
65
  registerTools(server);
45
66
  registerPrompts(server);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,+EAA+E;AAC/E,6EAA6E;AAE7E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AACpG,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9E,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEjC,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;IACtE,8DAA8D;IAC9D,MAAM,CAAC,UAAU,CAAC;SACf,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAC1C,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC;KAAM,CAAC;IACN,2EAA2E;IAE3E,MAAM,CAAC,yCAAyC,CAAC;SAC9C,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5B,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,2CAA2C,CAAC,CAAC;QAC3F,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAC9D,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAE/D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,eAAe,CAAC,MAAM,CAAC,CAAC;QAExB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC5D,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,+EAA+E;AAC/E,6EAA6E;AAE7E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,MAAM;IACN,MAAM;IACN,UAAU;IACV,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,MAAM;IACN,MAAM;IACN,MAAM;IACN,UAAU;IACV,cAAc;IACd,aAAa;IACb,MAAM;IACN,UAAU;IACV,WAAW;IACX,MAAM;IACN,MAAM;IACN,QAAQ;IACR,SAAS;CACV,CAAC,CAAC;AACH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9E,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEjC,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;IACtE,8DAA8D;IAC9D,MAAM,CAAC,UAAU,CAAC;SACf,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAC1C,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC;KAAM,CAAC;IACN,2EAA2E;IAE3E,MAAM,CAAC,yCAAyC,CAAC;SAC9C,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5B,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,2CAA2C,CAAC,CAAC;QAC3F,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAC9D,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAE/D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,eAAe,CAAC,MAAM,CAAC,CAAC;QAExB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC5D,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Plugin API — Extension system for custom evaluators
3
+ *
4
+ * Allows third-party extensions to add custom judges, rules, and evaluators
5
+ * that integrate seamlessly with the tribunal evaluation pipeline.
6
+ *
7
+ * ```ts
8
+ * import { registerPlugin } from "@kevinrabun/judges/api";
9
+ * registerPlugin({
10
+ * name: "my-org-rules",
11
+ * version: "1.0.0",
12
+ * judges: [myCustomJudge],
13
+ * rules: [myCustomRule],
14
+ * });
15
+ * ```
16
+ */
17
+ import type { Finding, JudgeDefinition, Severity } from "./types.js";
18
+ /** A custom evaluation rule that can be added via plugins */
19
+ export interface CustomRule {
20
+ /** Unique rule ID (e.g., "MYORG-001") */
21
+ id: string;
22
+ /** Human-readable title */
23
+ title: string;
24
+ /** Severity level */
25
+ severity: Severity;
26
+ /** Which judge category this rule belongs to */
27
+ judgeId: string;
28
+ /** Description of what the rule checks */
29
+ description: string;
30
+ /** Languages this rule applies to (empty = all) */
31
+ languages?: string[];
32
+ /** Regex pattern to match (simple pattern-based rule) */
33
+ pattern?: RegExp;
34
+ /** Custom analyze function for complex logic */
35
+ analyze?: (code: string, language: string) => Finding[];
36
+ /** Suggested fix text */
37
+ suggestedFix?: string;
38
+ /** Tags for filtering */
39
+ tags?: string[];
40
+ }
41
+ /** Plugin definition */
42
+ export interface JudgesPlugin {
43
+ /** Unique plugin name */
44
+ name: string;
45
+ /** Plugin version (semver) */
46
+ version: string;
47
+ /** Optional description */
48
+ description?: string;
49
+ /** Custom rules to register */
50
+ rules?: CustomRule[];
51
+ /** Custom judge definitions to add to the tribunal */
52
+ judges?: JudgeDefinition[];
53
+ /** Hook: called before evaluation */
54
+ beforeEvaluate?: (code: string, language: string) => void;
55
+ /** Hook: called after evaluation with findings for post-processing */
56
+ afterEvaluate?: (findings: Finding[]) => Finding[];
57
+ /** Hook: called to transform findings (e.g., add org-specific metadata) */
58
+ transformFindings?: (findings: Finding[]) => Finding[];
59
+ }
60
+ /** Plugin registration result */
61
+ export interface PluginRegistration {
62
+ name: string;
63
+ version: string;
64
+ rulesRegistered: number;
65
+ judgesRegistered: number;
66
+ }
67
+ /**
68
+ * Register a plugin with the judges system.
69
+ */
70
+ export declare function registerPlugin(plugin: JudgesPlugin): PluginRegistration;
71
+ /**
72
+ * Unregister a plugin and remove its rules/judges.
73
+ */
74
+ export declare function unregisterPlugin(name: string): boolean;
75
+ /**
76
+ * Get all registered plugins.
77
+ */
78
+ export declare function getRegisteredPlugins(): PluginRegistration[];
79
+ /**
80
+ * Get all custom rules from all registered plugins.
81
+ */
82
+ export declare function getCustomRules(): CustomRule[];
83
+ /**
84
+ * Get all custom judges from all registered plugins.
85
+ */
86
+ export declare function getPluginJudges(): JudgeDefinition[];
87
+ /**
88
+ * Evaluate custom rules against code and return findings.
89
+ */
90
+ export declare function evaluateCustomRules(code: string, language: string): Finding[];
91
+ /**
92
+ * Run all plugin beforeEvaluate hooks.
93
+ */
94
+ export declare function runBeforeHooks(code: string, language: string): void;
95
+ /**
96
+ * Run all plugin afterEvaluate hooks.
97
+ */
98
+ export declare function runAfterHooks(findings: Finding[]): Finding[];
99
+ /**
100
+ * Clear all registered plugins (useful for testing).
101
+ */
102
+ export declare function clearPlugins(): void;
103
+ //# sourceMappingURL=plugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAIrE,6DAA6D;AAC7D,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,EAAE,CAAC;IACxD,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAwB;AACxB,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,sDAAsD;IACtD,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,qCAAqC;IACrC,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,sEAAsE;IACtE,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC;IACnD,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC;CACxD;AAED,iCAAiC;AACjC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAQD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,kBAAkB,CAgCvE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAiBtD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,kBAAkB,EAAE,CAO3D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAE7C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,eAAe,EAAE,CAEnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA2C7E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAUnE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAmB5D;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAInC"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Plugin API — Extension system for custom evaluators
3
+ *
4
+ * Allows third-party extensions to add custom judges, rules, and evaluators
5
+ * that integrate seamlessly with the tribunal evaluation pipeline.
6
+ *
7
+ * ```ts
8
+ * import { registerPlugin } from "@kevinrabun/judges/api";
9
+ * registerPlugin({
10
+ * name: "my-org-rules",
11
+ * version: "1.0.0",
12
+ * judges: [myCustomJudge],
13
+ * rules: [myCustomRule],
14
+ * });
15
+ * ```
16
+ */
17
+ // ─── Plugin Registry ─────────────────────────────────────────────────────────
18
+ const registeredPlugins = new Map();
19
+ const customRules = new Map();
20
+ const pluginJudges = new Map();
21
+ /**
22
+ * Register a plugin with the judges system.
23
+ */
24
+ export function registerPlugin(plugin) {
25
+ if (!plugin.name)
26
+ throw new Error("Plugin name is required");
27
+ if (!plugin.version)
28
+ throw new Error("Plugin version is required");
29
+ if (registeredPlugins.has(plugin.name)) {
30
+ // Unregister existing version first
31
+ unregisterPlugin(plugin.name);
32
+ }
33
+ registeredPlugins.set(plugin.name, plugin);
34
+ let rulesRegistered = 0;
35
+ let judgesRegistered = 0;
36
+ // Register custom rules
37
+ if (plugin.rules) {
38
+ for (const rule of plugin.rules) {
39
+ if (!rule.id)
40
+ throw new Error(`Rule in plugin "${plugin.name}" is missing an id`);
41
+ customRules.set(rule.id, rule);
42
+ rulesRegistered++;
43
+ }
44
+ }
45
+ // Register custom judges
46
+ if (plugin.judges) {
47
+ for (const judge of plugin.judges) {
48
+ pluginJudges.set(judge.id, judge);
49
+ judgesRegistered++;
50
+ }
51
+ }
52
+ return { name: plugin.name, version: plugin.version, rulesRegistered, judgesRegistered };
53
+ }
54
+ /**
55
+ * Unregister a plugin and remove its rules/judges.
56
+ */
57
+ export function unregisterPlugin(name) {
58
+ const plugin = registeredPlugins.get(name);
59
+ if (!plugin)
60
+ return false;
61
+ if (plugin.rules) {
62
+ for (const rule of plugin.rules) {
63
+ customRules.delete(rule.id);
64
+ }
65
+ }
66
+ if (plugin.judges) {
67
+ for (const judge of plugin.judges) {
68
+ pluginJudges.delete(judge.id);
69
+ }
70
+ }
71
+ registeredPlugins.delete(name);
72
+ return true;
73
+ }
74
+ /**
75
+ * Get all registered plugins.
76
+ */
77
+ export function getRegisteredPlugins() {
78
+ return [...registeredPlugins.entries()].map(([, plugin]) => ({
79
+ name: plugin.name,
80
+ version: plugin.version,
81
+ rulesRegistered: plugin.rules?.length ?? 0,
82
+ judgesRegistered: plugin.judges?.length ?? 0,
83
+ }));
84
+ }
85
+ /**
86
+ * Get all custom rules from all registered plugins.
87
+ */
88
+ export function getCustomRules() {
89
+ return [...customRules.values()];
90
+ }
91
+ /**
92
+ * Get all custom judges from all registered plugins.
93
+ */
94
+ export function getPluginJudges() {
95
+ return [...pluginJudges.values()];
96
+ }
97
+ /**
98
+ * Evaluate custom rules against code and return findings.
99
+ */
100
+ export function evaluateCustomRules(code, language) {
101
+ const findings = [];
102
+ for (const rule of customRules.values()) {
103
+ // Skip if rule doesn't apply to this language
104
+ if (rule.languages && rule.languages.length > 0 && !rule.languages.includes(language)) {
105
+ continue;
106
+ }
107
+ // Custom analyze function
108
+ if (rule.analyze) {
109
+ try {
110
+ findings.push(...rule.analyze(code, language));
111
+ }
112
+ catch {
113
+ // Silently skip failed custom rules
114
+ }
115
+ continue;
116
+ }
117
+ // Pattern-based rule
118
+ if (rule.pattern) {
119
+ const re = new RegExp(rule.pattern.source, rule.pattern.flags);
120
+ let match;
121
+ const lines = code.split("\n");
122
+ while ((match = re.exec(code)) !== null) {
123
+ const beforeMatch = code.slice(0, match.index);
124
+ const lineNum = (beforeMatch.match(/\n/g) || []).length + 1;
125
+ findings.push({
126
+ ruleId: rule.id,
127
+ title: rule.title,
128
+ severity: rule.severity,
129
+ description: `${rule.description} (matched: ${match[0].slice(0, 100)})`,
130
+ lineNumbers: [lineNum],
131
+ recommendation: rule.suggestedFix || "",
132
+ suggestedFix: rule.suggestedFix,
133
+ });
134
+ }
135
+ }
136
+ }
137
+ return findings;
138
+ }
139
+ /**
140
+ * Run all plugin beforeEvaluate hooks.
141
+ */
142
+ export function runBeforeHooks(code, language) {
143
+ for (const plugin of registeredPlugins.values()) {
144
+ if (plugin.beforeEvaluate) {
145
+ try {
146
+ plugin.beforeEvaluate(code, language);
147
+ }
148
+ catch {
149
+ // Don't let plugin errors crash the evaluation
150
+ }
151
+ }
152
+ }
153
+ }
154
+ /**
155
+ * Run all plugin afterEvaluate hooks.
156
+ */
157
+ export function runAfterHooks(findings) {
158
+ let result = findings;
159
+ for (const plugin of registeredPlugins.values()) {
160
+ if (plugin.afterEvaluate) {
161
+ try {
162
+ result = plugin.afterEvaluate(result);
163
+ }
164
+ catch {
165
+ // Don't let plugin errors crash the evaluation
166
+ }
167
+ }
168
+ if (plugin.transformFindings) {
169
+ try {
170
+ result = plugin.transformFindings(result);
171
+ }
172
+ catch {
173
+ // Don't let plugin errors crash the evaluation
174
+ }
175
+ }
176
+ }
177
+ return result;
178
+ }
179
+ /**
180
+ * Clear all registered plugins (useful for testing).
181
+ */
182
+ export function clearPlugins() {
183
+ registeredPlugins.clear();
184
+ customRules.clear();
185
+ pluginJudges.clear();
186
+ }
187
+ //# sourceMappingURL=plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { JudgesConfig } from "./types.js";
2
+ export interface Preset {
3
+ name: string;
4
+ description: string;
5
+ config: JudgesConfig;
6
+ }
7
+ /**
8
+ * Built-in presets for quick configuration.
9
+ */
10
+ export declare const PRESETS: Record<string, Preset>;
11
+ /**
12
+ * Get a preset by name, or undefined if not found.
13
+ */
14
+ export declare function getPreset(name: string): Preset | undefined;
15
+ /**
16
+ * List all available preset names and descriptions.
17
+ */
18
+ export declare function listPresets(): Array<{
19
+ name: string;
20
+ description: string;
21
+ }>;
22
+ //# sourceMappingURL=presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiG1C,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1D;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAK1E"}
@@ -0,0 +1,115 @@
1
+ // ─── Named Presets ───────────────────────────────────────────────────────────
2
+ // Pre-configured evaluation profiles for common use cases.
3
+ // ──────────────────────────────────────────────────────────────────────────────
4
+ /**
5
+ * Built-in presets for quick configuration.
6
+ */
7
+ export const PRESETS = {
8
+ strict: {
9
+ name: "Strict",
10
+ description: "All judges, all severities. No findings tolerated. Best for production code reviews.",
11
+ config: {
12
+ minSeverity: "info",
13
+ },
14
+ },
15
+ lenient: {
16
+ name: "Lenient",
17
+ description: "Only critical and high severity findings. Good for early development.",
18
+ config: {
19
+ minSeverity: "high",
20
+ },
21
+ },
22
+ "security-only": {
23
+ name: "Security Only",
24
+ description: "Focus on security-related judges. Perfect for security audits.",
25
+ config: {
26
+ disabledJudges: [
27
+ "cost-effectiveness",
28
+ "scalability",
29
+ "accessibility",
30
+ "documentation",
31
+ "internationalization",
32
+ "ux",
33
+ "maintainability",
34
+ "caching",
35
+ "portability",
36
+ "ci-cd",
37
+ "code-structure",
38
+ "agent-instructions",
39
+ ],
40
+ minSeverity: "low",
41
+ },
42
+ },
43
+ startup: {
44
+ name: "Startup / MVP",
45
+ description: "Only critical issues and core security. Ship fast without shipping broken.",
46
+ config: {
47
+ minSeverity: "high",
48
+ disabledJudges: [
49
+ "accessibility",
50
+ "documentation",
51
+ "internationalization",
52
+ "backwards-compatibility",
53
+ "portability",
54
+ "maintainability",
55
+ "code-structure",
56
+ ],
57
+ },
58
+ },
59
+ compliance: {
60
+ name: "Compliance",
61
+ description: "Focus on compliance, data security, sovereignty, and privacy judges.",
62
+ config: {
63
+ disabledJudges: [
64
+ "cost-effectiveness",
65
+ "scalability",
66
+ "accessibility",
67
+ "ux",
68
+ "caching",
69
+ "portability",
70
+ "code-structure",
71
+ "agent-instructions",
72
+ "maintainability",
73
+ "documentation",
74
+ "internationalization",
75
+ ],
76
+ minSeverity: "low",
77
+ },
78
+ },
79
+ performance: {
80
+ name: "Performance",
81
+ description: "Focus on performance, caching, scalability, and concurrency judges.",
82
+ config: {
83
+ disabledJudges: [
84
+ "compliance",
85
+ "data-sovereignty",
86
+ "documentation",
87
+ "internationalization",
88
+ "accessibility",
89
+ "backwards-compatibility",
90
+ "portability",
91
+ "ux",
92
+ "ethics-bias",
93
+ "agent-instructions",
94
+ "code-structure",
95
+ ],
96
+ minSeverity: "low",
97
+ },
98
+ },
99
+ };
100
+ /**
101
+ * Get a preset by name, or undefined if not found.
102
+ */
103
+ export function getPreset(name) {
104
+ return PRESETS[name];
105
+ }
106
+ /**
107
+ * List all available preset names and descriptions.
108
+ */
109
+ export function listPresets() {
110
+ return Object.entries(PRESETS).map(([key, preset]) => ({
111
+ name: key,
112
+ description: preset.description,
113
+ }));
114
+ }
115
+ //# sourceMappingURL=presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,2DAA2D;AAC3D,iFAAiF;AAUjF;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAA2B;IAC7C,MAAM,EAAE;QACN,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,sFAAsF;QACnG,MAAM,EAAE;YACN,WAAW,EAAE,MAAkB;SAChC;KACF;IAED,OAAO,EAAE;QACP,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,uEAAuE;QACpF,MAAM,EAAE;YACN,WAAW,EAAE,MAAkB;SAChC;KACF;IAED,eAAe,EAAE;QACf,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,gEAAgE;QAC7E,MAAM,EAAE;YACN,cAAc,EAAE;gBACd,oBAAoB;gBACpB,aAAa;gBACb,eAAe;gBACf,eAAe;gBACf,sBAAsB;gBACtB,IAAI;gBACJ,iBAAiB;gBACjB,SAAS;gBACT,aAAa;gBACb,OAAO;gBACP,gBAAgB;gBAChB,oBAAoB;aACrB;YACD,WAAW,EAAE,KAAiB;SAC/B;KACF;IAED,OAAO,EAAE;QACP,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,4EAA4E;QACzF,MAAM,EAAE;YACN,WAAW,EAAE,MAAkB;YAC/B,cAAc,EAAE;gBACd,eAAe;gBACf,eAAe;gBACf,sBAAsB;gBACtB,yBAAyB;gBACzB,aAAa;gBACb,iBAAiB;gBACjB,gBAAgB;aACjB;SACF;KACF;IAED,UAAU,EAAE;QACV,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,sEAAsE;QACnF,MAAM,EAAE;YACN,cAAc,EAAE;gBACd,oBAAoB;gBACpB,aAAa;gBACb,eAAe;gBACf,IAAI;gBACJ,SAAS;gBACT,aAAa;gBACb,gBAAgB;gBAChB,oBAAoB;gBACpB,iBAAiB;gBACjB,eAAe;gBACf,sBAAsB;aACvB;YACD,WAAW,EAAE,KAAiB;SAC/B;KACF;IAED,WAAW,EAAE;QACX,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,qEAAqE;QAClF,MAAM,EAAE;YACN,cAAc,EAAE;gBACd,YAAY;gBACZ,kBAAkB;gBAClB,eAAe;gBACf,sBAAsB;gBACtB,eAAe;gBACf,yBAAyB;gBACzB,aAAa;gBACb,IAAI;gBACJ,aAAa;gBACb,oBAAoB;gBACpB,gBAAgB;aACjB;YACD,WAAW,EAAE,KAAiB;SAC/B;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,MAAM,CAAC,WAAW;KAChC,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,74 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://github.com/KevinRabun/judges/blob/main/judgesrc.schema.json",
4
+ "title": "Judges Panel Configuration",
5
+ "description": "Configuration schema for .judgesrc / .judgesrc.json files used by the Judges Panel CLI.",
6
+ "type": "object",
7
+ "properties": {
8
+ "$schema": {
9
+ "type": "string",
10
+ "description": "JSON Schema reference for IDE validation."
11
+ },
12
+ "preset": {
13
+ "type": "string",
14
+ "enum": ["strict", "lenient", "security-only", "startup", "compliance", "performance"],
15
+ "description": "Named preset to use as a base configuration. Individual settings override preset values."
16
+ },
17
+ "disabledRules": {
18
+ "type": "array",
19
+ "items": { "type": "string" },
20
+ "description": "Rule IDs to suppress entirely (e.g. [\"SEC-003\", \"COST-001\"])."
21
+ },
22
+ "disabledJudges": {
23
+ "type": "array",
24
+ "items": { "type": "string" },
25
+ "description": "Judge IDs to skip during evaluation (e.g. [\"accessibility\", \"documentation\"])."
26
+ },
27
+ "minSeverity": {
28
+ "type": "string",
29
+ "enum": ["critical", "high", "medium", "low", "info"],
30
+ "description": "Minimum finding severity to report. Anything below this threshold is filtered out.",
31
+ "default": "info"
32
+ },
33
+ "languages": {
34
+ "type": "array",
35
+ "items": { "type": "string" },
36
+ "description": "Languages to restrict analysis to. When empty, all languages are analyzed."
37
+ },
38
+ "ruleOverrides": {
39
+ "type": "object",
40
+ "additionalProperties": {
41
+ "type": "object",
42
+ "properties": {
43
+ "disabled": {
44
+ "type": "boolean",
45
+ "description": "Disable this specific rule."
46
+ },
47
+ "severity": {
48
+ "type": "string",
49
+ "enum": ["critical", "high", "medium", "low", "info"],
50
+ "description": "Override the default severity for this rule."
51
+ }
52
+ },
53
+ "additionalProperties": false
54
+ },
55
+ "description": "Per-rule overrides keyed by rule ID or wildcard prefix (e.g. \"SEC-*\")."
56
+ },
57
+ "failOnFindings": {
58
+ "type": "boolean",
59
+ "description": "Exit with code 1 when the verdict is fail. Useful for CI pipelines.",
60
+ "default": false
61
+ },
62
+ "baseline": {
63
+ "type": "string",
64
+ "description": "Path to a baseline JSON file. Findings matching the baseline are suppressed."
65
+ },
66
+ "format": {
67
+ "type": "string",
68
+ "enum": ["text", "json", "sarif", "markdown", "html", "junit", "codeclimate"],
69
+ "description": "Default output format.",
70
+ "default": "text"
71
+ }
72
+ },
73
+ "additionalProperties": false
74
+ }