code-auditor-mcp 4.0.2 → 4.0.4
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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +79 -4
- package/dist/cli.js +28 -3
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/dataPaths.d.ts +11 -0
- package/dist/dataPaths.d.ts.map +1 -1
- package/dist/dataPaths.js +13 -0
- package/dist/dataPaths.js.map +1 -1
- package/dist/languages/RuntimeManager.d.ts +4 -2
- package/dist/languages/RuntimeManager.d.ts.map +1 -1
- package/dist/languages/RuntimeManager.js +65 -35
- package/dist/languages/RuntimeManager.js.map +1 -1
- package/dist/languages/go/{analyzer → analyzer-darwin-amd64} +0 -0
- package/dist/languages/go/analyzer-darwin-arm64 +0 -0
- package/dist/languages/go/analyzer-linux-amd64 +0 -0
- package/dist/languages/go/analyzer-linux-arm64 +0 -0
- package/dist/languages/go/analyzer-windows-amd64.exe +0 -0
- package/dist/languages/goBinary.d.ts +8 -7
- package/dist/languages/goBinary.d.ts.map +1 -1
- package/dist/languages/goBinary.js +8 -7
- package/dist/languages/goBinary.js.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts +17 -0
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +123 -15
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -1
- package/dist/mcpAuditJobs.d.ts.map +1 -1
- package/dist/mcpAuditJobs.js +6 -2
- package/dist/mcpAuditJobs.js.map +1 -1
- package/dist/reporting/reportGenerator.d.ts +2 -1
- package/dist/reporting/reportGenerator.d.ts.map +1 -1
- package/dist/reporting/reportGenerator.js +2 -2
- package/dist/reporting/reportGenerator.js.map +1 -1
- package/dist/reporting/sarifReportGenerator.d.ts +15 -0
- package/dist/reporting/sarifReportGenerator.d.ts.map +1 -1
- package/dist/reporting/sarifReportGenerator.js +75 -15
- package/dist/reporting/sarifReportGenerator.js.map +1 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/skills/code-auditor/SKILL.md +1 -1
- package/server.json +2 -2
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "code-auditor",
|
|
11
11
|
"source": "./plugin",
|
|
12
12
|
"description": "Diff-scoped code quality auditing on every edit. Indexes your codebase, enforces invariants, and feeds violations back to the agent so fixes happen inline.",
|
|
13
|
-
"version": "4.0.
|
|
13
|
+
"version": "4.0.4",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Ben Hammond"
|
|
16
16
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,81 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the Code Auditor MCP project.
|
|
4
4
|
|
|
5
|
-
## [4.0.
|
|
5
|
+
## [4.0.4] — 2026-09-20
|
|
6
|
+
|
|
7
|
+
### Go analysis now works everywhere, not just Intel Macs
|
|
8
|
+
|
|
9
|
+
Go analysis silently returned zero findings on every platform but Intel Macs.
|
|
10
|
+
The shipped Go analyzer was a single `darwin/amd64` binary, so Apple Silicon,
|
|
11
|
+
Linux, and Windows (including all Linux/Windows CI) skipped Go entirely and
|
|
12
|
+
reported a clean tree. That silent-skip is fixed:
|
|
13
|
+
|
|
14
|
+
- **Per-platform binaries** — five static `CGO_ENABLED=0` binaries ship in the
|
|
15
|
+
package (`analyzer-darwin-arm64`, `analyzer-darwin-amd64`,
|
|
16
|
+
`analyzer-linux-amd64`, `analyzer-linux-arm64`, `analyzer-windows-amd64.exe`),
|
|
17
|
+
cross-compiled from one machine. The runtime picks the binary from **Node's**
|
|
18
|
+
platform/arch (Node spawns the process), not the Go toolchain's — a subtlety
|
|
19
|
+
that matters under Rosetta, where `go env` reports `amd64` while Node reports
|
|
20
|
+
`arm64`.
|
|
21
|
+
- **Cache-dir rebuild fallback** — when no native binary is present, the
|
|
22
|
+
analyzer now builds into the OS cache dir (`~/Library/Caches/code-auditor`,
|
|
23
|
+
`~/.cache/code-auditor`, `%LOCALAPPDATA%\code-auditor`) instead of writing into
|
|
24
|
+
the read-only shipped tree and overwriting the artifact.
|
|
25
|
+
- **Silent failure now says so** — a missing toolchain, wrong-arch binary, or
|
|
26
|
+
failed build surfaces as a named `Skipped analyzers` diagnostic in the text
|
|
27
|
+
CLI (`go-toolchain-missing`, `go-analyzer-wrong-arch`,
|
|
28
|
+
`go-analyzer-build-failed`) instead of a silent zero.
|
|
29
|
+
- **Guard 8** now asserts all five shipped binaries are present *and* that the
|
|
30
|
+
running platform's binary executes — a build where one cross-compile failed
|
|
31
|
+
can no longer pass on one machine and ship broken for another.
|
|
32
|
+
|
|
33
|
+
## [4.0.3] — 2026-09-20
|
|
34
|
+
|
|
35
|
+
### SQL injection: parameterized-query false positives fixed
|
|
36
|
+
|
|
37
|
+
Two parameterized-query idioms were misread as `sql-injection-risk` at every
|
|
38
|
+
prior count. The safety analysis now proves them safe instead of flagging them:
|
|
39
|
+
|
|
40
|
+
- **Placeholder list** — `filePaths.map(() => '?').join(', ')` is a constant
|
|
41
|
+
list of `?` placeholders regardless of the source array's contents; the values
|
|
42
|
+
are bound out-of-band, so the interpolated text is never raw data.
|
|
43
|
+
- **Literal clause template** — `['run_id = ?', 'rule = ?'].join(' AND ')` is a
|
|
44
|
+
join over literal `col = ?` fragments with values bound out-of-band. A new
|
|
45
|
+
`isSafeJoin` proves the receiver and every `.push()`ed element are safe, so a
|
|
46
|
+
`.push(userInput)` before the join is still flagged.
|
|
47
|
+
|
|
48
|
+
The two patterns were clearing real findings in `codeIndexDB`, `blastRadius`,
|
|
49
|
+
and `ledger`. Both are now correctly recognized as safe; the remaining
|
|
50
|
+
`sql-injection-risk` findings are genuine dynamic SQL (table/column identifier
|
|
51
|
+
interpolation, escaped name lists, reassigned `let` clauses) rather than
|
|
52
|
+
parameterized queries. Guard coverage is pinned by new fixtures
|
|
53
|
+
(`placeholder-list.ts`, `clause-template.ts`) asserting exact zero counts.
|
|
54
|
+
|
|
55
|
+
This also fixed a latent scope-resolution bug: `findEnclosingScope` fell back to
|
|
56
|
+
file-level first-match when a wrapped node was detached from its parent chain,
|
|
57
|
+
so `const where: string[] = [...]` in one function could resolve against a
|
|
58
|
+
different function's `let where` of the same name. The enclosing scope is now
|
|
59
|
+
resolved through the raw parent chain.
|
|
60
|
+
|
|
61
|
+
### SARIF: version-control provenance and schema validity
|
|
62
|
+
|
|
63
|
+
SARIF 2.1.0 output now carries GitHub Code Scanning metadata and emits only
|
|
64
|
+
schema-valid fields:
|
|
65
|
+
|
|
66
|
+
- `versionControlProvenance` (`repositoryUri` + `revisionId`) is read
|
|
67
|
+
best-effort from the project's git remote and HEAD, so uploaded alerts are
|
|
68
|
+
tied to a commit.
|
|
69
|
+
- `automationDetails.id` is set to `<tool>/<version>`, giving this tool's
|
|
70
|
+
uploads a distinct analysis category alongside CodeQL and others.
|
|
71
|
+
- Suggestions are emitted as `properties.resolution` (and a `help` string per
|
|
72
|
+
rule) instead of a bare `fixes` array — a SARIF fix requires `artifactChanges`,
|
|
73
|
+
which this tool does not produce, so the old output was schema-invalid.
|
|
74
|
+
- `startColumn` is omitted rather than clamped for 0-based/unknown columns
|
|
75
|
+
(SARIF requires a minimum of 1).
|
|
76
|
+
- Partial fingerprints are computed from the repo-relative path so GitHub alert
|
|
77
|
+
identity is stable across checkouts and machines.
|
|
78
|
+
|
|
79
|
+
|
|
6
80
|
|
|
7
81
|
### Severity vocabulary restored: `advisory` → `high`
|
|
8
82
|
|
|
@@ -14,15 +88,16 @@ tool results. The three non-severity meanings of "advisory" are unchanged: hook
|
|
|
14
88
|
mode (`hookType: 'blocking' | 'advisory' | 'none'`), the non-invariant
|
|
15
89
|
"advisory findings" report channel, and consultative "advisory" (= non-fatal).
|
|
16
90
|
|
|
17
|
-
###
|
|
91
|
+
### Sixteen rules restored from `severe` to `high`
|
|
18
92
|
|
|
19
|
-
The same recalibration escalated
|
|
93
|
+
The same recalibration escalated sixteen rules to `severe` that Spec 54 had
|
|
20
94
|
deliberately placed at `high`. They return to `high`:
|
|
21
95
|
|
|
22
96
|
`solid/class-size`, `solid/method-complexity`, `solid/dependency-inversion`,
|
|
23
97
|
`interface-size`, `parameter-count`, `function-length`, `function-size`,
|
|
24
98
|
`struct-size`, `switch-size`, `dry/duplicate`, `complex-query`,
|
|
25
|
-
`unfiltered-query`, `imports/import-style`, `tight-coupling`,
|
|
99
|
+
`unfiltered-query`, `react/performance`, `imports/import-style`, `tight-coupling`,
|
|
100
|
+
`hub-nodes`.
|
|
26
101
|
|
|
27
102
|
### Severity-ledger conformance guard
|
|
28
103
|
|
package/dist/cli.js
CHANGED
|
@@ -175,6 +175,25 @@ program
|
|
|
175
175
|
`${covUnassessed} unassessed · ${covNotApplicable} not-applicable · ` +
|
|
176
176
|
`${covCannotFire} cannot-fire`));
|
|
177
177
|
}
|
|
178
|
+
// ── Skipped analyzers (Spec 61) ──────────────────────────────
|
|
179
|
+
// A language present on disk but never analyzed is a stated gap, not a
|
|
180
|
+
// silent zero. The Go path surfaces a named runtime failure (missing
|
|
181
|
+
// toolchain, wrong-arch prebuilt binary, failed rebuild) as a
|
|
182
|
+
// metadata.diagnostics entry; before this section those kinds were
|
|
183
|
+
// invisible outside --json, so a polyglot repo with .go files and no Go
|
|
184
|
+
// toolchain printed zero Go findings and exited clean — the silent-zero
|
|
185
|
+
// failure mode. These lead above coverage gaps: a skipped analyzer is a
|
|
186
|
+
// whole language unmeasured, more severe than a per-file visibility gap.
|
|
187
|
+
const skippedAnalyzers = (result.metadata?.diagnostics ?? []).filter((d) => d.kind === 'go-toolchain-missing' ||
|
|
188
|
+
d.kind === 'go-analyzer-wrong-arch' ||
|
|
189
|
+
d.kind === 'go-analyzer-build-failed');
|
|
190
|
+
if (skippedAnalyzers.length > 0) {
|
|
191
|
+
console.log(chalk.yellow(`── Skipped analyzers ── ${skippedAnalyzers.length}`));
|
|
192
|
+
for (const d of skippedAnalyzers) {
|
|
193
|
+
const name = d.analyzerName || 'go';
|
|
194
|
+
console.log(chalk.yellow(` ${name} [${d.kind}] — ${d.message}`));
|
|
195
|
+
}
|
|
196
|
+
}
|
|
178
197
|
// ── Coverage gaps (Spec 58 follow-up) ─────────────────────────
|
|
179
198
|
// Coverage diagnostics are the analyzer saying "my visibility ends here",
|
|
180
199
|
// not "the code is wrong". They lead with counts, then per-occurrence
|
|
@@ -419,7 +438,12 @@ program
|
|
|
419
438
|
process.exit(1);
|
|
420
439
|
}
|
|
421
440
|
const { generateReport } = await import('./reporting/reportGenerator.js');
|
|
422
|
-
const
|
|
441
|
+
const { readVersionControlProvenance } = await import('./reporting/sarifReportGenerator.js');
|
|
442
|
+
const rootDir = resolve(options.path || process.cwd());
|
|
443
|
+
const config = options.format === 'sarif'
|
|
444
|
+
? { rootDir, ...readVersionControlProvenance(rootDir) }
|
|
445
|
+
: { rootDir };
|
|
446
|
+
const report = generateReport(result, options.format, config);
|
|
423
447
|
const outputDir = options.output || process.cwd();
|
|
424
448
|
const ext = options.format === 'sarif' ? 'sarif' : options.format;
|
|
425
449
|
const reportPath = join(outputDir, `audit-report.${ext}`);
|
|
@@ -573,8 +597,9 @@ program
|
|
|
573
597
|
const { blocking, resolutionGaps } = computeGatingDecision(violations, BLOCKING_SEVERITIES);
|
|
574
598
|
// JSON output
|
|
575
599
|
if (options.format === 'sarif') {
|
|
576
|
-
const { generateSARIFReport } = await import('./reporting/sarifReportGenerator.js');
|
|
577
|
-
const
|
|
600
|
+
const { generateSARIFReport, readVersionControlProvenance } = await import('./reporting/sarifReportGenerator.js');
|
|
601
|
+
const projectDir = resolve(options.path || process.cwd());
|
|
602
|
+
const sarifOutput = generateSARIFReport(result, { rootDir: projectDir, ...readVersionControlProvenance(projectDir) });
|
|
578
603
|
process.stdout.write(sarifOutput + '\n');
|
|
579
604
|
}
|
|
580
605
|
else if (options.json) {
|