@kevinrabun/judges 3.6.0 → 3.7.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/CHANGELOG.md +222 -0
- package/LICENSE +21 -0
- package/README.md +33 -17
- package/dist/calibration.d.ts.map +1 -1
- package/dist/calibration.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +211 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/benchmark.d.ts.map +1 -1
- package/dist/commands/benchmark.js +0 -13
- package/dist/commands/benchmark.js.map +1 -1
- package/dist/commands/config-share.d.ts.map +1 -1
- package/dist/commands/config-share.js +0 -3
- package/dist/commands/config-share.js.map +1 -1
- package/dist/commands/fix.d.ts +21 -0
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +2 -2
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/rule.js.map +1 -1
- package/dist/commands/smart-output.js +2 -2
- package/dist/commands/smart-output.js.map +1 -1
- package/dist/comparison.d.ts.map +1 -1
- package/dist/comparison.js.map +1 -1
- package/dist/fix-history.d.ts.map +1 -1
- package/dist/fix-history.js.map +1 -1
- package/dist/formatters/diagnostics.d.ts +1 -1
- package/dist/formatters/diagnostics.d.ts.map +1 -1
- package/dist/formatters/diagnostics.js +1 -1
- package/dist/formatters/diagnostics.js.map +1 -1
- package/dist/plugins.d.ts.map +1 -1
- package/dist/plugins.js +0 -1
- package/dist/plugins.js.map +1 -1
- package/package.json +2 -1
- package/server.json +2 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to **@kevinrabun/judges** are documented here.
|
|
4
|
+
|
|
5
|
+
## [3.7.1] — 2026-03-01
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- Added root `LICENSE` file (MIT) — was referenced in `package.json` `files` but missing from tarball.
|
|
9
|
+
- Added `CHANGELOG.md` to npm `files` array so it ships in the published package.
|
|
10
|
+
- Fixed CHANGELOG date and test count accuracy.
|
|
11
|
+
- VS Code extension: switched to `bundler` module resolution, fixed ESM/CJS import errors.
|
|
12
|
+
- VS Code extension: added `.vscodeignore` tuning, `galleryBanner` metadata, esbuild bundling.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## [3.7.0] — 2026-03-01
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- **`judges --version` command** — display installed version with update check.
|
|
20
|
+
- **`--fix` flag on eval** — evaluate and auto-fix in one step: `judges eval --fix src/app.ts`.
|
|
21
|
+
- **Glob / multi-file eval** — evaluate directories and patterns: `judges eval src/**/*.ts`.
|
|
22
|
+
- **Progress indicators** — `[1/12] src/app.ts…` progress during multi-file evaluation.
|
|
23
|
+
- **VS Code extension** — diagnostics, code actions, and quick-fix integration (`vscode-extension/`).
|
|
24
|
+
- **README terminal mockup** — SVG-based visual showing evaluation output.
|
|
25
|
+
- **`.judgesrc.example.json`** — annotated example configuration file.
|
|
26
|
+
- **GitHub Marketplace metadata** — enhanced `action.yml` for Marketplace discovery.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- `server.json` version synced to `3.7.0`.
|
|
30
|
+
- README test badge updated to **842**.
|
|
31
|
+
- Total test count: **842**.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## [3.6.0] — 2026-03-07
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- **Plugin system** (`--plugin`) — load custom evaluator plugins from npm packages or local files.
|
|
39
|
+
- **Finding fingerprints** — stable content-hash IDs for tracking findings across runs.
|
|
40
|
+
- **Calibration mode** (`judges calibrate`) — tune judge thresholds against known-good codebases.
|
|
41
|
+
- **Diagnostics format** (`--format diagnostics`) — LSP-compatible diagnostic output for editor integration.
|
|
42
|
+
- **Comparison command** (`judges compare`) — side-by-side feature matrix vs ESLint, SonarQube, Semgrep, CodeQL.
|
|
43
|
+
- **Language packs** (`judges pack`) — manage language-specific rule extensions.
|
|
44
|
+
- **Config sharing** (`judges config export/import`) — export and import team configurations.
|
|
45
|
+
- **Custom rules** (`judges rule create`) — define and manage custom evaluation rules.
|
|
46
|
+
- **Fix history** — track applied patches with undo support.
|
|
47
|
+
- **Smart output** — auto-detect terminal width and format output accordingly.
|
|
48
|
+
- **Feedback command** (`judges feedback`) — submit false-positive feedback for rule tuning.
|
|
49
|
+
- **Benchmark command** (`judges benchmark`) — run detection accuracy benchmarks against test suites.
|
|
50
|
+
- **14 new subsystem tests** for plugins, fingerprinting, calibration, and diagnostics.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
- CLI expanded from 14 to 22 commands.
|
|
54
|
+
- Output formats expanded from 7 to 8 (added `diagnostics`).
|
|
55
|
+
- Total test count: **819** (up from 754).
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- **`judges diff` command** — evaluate only changed lines from unified diff / git diff output. Pipe `git diff` directly or pass a patch file.
|
|
61
|
+
- **`judges deps` command** — analyze project dependencies for supply-chain risks across 11 manifest types (package.json, requirements.txt, Cargo.toml, go.mod, pom.xml, etc.).
|
|
62
|
+
- **`judges baseline create` command** — create a baseline JSON file from current findings for future suppression.
|
|
63
|
+
- **`judges completions` command** — generate shell completion scripts for bash, zsh, fish, and PowerShell.
|
|
64
|
+
- **`judges docs` command** — generate per-judge rule documentation in Markdown format, with `--output` for file output.
|
|
65
|
+
- **JUnit XML formatter** (`--format junit`) — CI/CD compatible output for Jenkins, Azure DevOps, GitHub Actions, GitLab CI.
|
|
66
|
+
- **CodeClimate JSON formatter** (`--format codeclimate`) — GitLab Code Quality widget compatible output with MD5 fingerprints.
|
|
67
|
+
- **Named presets** (`--preset`) — 6 built-in profiles: `strict`, `lenient`, `security-only`, `startup`, `compliance`, `performance`.
|
|
68
|
+
- **Config file support** (`--config`) — auto-discovers `.judgesrc` / `.judgesrc.json` in project root with full JSON Schema validation support.
|
|
69
|
+
- **`judgesrc.schema.json`** — JSON Schema for `.judgesrc` files with IDE autocomplete and validation.
|
|
70
|
+
- **`--min-score` flag** — exit non-zero when overall score falls below threshold (e.g. `--min-score 80`).
|
|
71
|
+
- **`--verbose` flag** — timing statistics and file-level detail in output.
|
|
72
|
+
- **`--quiet` flag** — suppress informational output, only show findings.
|
|
73
|
+
- **`--no-color` flag** — disable ANSI color codes for piped output.
|
|
74
|
+
- **CI Templates** — `judges ci-templates github` generates GitHub Actions workflow YAML.
|
|
75
|
+
- **24 new tests** covering all new formatters, commands, presets, and JSON Schema validation.
|
|
76
|
+
|
|
77
|
+
### Changed
|
|
78
|
+
- CLI expanded from 8 to 14 commands.
|
|
79
|
+
- Output formats expanded from 5 to 7 (added `junit`, `codeclimate`).
|
|
80
|
+
- Total test count: **754** (up from 730).
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## [3.4.0] — 2026-03-04
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
- **Init wizard** (`judges init`) — interactive project setup generating `.judgesrc` config.
|
|
88
|
+
- **Fix command** (`judges fix`) — auto-apply suggested patches from findings with `--apply` flag.
|
|
89
|
+
- **Watch mode** (`judges watch`) — file-system watcher for continuous evaluation during development.
|
|
90
|
+
- **Report command** (`judges report`) — full project analysis with HTML/JSON/Markdown output.
|
|
91
|
+
- **Hook command** (`judges hook`) — git pre-commit hook installation.
|
|
92
|
+
- **HTML formatter** — interactive browser-based report with severity filters and per-judge sections.
|
|
93
|
+
- **Baseline suppression** — suppress known findings from previous runs.
|
|
94
|
+
- **CI template generator** — `judges ci-templates` for GitLab CI, Azure Pipelines, Bitbucket Pipelines.
|
|
95
|
+
|
|
96
|
+
### Changed
|
|
97
|
+
- Total test count: **730**.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## [3.3.0] — 2026-03-02
|
|
102
|
+
|
|
103
|
+
### Changed
|
|
104
|
+
- **Unified tree-sitter AST** — consolidated `typescript-ast.ts` into `tree-sitter-ast.ts`, single parser for all 8 languages.
|
|
105
|
+
- Removed legacy TypeScript Compiler API dependency.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## [3.2.0] — 2026-02-29
|
|
110
|
+
|
|
111
|
+
### Added
|
|
112
|
+
- **Tree-sitter WASM integration** — structural AST analysis for 8 languages (TypeScript, JavaScript, Python, Go, Rust, Java, C#, C++).
|
|
113
|
+
- Language-specific structural patterns for each grammar.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## [3.1.1] — 2026-02-28
|
|
118
|
+
|
|
119
|
+
### Added
|
|
120
|
+
- **GitHub Action** (`action.yml`) — composite action for CI/CD with SARIF upload, fail-on-findings, and job summary.
|
|
121
|
+
- **Dockerfile** — multi-stage Node 20 Alpine build with non-root user for containerized usage.
|
|
122
|
+
- **GitHub Pages dashboard** (`docs/index.html`) — dark-themed dashboard showing project analysis results and judge directory.
|
|
123
|
+
- **Real-world evidence document** (`docs/real-world-evidence.md`) — Express.js, Flask, FastAPI analysis + before/after showcase.
|
|
124
|
+
- **Pages deployment workflow** (`.github/workflows/pages.yml`).
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## [3.1.0] — 2026-02-28
|
|
129
|
+
|
|
130
|
+
### Added
|
|
131
|
+
- **CLI evaluation mode** — `npx @kevinrabun/judges eval --file app.ts` runs the full tribunal from the command line, no MCP setup required. Supports `--language`, `--format`, `--judge`, and stdin piping.
|
|
132
|
+
- **Enhanced Python AST** — class-aware method extraction (`ClassName.method_name`), decorator detection, async function detection, self/cls parameter filtering, multi-line import handling.
|
|
133
|
+
- **Framework-aware analysis** — detects 14 frameworks (Express, React, Django, Flask, Spring, FastAPI, etc.) and reduces confidence on framework-idiomatic findings to cut false positives.
|
|
134
|
+
- **Content-hash LRU caching** — caches AST structure, taint flow, and tribunal results by content hash for faster re-evaluation of unchanged files.
|
|
135
|
+
- **SARIF 2.1.0 structural validator** — `validateSarifLog()` checks all mandatory SARIF properties before output.
|
|
136
|
+
- **Multi-line auto-fix patches** — 5 structural patch rules for Express helmet, CORS, rate limiting, error handlers, and health endpoints.
|
|
137
|
+
- **Confidence-weighted scoring** — findings now carry estimated confidence; low-confidence findings have reduced score impact.
|
|
138
|
+
- **Finding provenance** — every finding includes `provenance` field with rule ID and evidence trail for auditability.
|
|
139
|
+
- **Absence-based finding demotion** — findings flagging *missing* patterns are demoted from critical/high to medium to reduce false positives.
|
|
140
|
+
- **28 negative tests** for false positive prevention.
|
|
141
|
+
- **169 subsystem unit tests** (scoring, dedup, config, patches, suppression, SARIF, Python parser).
|
|
142
|
+
- **Quickstart example** (`examples/quickstart.ts`) using the package API.
|
|
143
|
+
- **CHANGELOG.md** with full version history.
|
|
144
|
+
|
|
145
|
+
### Fixed
|
|
146
|
+
- `server.json` version now stays in sync with `package.json`.
|
|
147
|
+
- MCP server version string updated from `2.0.0` to `3.1.0`.
|
|
148
|
+
- Demo example includes guidance for both in-repo and package-installed usage.
|
|
149
|
+
|
|
150
|
+
### Changed
|
|
151
|
+
- Total test count: **899** (702 integration + 28 negative + 169 subsystem).
|
|
152
|
+
- Python structural parser fully rewritten with two-pass class boundary detection.
|
|
153
|
+
- Class name extraction added for all supported languages (Python, Java, C#, Rust, Go).
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## [3.0.3] — 2026-02-27
|
|
158
|
+
|
|
159
|
+
### Fixed
|
|
160
|
+
- Resolved all 14 CodeQL ReDoS alerts via atomic character classes and possessive-style patterns.
|
|
161
|
+
- Suppressed 4 intentional vulnerability alerts in `examples/sample-vulnerable-api.ts` (test fixture).
|
|
162
|
+
- Resolved Dependabot `hono` IP spoofing alert via `overrides`.
|
|
163
|
+
- GitHub Releases now auto-created on tag push (`publish-mcp.yml`).
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## [3.0.2] — 2026-02-26
|
|
168
|
+
|
|
169
|
+
### Fixed
|
|
170
|
+
- Publish workflow repaired (npm provenance, correct trigger).
|
|
171
|
+
- Removed dead code from build artifacts.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## [3.0.1] — 2026-02-26
|
|
176
|
+
|
|
177
|
+
### Fixed
|
|
178
|
+
- Dropped Node 18 from CI matrix (ESLint 10 requires Node >= 20).
|
|
179
|
+
- Added adversarial mandate to code-structure and framework-safety judges.
|
|
180
|
+
- Fixed `FW-` rule prefix in README documentation.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## [3.0.0] — 2026-02-25
|
|
185
|
+
|
|
186
|
+
### Added
|
|
187
|
+
- **Monolith decomposition**: 35 specialized judges split from single evaluator file.
|
|
188
|
+
- **Built-in AST analysis** via TypeScript Compiler API — no separate parser needed.
|
|
189
|
+
- **App Builder Workflow** (3-step): release decision, plain-language risk summaries, prioritized remediation tasks.
|
|
190
|
+
- **V2 context-aware evaluation** with policy profiles, evidence calibration, specialty feedback, confidence scoring.
|
|
191
|
+
- **Public repository URL reporting** — clone any public repo and generate a full tribunal report.
|
|
192
|
+
- **Project-level analysis** with cross-file architectural detection (duplication, dependency cycles, god modules).
|
|
193
|
+
- **Diff evaluation** — analyze only changed lines for PR reviews.
|
|
194
|
+
- **Dependency analysis** — supply-chain manifest scanning.
|
|
195
|
+
- **SARIF output** for GitHub Code Scanning integration.
|
|
196
|
+
- **Inline suppression** via `judges-disable` comments.
|
|
197
|
+
- CI/CD infrastructure with GitHub Actions (CI, publish, PR review, daily automation).
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## [2.3.0] — 2026-02-24
|
|
202
|
+
|
|
203
|
+
### Added
|
|
204
|
+
- AI Code Safety judge with 12 AICS rules.
|
|
205
|
+
- Full `suggestedFix` and `confidence` coverage across all 427 findings.
|
|
206
|
+
- Multi-language detection via language pattern system.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
[3.7.0]: https://github.com/KevinRabun/judges/compare/v3.6.0...v3.7.0
|
|
211
|
+
[3.6.0]: https://github.com/KevinRabun/judges/compare/v3.5.0...v3.6.0
|
|
212
|
+
[3.5.0]: https://github.com/KevinRabun/judges/compare/v3.4.0...v3.5.0
|
|
213
|
+
[3.4.0]: https://github.com/KevinRabun/judges/compare/v3.3.0...v3.4.0
|
|
214
|
+
[3.3.0]: https://github.com/KevinRabun/judges/compare/v3.2.0...v3.3.0
|
|
215
|
+
[3.2.0]: https://github.com/KevinRabun/judges/compare/v3.1.1...v3.2.0
|
|
216
|
+
[3.1.1]: https://github.com/KevinRabun/judges/compare/v3.1.0...v3.1.1
|
|
217
|
+
[3.1.0]: https://github.com/KevinRabun/judges/compare/v3.0.3...v3.1.0
|
|
218
|
+
[3.0.3]: https://github.com/KevinRabun/judges/compare/v3.0.2...v3.0.3
|
|
219
|
+
[3.0.2]: https://github.com/KevinRabun/judges/compare/v3.0.1...v3.0.2
|
|
220
|
+
[3.0.1]: https://github.com/KevinRabun/judges/compare/v3.0.0...v3.0.1
|
|
221
|
+
[3.0.0]: https://github.com/KevinRabun/judges/compare/v2.3.0...v3.0.0
|
|
222
|
+
[2.3.0]: https://github.com/KevinRabun/judges/releases/tag/v2.3.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kevin Rabun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ An MCP (Model Context Protocol) server that provides a panel of **35 specialized
|
|
|
11
11
|
[](https://www.npmjs.com/package/@kevinrabun/judges)
|
|
12
12
|
[](https://www.npmjs.com/package/@kevinrabun/judges)
|
|
13
13
|
[](https://opensource.org/licenses/MIT)
|
|
14
|
-
[](https://github.com/KevinRabun/judges/actions)
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
@@ -32,6 +32,10 @@ AI code generators (Copilot, Cursor, Claude, ChatGPT, etc.) write code fast —
|
|
|
32
32
|
|
|
33
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.
|
|
34
34
|
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="docs/terminal-output.svg" alt="Judges — Terminal Output" width="680" />
|
|
37
|
+
</p>
|
|
38
|
+
|
|
35
39
|
---
|
|
36
40
|
|
|
37
41
|
## Quick Start
|
|
@@ -964,28 +968,40 @@ Each judge has a corresponding prompt for LLM-powered deep analysis:
|
|
|
964
968
|
|
|
965
969
|
## Configuration
|
|
966
970
|
|
|
967
|
-
|
|
971
|
+
Create a `.judgesrc.json` (or `.judgesrc`) file in your project root to customize evaluation behavior. See [`.judgesrc.example.json`](.judgesrc.example.json) for a copy-paste-ready template, or reference the [JSON Schema](judgesrc.schema.json) for full IDE autocompletion.
|
|
968
972
|
|
|
969
973
|
```json
|
|
970
974
|
{
|
|
971
|
-
"
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
}
|
|
979
|
-
}
|
|
975
|
+
"$schema": "https://github.com/KevinRabun/judges/blob/main/judgesrc.schema.json",
|
|
976
|
+
"preset": "strict",
|
|
977
|
+
"minSeverity": "medium",
|
|
978
|
+
"disabledRules": ["COST-*", "I18N-001"],
|
|
979
|
+
"disabledJudges": ["accessibility", "ethics-bias"],
|
|
980
|
+
"ruleOverrides": {
|
|
981
|
+
"SEC-003": { "severity": "critical" },
|
|
982
|
+
"DOC-*": { "disabled": true }
|
|
983
|
+
},
|
|
984
|
+
"languages": ["typescript", "python"],
|
|
985
|
+
"format": "text",
|
|
986
|
+
"failOnFindings": false,
|
|
987
|
+
"baseline": ""
|
|
980
988
|
}
|
|
981
989
|
```
|
|
982
990
|
|
|
983
|
-
| Field | Type | Description |
|
|
984
|
-
|
|
985
|
-
| `
|
|
986
|
-
| `
|
|
987
|
-
| `minSeverity` | `string` | Minimum severity to report: `critical
|
|
988
|
-
| `
|
|
991
|
+
| Field | Type | Default | Description |
|
|
992
|
+
|-------|------|---------|-------------|
|
|
993
|
+
| `$schema` | `string` | — | JSON Schema URL for IDE validation |
|
|
994
|
+
| `preset` | `string` | — | Named preset: `strict`, `lenient`, `security-only`, `startup`, `compliance`, `performance` |
|
|
995
|
+
| `minSeverity` | `string` | `"info"` | Minimum severity to report: `critical` · `high` · `medium` · `low` · `info` |
|
|
996
|
+
| `disabledRules` | `string[]` | `[]` | Rule IDs or prefix wildcards to suppress (e.g. `"COST-*"`, `"SEC-003"`) |
|
|
997
|
+
| `disabledJudges` | `string[]` | `[]` | Judge IDs to skip entirely (e.g. `"cost-effectiveness"`) |
|
|
998
|
+
| `ruleOverrides` | `object` | `{}` | Per-rule overrides keyed by rule ID or wildcard — `{ disabled?: boolean, severity?: string }` |
|
|
999
|
+
| `languages` | `string[]` | `[]` | Restrict analysis to specific languages (empty = all) |
|
|
1000
|
+
| `format` | `string` | `"text"` | Default output format: `text` · `json` · `sarif` · `markdown` · `html` · `junit` · `codeclimate` |
|
|
1001
|
+
| `failOnFindings` | `boolean` | `false` | Exit code 1 when verdict is `fail` — useful for CI gates |
|
|
1002
|
+
| `baseline` | `string` | `""` | Path to a baseline JSON file — matching findings are suppressed |
|
|
1003
|
+
|
|
1004
|
+
All evaluation tools (CLI and MCP) accept the same configuration fields via `--config <path>` or inline `config` parameter.
|
|
989
1005
|
|
|
990
1006
|
---
|
|
991
1007
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calibration.d.ts","sourceRoot":"","sources":["../src/calibration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,
|
|
1
|
+
{"version":3,"file":"calibration.d.ts","sourceRoot":"","sources":["../src/calibration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAI/E,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,kDAAkD;IAClD,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,sDAAsD;IACtD,QAAQ,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,CAGvF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,kBAAkB,CAgD9G;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,EAAE,CAsCX;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,EAAE,CAGlG"}
|
package/dist/calibration.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calibration.js","sourceRoot":"","sources":["../src/calibration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"calibration.js","sourceRoot":"","sources":["../src/calibration.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AA4gBH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0Z1D"}
|
package/dist/cli.js
CHANGED
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
* judges hook install # install pre-commit
|
|
20
20
|
* judges eval --help # show help
|
|
21
21
|
*/
|
|
22
|
-
import { readFileSync, existsSync } from "fs";
|
|
23
|
-
import { resolve, extname } from "path";
|
|
22
|
+
import { readFileSync, existsSync, readdirSync, statSync, writeFileSync } from "fs";
|
|
23
|
+
import { resolve, extname, dirname, relative, join } from "path";
|
|
24
|
+
import { fileURLToPath } from "url";
|
|
24
25
|
import { evaluateWithTribunal, evaluateWithJudge, formatVerdictAsMarkdown, formatEvaluationAsMarkdown, } from "./evaluators/index.js";
|
|
25
26
|
import { getJudge, getJudgeSummaries } from "./judges/index.js";
|
|
26
27
|
import { verdictToSarif } from "./formatters/sarif.js";
|
|
@@ -37,6 +38,7 @@ import { runDocs } from "./commands/docs.js";
|
|
|
37
38
|
import { generateGitLabCi, generateAzurePipelines, generateBitbucketPipelines } from "./commands/ci-templates.js";
|
|
38
39
|
import { getPreset, listPresets } from "./presets.js";
|
|
39
40
|
import { parseConfig } from "./config.js";
|
|
41
|
+
import { applyPatches } from "./commands/fix.js";
|
|
40
42
|
import { runFeedback } from "./commands/feedback.js";
|
|
41
43
|
import { runBenchmark } from "./commands/benchmark.js";
|
|
42
44
|
import { runRule } from "./commands/rule.js";
|
|
@@ -100,6 +102,7 @@ function parseCliArgs(argv) {
|
|
|
100
102
|
noColor: false,
|
|
101
103
|
verbose: false,
|
|
102
104
|
quiet: false,
|
|
105
|
+
fix: false,
|
|
103
106
|
};
|
|
104
107
|
// First non-flag arg is the command
|
|
105
108
|
let i = 2; // skip node + script
|
|
@@ -160,6 +163,9 @@ function parseCliArgs(argv) {
|
|
|
160
163
|
case "--quiet":
|
|
161
164
|
args.quiet = true;
|
|
162
165
|
break;
|
|
166
|
+
case "--fix":
|
|
167
|
+
args.fix = true;
|
|
168
|
+
break;
|
|
163
169
|
default:
|
|
164
170
|
// If it looks like a file path (not a flag), treat as --file
|
|
165
171
|
if (!arg.startsWith("-") && !args.file) {
|
|
@@ -196,6 +202,7 @@ USAGE:
|
|
|
196
202
|
judges config Export/import shared team configs
|
|
197
203
|
judges compare Compare judges vs other tools
|
|
198
204
|
judges list List all available judges
|
|
205
|
+
judges version Show version information
|
|
199
206
|
judges --help Show this help
|
|
200
207
|
|
|
201
208
|
EVAL OPTIONS:
|
|
@@ -212,6 +219,7 @@ EVAL OPTIONS:
|
|
|
212
219
|
--no-color Disable colored output
|
|
213
220
|
--verbose Show detailed evaluation information
|
|
214
221
|
--quiet Suppress non-essential output
|
|
222
|
+
--fix Auto-fix findings after evaluation (applies patches in-place)
|
|
215
223
|
--help, -h Show this help
|
|
216
224
|
|
|
217
225
|
FIX OPTIONS:
|
|
@@ -299,6 +307,48 @@ function readCode(filePath) {
|
|
|
299
307
|
console.error("Usage: judges eval --file <path> or cat file | judges eval --language <lang>");
|
|
300
308
|
process.exit(1);
|
|
301
309
|
}
|
|
310
|
+
// ─── Glob / Multi-File Resolution ───────────────────────────────────────────
|
|
311
|
+
const SUPPORTED_EXTENSIONS = new Set(Object.keys(EXT_TO_LANG));
|
|
312
|
+
function collectFiles(target) {
|
|
313
|
+
const resolved = resolve(target);
|
|
314
|
+
if (!existsSync(resolved))
|
|
315
|
+
return [];
|
|
316
|
+
const stat = statSync(resolved);
|
|
317
|
+
if (stat.isFile())
|
|
318
|
+
return [resolved];
|
|
319
|
+
if (stat.isDirectory()) {
|
|
320
|
+
const files = [];
|
|
321
|
+
walkDir(resolved, files);
|
|
322
|
+
return files;
|
|
323
|
+
}
|
|
324
|
+
return [];
|
|
325
|
+
}
|
|
326
|
+
function walkDir(dir, results) {
|
|
327
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
328
|
+
for (const entry of entries) {
|
|
329
|
+
const fullPath = join(dir, entry.name);
|
|
330
|
+
// Skip common non-source directories
|
|
331
|
+
if (entry.isDirectory()) {
|
|
332
|
+
if (["node_modules", ".git", "dist", "build", ".next", "__pycache__", "target", "vendor"].includes(entry.name))
|
|
333
|
+
continue;
|
|
334
|
+
walkDir(fullPath, results);
|
|
335
|
+
}
|
|
336
|
+
else if (entry.isFile()) {
|
|
337
|
+
const ext = extname(entry.name);
|
|
338
|
+
if (SUPPORTED_EXTENSIONS.has(ext)) {
|
|
339
|
+
results.push(fullPath);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function isDirectory(filePath) {
|
|
345
|
+
try {
|
|
346
|
+
return statSync(resolve(filePath)).isDirectory();
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
302
352
|
// ─── Format Output ──────────────────────────────────────────────────────────
|
|
303
353
|
function formatTribunalOutput(verdict, format, filePath) {
|
|
304
354
|
switch (format) {
|
|
@@ -406,9 +456,36 @@ function listJudges() {
|
|
|
406
456
|
console.log(` Total: ${judges.length} judges`);
|
|
407
457
|
console.log("");
|
|
408
458
|
}
|
|
459
|
+
// ─── Version ────────────────────────────────────────────────────────────────
|
|
460
|
+
function getPackageVersion() {
|
|
461
|
+
try {
|
|
462
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
463
|
+
const __dirname = dirname(__filename);
|
|
464
|
+
const pkgPath = resolve(__dirname, "..", "package.json");
|
|
465
|
+
if (existsSync(pkgPath)) {
|
|
466
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
467
|
+
return pkg.version || "unknown";
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
catch {
|
|
471
|
+
// fallback
|
|
472
|
+
}
|
|
473
|
+
return "unknown";
|
|
474
|
+
}
|
|
475
|
+
function printVersion() {
|
|
476
|
+
const version = getPackageVersion();
|
|
477
|
+
console.log(`@kevinrabun/judges v${version}`);
|
|
478
|
+
console.log(`Node.js ${process.version}`);
|
|
479
|
+
console.log(`Platform: ${process.platform} ${process.arch}`);
|
|
480
|
+
}
|
|
409
481
|
// ─── Main CLI Entry Point ───────────────────────────────────────────────────
|
|
410
482
|
export async function runCli(argv) {
|
|
411
483
|
const args = parseCliArgs(argv);
|
|
484
|
+
// ─── Version Command ─────────────────────────────────────────────────
|
|
485
|
+
if (args.command === "version" || args.command === "--version" || argv.includes("--version") || argv.includes("-V")) {
|
|
486
|
+
printVersion();
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
412
489
|
if (args.help || (!args.command && !args.file)) {
|
|
413
490
|
printHelp();
|
|
414
491
|
process.exit(0);
|
|
@@ -521,8 +598,6 @@ export async function runCli(argv) {
|
|
|
521
598
|
// ─── Eval Command ────────────────────────────────────────────────────
|
|
522
599
|
if (args.command === "eval" || args.file) {
|
|
523
600
|
const startTime = Date.now();
|
|
524
|
-
const { code, resolvedPath } = readCode(args.file);
|
|
525
|
-
const language = args.language || detectLanguage(args.file || resolvedPath) || "typescript";
|
|
526
601
|
// Load config from file or preset
|
|
527
602
|
const evalConfig = loadEvalConfig(args);
|
|
528
603
|
// Load baseline if specified (from CLI flag — config doesn't carry baseline)
|
|
@@ -532,6 +607,91 @@ export async function runCli(argv) {
|
|
|
532
607
|
}
|
|
533
608
|
// Build evaluation options from config
|
|
534
609
|
const evalOptions = evalConfig ? { config: evalConfig } : undefined;
|
|
610
|
+
// ── Multi-file / directory mode ──────────────────────────────────────
|
|
611
|
+
const target = args.file;
|
|
612
|
+
if (target && isDirectory(target)) {
|
|
613
|
+
const files = collectFiles(target);
|
|
614
|
+
if (files.length === 0) {
|
|
615
|
+
console.error(`No supported source files found in: ${target}`);
|
|
616
|
+
process.exit(1);
|
|
617
|
+
}
|
|
618
|
+
if (!args.quiet) {
|
|
619
|
+
console.log(`\n Scanning ${files.length} file(s) in ${target}…\n`);
|
|
620
|
+
}
|
|
621
|
+
let totalFindings = 0;
|
|
622
|
+
let totalCritical = 0;
|
|
623
|
+
let totalHigh = 0;
|
|
624
|
+
let failCount = 0;
|
|
625
|
+
let totalFixed = 0;
|
|
626
|
+
for (let idx = 0; idx < files.length; idx++) {
|
|
627
|
+
const filePath = files[idx];
|
|
628
|
+
const relPath = relative(resolve("."), filePath);
|
|
629
|
+
if (!args.quiet) {
|
|
630
|
+
process.stderr.write(` [${idx + 1}/${files.length}] ${relPath}…`);
|
|
631
|
+
}
|
|
632
|
+
const fileCode = readFileSync(filePath, "utf-8");
|
|
633
|
+
const fileLang = args.language || detectLanguage(filePath) || "typescript";
|
|
634
|
+
const verdict = evaluateWithTribunal(fileCode, fileLang, undefined, evalOptions);
|
|
635
|
+
// Apply baseline suppression
|
|
636
|
+
if (baselineFindings) {
|
|
637
|
+
for (const evaluation of verdict.evaluations) {
|
|
638
|
+
evaluation.findings = evaluation.findings.filter((f) => !baselineFindings.has(baselineKey(f)));
|
|
639
|
+
}
|
|
640
|
+
verdict.findings = verdict.findings.filter((f) => !baselineFindings.has(baselineKey(f)));
|
|
641
|
+
}
|
|
642
|
+
const fileFindings = verdict.evaluations.reduce((s, e) => s + e.findings.length, 0);
|
|
643
|
+
totalFindings += fileFindings;
|
|
644
|
+
totalCritical += verdict.criticalCount;
|
|
645
|
+
totalHigh += verdict.highCount;
|
|
646
|
+
if (verdict.overallVerdict === "fail")
|
|
647
|
+
failCount++;
|
|
648
|
+
if (!args.quiet) {
|
|
649
|
+
const icon = verdict.overallVerdict === "pass" ? "✅" : verdict.overallVerdict === "warning" ? "⚠️" : "❌";
|
|
650
|
+
process.stderr.write(` ${icon} ${verdict.overallScore}/100 (${fileFindings} findings)\n`);
|
|
651
|
+
}
|
|
652
|
+
// Auto-fix in multi-file mode
|
|
653
|
+
if (args.fix) {
|
|
654
|
+
const allFileFindings = verdict.evaluations.flatMap((e) => e.findings);
|
|
655
|
+
const fixable = allFileFindings
|
|
656
|
+
.filter((f) => f.patch)
|
|
657
|
+
.map((f) => ({
|
|
658
|
+
ruleId: f.ruleId,
|
|
659
|
+
title: f.title,
|
|
660
|
+
severity: f.severity,
|
|
661
|
+
patch: f.patch,
|
|
662
|
+
lineNumbers: f.lineNumbers,
|
|
663
|
+
}));
|
|
664
|
+
if (fixable.length > 0) {
|
|
665
|
+
const patchResult = applyPatches(fileCode, fixable);
|
|
666
|
+
writeFileSync(filePath, patchResult.result, "utf-8");
|
|
667
|
+
totalFixed += patchResult.applied;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
const elapsed = Date.now() - startTime;
|
|
672
|
+
// Summary
|
|
673
|
+
console.log("");
|
|
674
|
+
console.log("╔══════════════════════════════════════════════════════════════╗");
|
|
675
|
+
console.log("║ Judges Panel — Multi-File Summary ║");
|
|
676
|
+
console.log("╚══════════════════════════════════════════════════════════════╝");
|
|
677
|
+
console.log("");
|
|
678
|
+
console.log(` Files : ${files.length}`);
|
|
679
|
+
console.log(` Findings : ${totalFindings}`);
|
|
680
|
+
console.log(` Critical : ${totalCritical}`);
|
|
681
|
+
console.log(` High : ${totalHigh}`);
|
|
682
|
+
console.log(` Failed : ${failCount} file(s)`);
|
|
683
|
+
if (args.fix && totalFixed > 0) {
|
|
684
|
+
console.log(` Fixed : ${totalFixed} patch(es) applied`);
|
|
685
|
+
}
|
|
686
|
+
console.log(` Time : ${elapsed}ms`);
|
|
687
|
+
console.log("");
|
|
688
|
+
if (args.failOnFindings && failCount > 0)
|
|
689
|
+
process.exit(1);
|
|
690
|
+
process.exit(0);
|
|
691
|
+
}
|
|
692
|
+
// ── Single-file mode ─────────────────────────────────────────────────
|
|
693
|
+
const { code, resolvedPath } = readCode(args.file);
|
|
694
|
+
const language = args.language || detectLanguage(args.file || resolvedPath) || "typescript";
|
|
535
695
|
if (args.judge) {
|
|
536
696
|
// Single judge mode
|
|
537
697
|
const judge = getJudge(args.judge);
|
|
@@ -586,6 +746,29 @@ export async function runCli(argv) {
|
|
|
586
746
|
console.error(`Score ${evaluation.score} is below minimum threshold ${args.minScore}`);
|
|
587
747
|
process.exit(1);
|
|
588
748
|
}
|
|
749
|
+
// Auto-fix if --fix flag is set (single judge mode)
|
|
750
|
+
if (args.fix && resolvedPath) {
|
|
751
|
+
const fixable = evaluation.findings
|
|
752
|
+
.filter((f) => f.patch)
|
|
753
|
+
.map((f) => ({
|
|
754
|
+
ruleId: f.ruleId,
|
|
755
|
+
title: f.title,
|
|
756
|
+
severity: f.severity,
|
|
757
|
+
patch: f.patch,
|
|
758
|
+
lineNumbers: f.lineNumbers,
|
|
759
|
+
}));
|
|
760
|
+
if (fixable.length > 0) {
|
|
761
|
+
const { result, applied, skipped } = applyPatches(code, fixable);
|
|
762
|
+
writeFileSync(resolvedPath, result, "utf-8");
|
|
763
|
+
console.log(`\n ✅ Applied ${applied} fix(es) to ${args.file || resolvedPath}`);
|
|
764
|
+
if (skipped > 0) {
|
|
765
|
+
console.log(` ⏭ Skipped ${skipped} fix(es) (source text changed)`);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
else if (!args.quiet) {
|
|
769
|
+
console.log("\n No auto-fixable findings.");
|
|
770
|
+
}
|
|
771
|
+
}
|
|
589
772
|
}
|
|
590
773
|
else {
|
|
591
774
|
// Full tribunal mode
|
|
@@ -632,6 +815,30 @@ export async function runCli(argv) {
|
|
|
632
815
|
console.error(`Score ${verdict.overallScore} is below minimum threshold ${args.minScore}`);
|
|
633
816
|
process.exit(1);
|
|
634
817
|
}
|
|
818
|
+
// Auto-fix if --fix flag is set
|
|
819
|
+
if (args.fix && resolvedPath) {
|
|
820
|
+
const allFindings = verdict.evaluations.flatMap((e) => e.findings);
|
|
821
|
+
const fixable = allFindings
|
|
822
|
+
.filter((f) => f.patch)
|
|
823
|
+
.map((f) => ({
|
|
824
|
+
ruleId: f.ruleId,
|
|
825
|
+
title: f.title,
|
|
826
|
+
severity: f.severity,
|
|
827
|
+
patch: f.patch,
|
|
828
|
+
lineNumbers: f.lineNumbers,
|
|
829
|
+
}));
|
|
830
|
+
if (fixable.length > 0) {
|
|
831
|
+
const { result, applied, skipped } = applyPatches(code, fixable);
|
|
832
|
+
writeFileSync(resolvedPath, result, "utf-8");
|
|
833
|
+
console.log(`\n ✅ Applied ${applied} fix(es) to ${args.file || resolvedPath}`);
|
|
834
|
+
if (skipped > 0) {
|
|
835
|
+
console.log(` ⏭ Skipped ${skipped} fix(es) (source text changed)`);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
else if (!args.quiet) {
|
|
839
|
+
console.log("\n No auto-fixable findings.");
|
|
840
|
+
}
|
|
841
|
+
}
|
|
635
842
|
}
|
|
636
843
|
process.exit(0);
|
|
637
844
|
}
|