@kevinrabun/judges 3.1.0 → 3.1.1

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.
package/README.md CHANGED
@@ -9,12 +9,100 @@ An MCP (Model Context Protocol) server that provides a panel of **35 specialized
9
9
 
10
10
  [![CI](https://github.com/KevinRabun/judges/actions/workflows/ci.yml/badge.svg)](https://github.com/KevinRabun/judges/actions/workflows/ci.yml)
11
11
  [![npm](https://img.shields.io/npm/v/@kevinrabun/judges)](https://www.npmjs.com/package/@kevinrabun/judges)
12
+ [![npm downloads](https://img.shields.io/npm/dw/@kevinrabun/judges)](https://www.npmjs.com/package/@kevinrabun/judges)
12
13
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
+ [![Tests](https://img.shields.io/badge/tests-899-brightgreen)](https://github.com/KevinRabun/judges/actions)
15
+
16
+ ---
17
+
18
+ ## Why Judges?
19
+
20
+ AI code generators (Copilot, Cursor, Claude, ChatGPT, etc.) write code fast — but they routinely produce **insecure defaults, missing auth, hardcoded secrets, and poor error handling**. Human reviewers catch some of this, but nobody reviews 35 dimensions consistently.
21
+
22
+ | | ESLint / Biome | SonarQube | Semgrep / CodeQL | **Judges** |
23
+ |---|---|---|---|---|
24
+ | **Scope** | Style + some bugs | Bugs + code smells | Security patterns | **35 domains**: security, cost, compliance, a11y, API design, cloud, UX, … |
25
+ | **AI-generated code focus** | No | No | Partial | **Purpose-built** for AI output failure modes |
26
+ | **Setup** | Config per project | Server + scanner | Cloud or local | **One command**: `npx @kevinrabun/judges eval file.ts` |
27
+ | **Auto-fix patches** | Some | No | No | **47 deterministic patches** — no LLM needed |
28
+ | **Non-technical output** | No | Dashboard | No | **Plain-language findings** with What/Why/Next |
29
+ | **MCP native** | No | No | No | **Yes** — works inside Copilot, Claude, Cursor |
30
+ | **SARIF output** | No | Yes | Yes | **Yes** — upload to GitHub Code Scanning |
31
+ | **Cost** | Free | $$$$ | Free/paid | **Free / MIT** |
32
+
33
+ **Judges doesn't replace linters** — it covers the dimensions linters don't: authentication strategy, data sovereignty, cost patterns, accessibility, framework-specific anti-patterns, and architectural issues across multiple files.
13
34
 
14
35
  ---
15
36
 
16
37
  ## Quick Start
17
38
 
39
+ ### Try it now (no clone needed)
40
+
41
+ ```bash
42
+ # Install globally
43
+ npm install -g @kevinrabun/judges
44
+
45
+ # Evaluate any file
46
+ judges eval src/app.ts
47
+
48
+ # Pipe from stdin
49
+ cat api.py | judges eval --language python
50
+
51
+ # Single judge
52
+ judges eval --judge cybersecurity server.ts
53
+
54
+ # SARIF output for CI
55
+ judges eval --file app.ts --format sarif > results.sarif
56
+
57
+ # List all 35 judges
58
+ judges list
59
+ ```
60
+
61
+ ### Use in GitHub Actions
62
+
63
+ Add Judges to your CI pipeline with zero configuration:
64
+
65
+ ```yaml
66
+ # .github/workflows/judges.yml
67
+ name: Judges Code Review
68
+ on: [pull_request]
69
+
70
+ jobs:
71
+ judges:
72
+ runs-on: ubuntu-latest
73
+ permissions:
74
+ contents: read
75
+ security-events: write # only if using upload-sarif
76
+ steps:
77
+ - uses: actions/checkout@v4
78
+ - uses: KevinRabun/judges@main
79
+ with:
80
+ path: src/api.ts # file or directory
81
+ format: text # text | json | sarif | markdown
82
+ upload-sarif: true # upload to GitHub Code Scanning
83
+ fail-on-findings: true # fail CI on critical/high findings
84
+ ```
85
+
86
+ **Outputs** available for downstream steps: `verdict`, `score`, `findings`, `critical`, `high`, `sarif-file`.
87
+
88
+ ### Use with Docker (no Node.js required)
89
+
90
+ ```bash
91
+ # Build the image
92
+ docker build -t judges .
93
+
94
+ # Evaluate a local file
95
+ docker run --rm -v $(pwd):/code judges eval --file /code/app.ts
96
+
97
+ # Pipe from stdin
98
+ cat api.py | docker run --rm -i judges eval --language python
99
+
100
+ # List judges
101
+ docker run --rm judges list
102
+ ```
103
+
104
+ ### Or use as an MCP server
105
+
18
106
  ### 1. Install and Build
19
107
 
20
108
  ```bash
package/dist/api.d.ts CHANGED
@@ -19,6 +19,7 @@ export { LRUCache, contentHash } from "./cache.js";
19
19
  export { clearProjectCache } from "./evaluators/project.js";
20
20
  export { findingsToSarif, evaluationToSarif, verdictToSarif, validateSarifLog } from "./formatters/sarif.js";
21
21
  export type { SarifValidationError } from "./formatters/sarif.js";
22
+ export { runCli } from "./cli.js";
22
23
  import type { EvaluationOptions } from "./evaluators/index.js";
23
24
  import type { JudgeEvaluation, TribunalVerdict } from "./types.js";
24
25
  /**
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EACV,QAAQ,EACR,OAAO,EACP,OAAO,EACP,KAAK,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACpB,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGpF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAGnG,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC7G,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAKlE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAInE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,eAAe,CAEzG;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,eAAe,CAMjB"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EACV,QAAQ,EACR,OAAO,EACP,OAAO,EACP,KAAK,EACL,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACpB,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGpF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAIxE,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAGnG,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC7G,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAKlC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAInE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,eAAe,CAEzG;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,eAAe,CAMjB"}
package/dist/api.js CHANGED
@@ -25,6 +25,8 @@ export { LRUCache, contentHash } from "./cache.js";
25
25
  export { clearProjectCache } from "./evaluators/project.js";
26
26
  // ─── Formatters ──────────────────────────────────────────────────────────────
27
27
  export { findingsToSarif, evaluationToSarif, verdictToSarif, validateSarifLog } from "./formatters/sarif.js";
28
+ // ─── CLI ─────────────────────────────────────────────────────────────────────
29
+ export { runCli } from "./cli.js";
28
30
  // ─── Convenience Aliases ─────────────────────────────────────────────────────
29
31
  import { evaluateWithTribunal, evaluateWithJudge } from "./evaluators/index.js";
30
32
  import { getJudge } from "./judges/index.js";
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA+BH,gFAAgF;AAChF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpF,gFAAgF;AAChF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEzD,gFAAgF;AAChF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAExE,gFAAgF;AAEhF,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,+EAA+E;AAC/E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAEnG,gFAAgF;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,gFAAgF;AAChF,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG7G,gFAAgF;AAEhF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGhF,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,QAAgB,EAAE,OAA2B;IACtF,OAAO,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAe,EACf,IAAY,EACZ,QAAgB,EAChB,OAA2B;IAE3B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,eAAe,CAAC,mBAAmB,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA+BH,gFAAgF;AAChF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpF,gFAAgF;AAChF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEzD,gFAAgF;AAChF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAExE,gFAAgF;AAEhF,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,+EAA+E;AAC/E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAEnG,gFAAgF;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAElE,gFAAgF;AAChF,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,gFAAgF;AAChF,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG7G,gFAAgF;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,gFAAgF;AAEhF,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGhF,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,QAAgB,EAAE,OAA2B;IACtF,OAAO,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAe,EACf,IAAY,EACZ,QAAgB,EAChB,OAA2B;IAE3B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,eAAe,CAAC,mBAAmB,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Judges Panel — CLI Evaluator
4
+ *
5
+ * Evaluate code directly from the command line without MCP setup.
6
+ *
7
+ * Usage:
8
+ * judges eval --file src/app.ts # evaluate a file
9
+ * judges eval --file src/app.ts --language python # explicit language
10
+ * judges eval --file src/app.ts --format sarif # SARIF output
11
+ * judges eval --file src/app.ts --judge cybersecurity # single judge
12
+ * cat src/app.ts | judges eval --language typescript # stdin pipe
13
+ * judges eval --help # show help
14
+ */
15
+ export declare function runCli(argv: string[]): void;
16
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAgTH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAiD3C"}
package/dist/cli.js ADDED
@@ -0,0 +1,317 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Judges Panel — CLI Evaluator
4
+ *
5
+ * Evaluate code directly from the command line without MCP setup.
6
+ *
7
+ * Usage:
8
+ * judges eval --file src/app.ts # evaluate a file
9
+ * judges eval --file src/app.ts --language python # explicit language
10
+ * judges eval --file src/app.ts --format sarif # SARIF output
11
+ * judges eval --file src/app.ts --judge cybersecurity # single judge
12
+ * cat src/app.ts | judges eval --language typescript # stdin pipe
13
+ * judges eval --help # show help
14
+ */
15
+ import { readFileSync, existsSync } from "fs";
16
+ import { resolve, extname } from "path";
17
+ import { evaluateWithTribunal, evaluateWithJudge, formatVerdictAsMarkdown, formatEvaluationAsMarkdown, } from "./evaluators/index.js";
18
+ import { getJudge, getJudgeSummaries } from "./judges/index.js";
19
+ import { verdictToSarif } from "./formatters/sarif.js";
20
+ // ─── Language Detection from Extension ──────────────────────────────────────
21
+ const EXT_TO_LANG = {
22
+ ".ts": "typescript",
23
+ ".tsx": "typescript",
24
+ ".js": "javascript",
25
+ ".jsx": "javascript",
26
+ ".mjs": "javascript",
27
+ ".cjs": "javascript",
28
+ ".py": "python",
29
+ ".rs": "rust",
30
+ ".go": "go",
31
+ ".java": "java",
32
+ ".cs": "csharp",
33
+ ".rb": "ruby",
34
+ ".php": "php",
35
+ ".swift": "swift",
36
+ ".kt": "kotlin",
37
+ ".scala": "scala",
38
+ ".c": "c",
39
+ ".cpp": "cpp",
40
+ ".h": "c",
41
+ ".hpp": "cpp",
42
+ ".yaml": "yaml",
43
+ ".yml": "yaml",
44
+ ".json": "json",
45
+ ".tf": "terraform",
46
+ ".hcl": "terraform",
47
+ ".dockerfile": "dockerfile",
48
+ ".sh": "bash",
49
+ ".bash": "bash",
50
+ };
51
+ function detectLanguage(filePath) {
52
+ if (!filePath)
53
+ return undefined;
54
+ const base = filePath.toLowerCase();
55
+ if (base.endsWith("dockerfile") || base.includes("dockerfile."))
56
+ return "dockerfile";
57
+ const ext = extname(base);
58
+ return EXT_TO_LANG[ext];
59
+ }
60
+ function parseCliArgs(argv) {
61
+ const args = {
62
+ command: undefined,
63
+ file: undefined,
64
+ language: undefined,
65
+ format: "text",
66
+ judge: undefined,
67
+ help: false,
68
+ };
69
+ // First non-flag arg is the command
70
+ let i = 2; // skip node + script
71
+ if (i < argv.length && !argv[i].startsWith("-")) {
72
+ args.command = argv[i];
73
+ i++;
74
+ }
75
+ for (; i < argv.length; i++) {
76
+ const arg = argv[i];
77
+ switch (arg) {
78
+ case "--file":
79
+ case "-f":
80
+ args.file = argv[++i];
81
+ break;
82
+ case "--language":
83
+ case "-l":
84
+ args.language = argv[++i];
85
+ break;
86
+ case "--format":
87
+ case "-o":
88
+ args.format = argv[++i];
89
+ break;
90
+ case "--judge":
91
+ case "-j":
92
+ args.judge = argv[++i];
93
+ break;
94
+ case "--help":
95
+ case "-h":
96
+ args.help = true;
97
+ break;
98
+ default:
99
+ // If it looks like a file path (not a flag), treat as --file
100
+ if (!arg.startsWith("-") && !args.file) {
101
+ args.file = arg;
102
+ }
103
+ break;
104
+ }
105
+ }
106
+ return args;
107
+ }
108
+ // ─── Help Text ──────────────────────────────────────────────────────────────
109
+ function printHelp() {
110
+ console.log(`
111
+ Judges Panel — CLI Code Evaluator
112
+
113
+ USAGE:
114
+ judges eval [options] [file] Evaluate code with the full tribunal
115
+ judges eval --judge <id> [file] Evaluate with a single judge
116
+ judges list List all available judges
117
+ judges --help Show this help
118
+
119
+ OPTIONS:
120
+ --file, -f <path> File to evaluate (or pass as positional arg)
121
+ --language, -l <lang> Language override (auto-detected from extension)
122
+ --format, -o <fmt> Output format: text (default), json, sarif, markdown
123
+ --judge, -j <id> Run a single judge instead of the full tribunal
124
+ --help, -h Show this help
125
+
126
+ STDIN:
127
+ cat file.ts | judges eval --language typescript
128
+
129
+ EXAMPLES:
130
+ judges eval src/app.ts
131
+ judges eval --file api.py --format sarif
132
+ judges eval --judge cybersecurity server.ts
133
+ judges eval --format json < main.go --language go
134
+ judges list
135
+
136
+ SUPPORTED LANGUAGES:
137
+ typescript, javascript, python, rust, go, java, csharp,
138
+ ruby, php, swift, kotlin, scala, c, cpp, yaml, json,
139
+ terraform, dockerfile, bash
140
+ `);
141
+ }
142
+ // ─── Read Code Input ────────────────────────────────────────────────────────
143
+ function readCode(filePath) {
144
+ if (filePath) {
145
+ const resolved = resolve(filePath);
146
+ if (!existsSync(resolved)) {
147
+ console.error(`Error: File not found: ${resolved}`);
148
+ process.exit(1);
149
+ }
150
+ return { code: readFileSync(resolved, "utf-8"), resolvedPath: resolved };
151
+ }
152
+ // Try reading from stdin
153
+ if (!process.stdin.isTTY) {
154
+ try {
155
+ const code = readFileSync(0, "utf-8"); // fd 0 = stdin
156
+ return { code, resolvedPath: undefined };
157
+ }
158
+ catch {
159
+ console.error("Error: Could not read from stdin");
160
+ process.exit(1);
161
+ }
162
+ }
163
+ console.error("Error: No file specified and no stdin input detected.");
164
+ console.error("Usage: judges eval --file <path> or cat file | judges eval --language <lang>");
165
+ process.exit(1);
166
+ }
167
+ // ─── Format Output ──────────────────────────────────────────────────────────
168
+ function formatTribunalOutput(verdict, format, filePath) {
169
+ switch (format) {
170
+ case "json":
171
+ return JSON.stringify(verdict, null, 2);
172
+ case "sarif":
173
+ return JSON.stringify(verdictToSarif(verdict, filePath), null, 2);
174
+ case "markdown":
175
+ return formatVerdictAsMarkdown(verdict);
176
+ case "text":
177
+ default:
178
+ return formatTextOutput(verdict);
179
+ }
180
+ }
181
+ function formatTextOutput(verdict) {
182
+ const lines = [];
183
+ const totalFindings = verdict.evaluations.reduce((s, e) => s + e.findings.length, 0);
184
+ lines.push("╔══════════════════════════════════════════════════════════════╗");
185
+ lines.push("║ Judges Panel — Evaluation Result ║");
186
+ lines.push("╚══════════════════════════════════════════════════════════════╝");
187
+ lines.push("");
188
+ lines.push(` Verdict : ${verdict.overallVerdict.toUpperCase()}`);
189
+ lines.push(` Score : ${verdict.overallScore}/100`);
190
+ lines.push(` Critical : ${verdict.criticalCount}`);
191
+ lines.push(` High : ${verdict.highCount}`);
192
+ lines.push(` Findings : ${totalFindings}`);
193
+ lines.push(` Judges : ${verdict.evaluations.length}`);
194
+ lines.push("");
195
+ // Per-judge table
196
+ lines.push(" Per-Judge Breakdown:");
197
+ lines.push(" " + "─".repeat(60));
198
+ for (const evaluation of verdict.evaluations) {
199
+ const icon = evaluation.verdict === "pass" ? "✅" : evaluation.verdict === "warning" ? "⚠️ " : "❌";
200
+ const name = evaluation.judgeName.padEnd(28);
201
+ const score = String(evaluation.score).padStart(3);
202
+ const findings = String(evaluation.findings.length).padStart(2);
203
+ lines.push(` ${icon} ${name} ${score}/100 ${findings} finding(s)`);
204
+ }
205
+ lines.push("");
206
+ // Top findings
207
+ const allFindings = verdict.evaluations.flatMap((e) => e.findings);
208
+ const critical = allFindings.filter((f) => f.severity === "critical" || f.severity === "high");
209
+ if (critical.length > 0) {
210
+ lines.push(" Critical & High Findings:");
211
+ lines.push(" " + "─".repeat(60));
212
+ for (const f of critical.slice(0, 20)) {
213
+ lines.push(` [${f.severity.toUpperCase().padEnd(8)}] ${f.ruleId}: ${f.title}`);
214
+ if (f.lineNumbers && f.lineNumbers.length > 0) {
215
+ lines.push(` Line ${f.lineNumbers[0]}: ${f.description.slice(0, 100)}`);
216
+ }
217
+ }
218
+ if (critical.length > 20) {
219
+ lines.push(` ... and ${critical.length - 20} more critical/high findings`);
220
+ }
221
+ lines.push("");
222
+ }
223
+ // Exit guidance
224
+ if (verdict.overallVerdict === "fail") {
225
+ lines.push(" ⛔ FAIL — This code has issues that should be addressed before shipping.");
226
+ }
227
+ else if (verdict.overallVerdict === "warning") {
228
+ lines.push(" ⚠️ WARNING — Review findings above before proceeding.");
229
+ }
230
+ else {
231
+ lines.push(" ✅ PASS — No critical issues detected.");
232
+ }
233
+ lines.push("");
234
+ return lines.join("\n");
235
+ }
236
+ function formatSingleJudgeTextOutput(evaluation) {
237
+ const lines = [];
238
+ lines.push("╔══════════════════════════════════════════════════════════════╗");
239
+ lines.push(`║ Judge: ${evaluation.judgeName.padEnd(49)}║`);
240
+ lines.push("╚══════════════════════════════════════════════════════════════╝");
241
+ lines.push("");
242
+ lines.push(` Verdict : ${evaluation.verdict.toUpperCase()}`);
243
+ lines.push(` Score : ${evaluation.score}/100`);
244
+ lines.push(` Findings : ${evaluation.findings.length}`);
245
+ lines.push("");
246
+ for (const f of evaluation.findings) {
247
+ lines.push(` [${f.severity.toUpperCase().padEnd(8)}] ${f.ruleId}: ${f.title}`);
248
+ if (f.lineNumbers && f.lineNumbers.length > 0) {
249
+ lines.push(` Line ${f.lineNumbers[0]}: ${f.description.slice(0, 120)}`);
250
+ }
251
+ if (f.suggestedFix) {
252
+ lines.push(` Fix: ${f.suggestedFix.slice(0, 120)}`);
253
+ }
254
+ }
255
+ lines.push("");
256
+ return lines.join("\n");
257
+ }
258
+ // ─── List Judges ────────────────────────────────────────────────────────────
259
+ function listJudges() {
260
+ const judges = getJudgeSummaries();
261
+ console.log("");
262
+ console.log(" Available Judges:");
263
+ console.log(" " + "─".repeat(60));
264
+ for (const j of judges) {
265
+ console.log(` ${j.id.padEnd(30)} ${j.name}`);
266
+ }
267
+ console.log("");
268
+ console.log(` Total: ${judges.length} judges`);
269
+ console.log("");
270
+ }
271
+ // ─── Main CLI Entry Point ───────────────────────────────────────────────────
272
+ export function runCli(argv) {
273
+ const args = parseCliArgs(argv);
274
+ if (args.help || (!args.command && !args.file)) {
275
+ printHelp();
276
+ process.exit(0);
277
+ }
278
+ if (args.command === "list") {
279
+ listJudges();
280
+ process.exit(0);
281
+ }
282
+ if (args.command === "eval" || args.file) {
283
+ const { code, resolvedPath } = readCode(args.file);
284
+ const language = args.language || detectLanguage(args.file || resolvedPath) || "typescript";
285
+ if (args.judge) {
286
+ // Single judge mode
287
+ const judge = getJudge(args.judge);
288
+ if (!judge) {
289
+ console.error(`Error: Unknown judge "${args.judge}"`);
290
+ console.error("Run 'judges list' to see available judges.");
291
+ process.exit(1);
292
+ }
293
+ const evaluation = evaluateWithJudge(judge, code, language);
294
+ if (args.format === "json") {
295
+ console.log(JSON.stringify(evaluation, null, 2));
296
+ }
297
+ else if (args.format === "markdown") {
298
+ console.log(formatEvaluationAsMarkdown(evaluation));
299
+ }
300
+ else {
301
+ console.log(formatSingleJudgeTextOutput(evaluation));
302
+ }
303
+ }
304
+ else {
305
+ // Full tribunal mode
306
+ const verdict = evaluateWithTribunal(code, language);
307
+ console.log(formatTribunalOutput(verdict, args.format, resolvedPath || args.file));
308
+ }
309
+ // Set exit code based on verdict
310
+ process.exit(0);
311
+ }
312
+ // Unknown command
313
+ console.error(`Unknown command: ${args.command}`);
314
+ printHelp();
315
+ process.exit(1);
316
+ }
317
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,22 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Judges Panel — MCP Server
3
+ * Judges Panel — MCP Server + CLI
4
4
  *
5
- * An MCP server that provides a panel of specialized judges to evaluate
6
- * AI-generated code. Each tool returns both automated pattern-detection
7
- * findings AND the judge's deep-review criteria, enabling the calling LLM
8
- * to perform thorough contextual analysis beyond what static patterns catch.
5
+ * When invoked with a subcommand (eval, list, --help), runs as a CLI tool.
6
+ * Otherwise, starts as an MCP stdio server.
9
7
  *
10
- * Tools exposed:
11
- * - get_judges: List all available judges
12
- * - evaluate_v2: Context/evidence-aware V2 evaluation
13
- * - evaluate_app_builder_flow: 3-step workflow (review, translate, tasks)
14
- * - evaluate_public_repo_report: Clone public repo and generate full report
15
- * - evaluate_code: Full panel review (all judges)
16
- * - evaluate_code_single_judge: Review by a specific judge
17
- * - evaluate_project: Multi-file project analysis
18
- * - evaluate_diff: Changed-line-only diff analysis
19
- * - analyze_dependencies: Supply-chain manifest analysis
8
+ * CLI usage:
9
+ * judges eval --file src/app.ts # evaluate a file
10
+ * judges eval --file src/app.ts --format sarif # SARIF output
11
+ * judges eval --judge cybersecurity server.ts # single judge
12
+ * cat file.ts | judges eval --language typescript # stdin pipe
13
+ * judges list # list all judges
14
+ * judges --help # show help
15
+ *
16
+ * MCP usage:
17
+ * Add to your MCP config (VS Code, Claude Desktop, etc.)
20
18
  */
21
19
  export {};
22
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;GAkBG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG"}
package/dist/index.js CHANGED
@@ -1,43 +1,51 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Judges Panel — MCP Server
3
+ * Judges Panel — MCP Server + CLI
4
4
  *
5
- * An MCP server that provides a panel of specialized judges to evaluate
6
- * AI-generated code. Each tool returns both automated pattern-detection
7
- * findings AND the judge's deep-review criteria, enabling the calling LLM
8
- * to perform thorough contextual analysis beyond what static patterns catch.
5
+ * When invoked with a subcommand (eval, list, --help), runs as a CLI tool.
6
+ * Otherwise, starts as an MCP stdio server.
9
7
  *
10
- * Tools exposed:
11
- * - get_judges: List all available judges
12
- * - evaluate_v2: Context/evidence-aware V2 evaluation
13
- * - evaluate_app_builder_flow: 3-step workflow (review, translate, tasks)
14
- * - evaluate_public_repo_report: Clone public repo and generate full report
15
- * - evaluate_code: Full panel review (all judges)
16
- * - evaluate_code_single_judge: Review by a specific judge
17
- * - evaluate_project: Multi-file project analysis
18
- * - evaluate_diff: Changed-line-only diff analysis
19
- * - analyze_dependencies: Supply-chain manifest analysis
8
+ * CLI usage:
9
+ * judges eval --file src/app.ts # evaluate a file
10
+ * judges eval --file src/app.ts --format sarif # SARIF output
11
+ * judges eval --judge cybersecurity server.ts # single judge
12
+ * cat file.ts | judges eval --language typescript # stdin pipe
13
+ * judges list # list all judges
14
+ * judges --help # show help
15
+ *
16
+ * MCP usage:
17
+ * Add to your MCP config (VS Code, Claude Desktop, etc.)
20
18
  */
21
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23
- import { registerTools } from "./tools/register.js";
24
- import { registerPrompts } from "./tools/prompts.js";
25
- // ─── Create MCP Server ──────────────────────────────────────────────────────
26
- const server = new McpServer({
27
- name: "judges",
28
- version: "2.0.0",
29
- });
30
- // ─── Register Tools & Prompts ────────────────────────────────────────────────
31
- registerTools(server);
32
- registerPrompts(server);
33
- // ─── Start Server ────────────────────────────────────────────────────────────
34
- async function main() {
35
- const transport = new StdioServerTransport();
36
- await server.connect(transport);
37
- console.error("Judges Panel MCP server running on stdio");
19
+ // ─── CLI Detection ──────────────────────────────────────────────────────────
20
+ // If the user passed a subcommand or flag, run as CLI instead of MCP server.
21
+ const cliCommands = new Set(["eval", "list", "evaluate"]);
22
+ const cliFlags = new Set(["--help", "-h", "--file", "-f", "--version", "-v"]);
23
+ const firstArg = process.argv[2];
24
+ if (firstArg && (cliCommands.has(firstArg) || cliFlags.has(firstArg))) {
25
+ // Dynamic import to avoid loading MCP SDK when running as CLI
26
+ import("./cli.js").then(({ runCli }) => runCli(process.argv));
27
+ }
28
+ else {
29
+ // ─── MCP Server Mode ────────────────────────────────────────────────────
30
+ import("@modelcontextprotocol/sdk/server/mcp.js")
31
+ .then(async ({ McpServer }) => {
32
+ const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
33
+ const { registerTools } = await import("./tools/register.js");
34
+ const { registerPrompts } = await import("./tools/prompts.js");
35
+ const server = new McpServer({
36
+ name: "judges",
37
+ version: "3.1.1",
38
+ });
39
+ registerTools(server);
40
+ registerPrompts(server);
41
+ const transport = new StdioServerTransport();
42
+ await server.connect(transport);
43
+ console.error("Judges Panel MCP server running on stdio");
44
+ })
45
+ .catch((err) => {
46
+ console.error("Failed to start Judges Panel:", err);
47
+ process.exit(1);
48
+ });
38
49
  }
39
- main().catch((err) => {
40
- console.error("Failed to start Judges Panel:", err);
41
- process.exit(1);
42
- });
50
+ export {};
43
51
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,+EAA+E;AAE/E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,gFAAgF;AAEhF,aAAa,CAAC,MAAM,CAAC,CAAC;AACtB,eAAe,CAAC,MAAM,CAAC,CAAC;AAExB,gFAAgF;AAEhF,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;AAC5D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,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,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAC1D,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,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAChE,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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevinrabun/judges",
3
- "version": "3.1.0",
3
+ "version": "3.1.1",
4
4
  "description": "35 specialized judges that evaluate AI-generated code for security, cost, and quality.",
5
5
  "mcpName": "io.github.KevinRabun/judges",
6
6
  "type": "module",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/kevinrabun/judges",
8
8
  "source": "github"
9
9
  },
10
- "version": "3.0.3",
10
+ "version": "3.1.1",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.0.3",
15
+ "version": "3.1.1",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }