code-auditor-mcp 3.9.11 → 4.0.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +200 -0
- package/dist/analyzers/analyzerUtils.js +2 -2
- package/dist/analyzers/analyzerUtils.js.map +1 -1
- package/dist/analyzers/applicability.d.ts.map +1 -1
- package/dist/analyzers/applicability.js +1 -0
- package/dist/analyzers/applicability.js.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js +3 -3
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.d.ts +2 -2
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js +39 -15
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js.map +1 -1
- package/dist/analyzers/documentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/documentationAnalyzer.js +14 -16
- package/dist/analyzers/documentationAnalyzer.js.map +1 -1
- package/dist/analyzers/invariantsAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/invariantsAnalyzer.js +30 -25
- package/dist/analyzers/invariantsAnalyzer.js.map +1 -1
- package/dist/analyzers/reactAnalyzer.d.ts +1 -1
- package/dist/analyzers/reactAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/reactAnalyzer.js +34 -116
- package/dist/analyzers/reactAnalyzer.js.map +1 -1
- package/dist/analyzers/ruleRegistry.d.ts +5 -3
- package/dist/analyzers/ruleRegistry.d.ts.map +1 -1
- package/dist/analyzers/ruleRegistry.js +198 -54
- package/dist/analyzers/ruleRegistry.js.map +1 -1
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.d.ts +2 -2
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.js +10 -17
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +6 -6
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js +13 -13
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +22 -64
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts +3 -2
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +14 -13
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +11 -11
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +18 -7
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts +2 -2
- package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalStylesAnalyzer.js +38 -26
- package/dist/analyzers/universal/UniversalStylesAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/schema/codeAnalysis.d.ts +37 -13
- package/dist/analyzers/universal/schema/codeAnalysis.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/codeAnalysis.js +42 -54
- package/dist/analyzers/universal/schema/codeAnalysis.js.map +1 -1
- package/dist/analyzers/universal/schema/jsonSchema.js +1 -1
- package/dist/analyzers/universal/schema/jsonSchema.js.map +1 -1
- package/dist/analyzers/universal/schema/violations.d.ts +1 -1
- package/dist/analyzers/universal/schema/violations.d.ts.map +1 -1
- package/dist/auditRouter.js +7 -7
- package/dist/auditRouter.js.map +1 -1
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +36 -6
- package/dist/auditRunner.js.map +1 -1
- package/dist/cli.js +23 -17
- package/dist/cli.js.map +1 -1
- package/dist/codeIndexDB.d.ts +1 -1
- package/dist/codeIndexDB.d.ts.map +1 -1
- package/dist/codeIndexDB.js +148 -18
- package/dist/codeIndexDB.js.map +1 -1
- package/dist/componentScanner.d.ts.map +1 -1
- package/dist/componentScanner.js +89 -28
- package/dist/componentScanner.js.map +1 -1
- package/dist/config/configLoader.js +1 -1
- package/dist/config/configLoader.js.map +1 -1
- package/dist/config/defaults.js +3 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/conventions/conventionMiner.d.ts.map +1 -1
- package/dist/conventions/conventionMiner.js +3 -10
- package/dist/conventions/conventionMiner.js.map +1 -1
- package/dist/daemon/core.d.ts.map +1 -1
- package/dist/daemon/core.js +33 -38
- package/dist/daemon/core.js.map +1 -1
- package/dist/daemon/lspServer.js +1 -1
- package/dist/daemon/lspServer.js.map +1 -1
- package/dist/daemon/main.d.ts.map +1 -1
- package/dist/daemon/main.js +14 -4
- package/dist/daemon/main.js.map +1 -1
- package/dist/enforcement/gate.js +2 -2
- package/dist/functionScanner.d.ts.map +1 -1
- package/dist/functionScanner.js +47 -42
- package/dist/functionScanner.js.map +1 -1
- package/dist/graph/importClassification.d.ts +76 -0
- package/dist/graph/importClassification.d.ts.map +1 -0
- package/dist/graph/importClassification.js +221 -0
- package/dist/graph/importClassification.js.map +1 -0
- package/dist/graph/importGraph.d.ts +1 -0
- package/dist/graph/importGraph.d.ts.map +1 -1
- package/dist/graph/importGraph.js +1 -1
- package/dist/graph/importGraph.js.map +1 -1
- package/dist/hooks/codex.d.ts.map +1 -1
- package/dist/hooks/codex.js +1 -1
- package/dist/hooks/codex.js.map +1 -1
- package/dist/hooks/core.d.ts +1 -1
- package/dist/hooks/core.d.ts.map +1 -1
- package/dist/hooks/core.js +4 -4
- package/dist/hooks/core.js.map +1 -1
- package/dist/hooks/cursor.d.ts.map +1 -1
- package/dist/hooks/cursor.js +2 -2
- package/dist/hooks/cursor.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installer.d.ts +20 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +58 -0
- package/dist/installer.js.map +1 -1
- package/dist/invariants/invariant-rules.schema.json +1 -1
- package/dist/invariants/ruleValidator.js +1 -1
- package/dist/invariants/ruleValidator.js.map +1 -1
- package/dist/invariants/types.d.ts +1 -1
- package/dist/invariants/types.d.ts.map +1 -1
- package/dist/languages/LanguageOrchestrator.d.ts +3 -2
- package/dist/languages/LanguageOrchestrator.d.ts.map +1 -1
- package/dist/languages/LanguageOrchestrator.js +1 -1
- package/dist/languages/LanguageOrchestrator.js.map +1 -1
- package/dist/languages/RuntimeManager.d.ts +20 -11
- package/dist/languages/RuntimeManager.d.ts.map +1 -1
- package/dist/languages/RuntimeManager.js +151 -51
- package/dist/languages/RuntimeManager.js.map +1 -1
- package/dist/languages/adapterBridge.d.ts +10 -0
- package/dist/languages/adapterBridge.d.ts.map +1 -1
- package/dist/languages/adapterBridge.js +30 -7
- package/dist/languages/adapterBridge.js.map +1 -1
- package/dist/languages/go/GoAdapter.d.ts +1 -19
- package/dist/languages/go/GoAdapter.d.ts.map +1 -1
- package/dist/languages/go/GoAdapter.js +33 -116
- package/dist/languages/go/GoAdapter.js.map +1 -1
- package/dist/languages/go/analyzer +0 -0
- package/dist/languages/go/analyzer-src/analyzer.go +8 -8
- package/dist/languages/go/analyzer-src/solid.go +5 -5
- package/dist/languages/goBinary.d.ts +46 -0
- package/dist/languages/goBinary.d.ts.map +1 -0
- package/dist/languages/goBinary.js +169 -0
- package/dist/languages/goBinary.js.map +1 -0
- package/dist/languages/tree-sitter/TreeSitterCssAdapter.d.ts +1 -28
- package/dist/languages/tree-sitter/TreeSitterCssAdapter.d.ts.map +1 -1
- package/dist/languages/tree-sitter/TreeSitterCssAdapter.js +3 -42
- package/dist/languages/tree-sitter/TreeSitterCssAdapter.js.map +1 -1
- package/dist/languages/tree-sitter/converter.d.ts.map +1 -1
- package/dist/languages/tree-sitter/converter.js +2 -1
- package/dist/languages/tree-sitter/converter.js.map +1 -1
- package/dist/languages/tree-sitter/rawNode.d.ts +31 -0
- package/dist/languages/tree-sitter/rawNode.d.ts.map +1 -0
- package/dist/languages/tree-sitter/rawNode.js +38 -0
- package/dist/languages/tree-sitter/rawNode.js.map +1 -0
- package/dist/languages/types.d.ts +0 -21
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts +1 -32
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +69 -203
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -1
- package/dist/ledger.d.ts +3 -0
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +45 -9
- package/dist/ledger.js.map +1 -1
- package/dist/mcp-tools/projectTasks.js +2 -2
- package/dist/mcp-tools/projectTasks.js.map +1 -1
- package/dist/mcp-tools/workflowGuide.js +3 -3
- package/dist/mcp-tools/workflowGuide.js.map +1 -1
- package/dist/mcp-tools-shared.js +13 -13
- package/dist/mcp-tools-shared.js.map +1 -1
- package/dist/mcp-ui-simple.js +7 -7
- package/dist/mcp-ui-simple.js.map +1 -1
- package/dist/mcp.js +14 -14
- package/dist/mcp.js.map +1 -1
- package/dist/mcpAuditJobs.js +7 -7
- package/dist/mcpAuditJobs.js.map +1 -1
- package/dist/mcpAutoIndex.js +1 -1
- package/dist/mcpAutoIndex.js.map +1 -1
- package/dist/nextFile.d.ts +2 -2
- package/dist/nextFile.d.ts.map +1 -1
- package/dist/nextFile.js +19 -5
- package/dist/nextFile.js.map +1 -1
- package/dist/nextFileIncremental.d.ts +3 -2
- package/dist/nextFileIncremental.d.ts.map +1 -1
- package/dist/nextFileIncremental.js +20 -7
- package/dist/nextFileIncremental.js.map +1 -1
- package/dist/pipelineAdapters.d.ts +17 -0
- package/dist/pipelineAdapters.d.ts.map +1 -1
- package/dist/pipelineAdapters.js +279 -178
- package/dist/pipelineAdapters.js.map +1 -1
- package/dist/reporting/csvReportGenerator.js +6 -6
- package/dist/reporting/csvReportGenerator.js.map +1 -1
- package/dist/reporting/htmlReportGenerator.js +11 -11
- package/dist/reporting/htmlReportGenerator.js.map +1 -1
- package/dist/reporting/jsonReportGenerator.js +2 -2
- package/dist/reporting/jsonReportGenerator.js.map +1 -1
- package/dist/reporting/sarifReportGenerator.js +1 -1
- package/dist/reporting/sarifReportGenerator.js.map +1 -1
- package/dist/scripts/benchmarkWorkers.js +1 -1
- package/dist/scripts/benchmarkWorkers.js.map +1 -1
- package/dist/styles/cssAstExtractor.d.ts +2 -2
- package/dist/styles/cssAstExtractor.d.ts.map +1 -1
- package/dist/styles/cssAstExtractor.js +67 -111
- package/dist/styles/cssAstExtractor.js.map +1 -1
- package/dist/styles/styleIndexer.d.ts.map +1 -1
- package/dist/styles/styleIndexer.js +19 -6
- package/dist/styles/styleIndexer.js.map +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/types/crossLanguage.d.ts +1 -1
- package/dist/types/crossLanguage.d.ts.map +1 -1
- package/dist/types.d.ts +59 -19
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +6 -5
- package/dist/types.js.map +1 -1
- package/dist/utils/astParser.d.ts +1 -17
- package/dist/utils/astParser.d.ts.map +1 -1
- package/dist/utils/astParser.js +18 -60
- package/dist/utils/astParser.js.map +1 -1
- package/dist/utils/astUtils.d.ts +12 -12
- package/dist/utils/astUtils.d.ts.map +1 -1
- package/dist/utils/astUtils.js +83 -82
- package/dist/utils/astUtils.js.map +1 -1
- package/dist/utils/componentResponsibility.d.ts +8 -8
- package/dist/utils/componentResponsibility.d.ts.map +1 -1
- package/dist/utils/componentResponsibility.js +33 -38
- package/dist/utils/componentResponsibility.js.map +1 -1
- package/dist/utils/dependencyExtractor.d.ts +3 -3
- package/dist/utils/dependencyExtractor.d.ts.map +1 -1
- package/dist/utils/dependencyExtractor.js +26 -30
- package/dist/utils/dependencyExtractor.js.map +1 -1
- package/dist/utils/fileDiscovery.d.ts.map +1 -1
- package/dist/utils/fileDiscovery.js +65 -0
- package/dist/utils/fileDiscovery.js.map +1 -1
- package/dist/utils/jsDocParser.d.ts +6 -6
- package/dist/utils/jsDocParser.d.ts.map +1 -1
- package/dist/utils/jsDocParser.js +18 -21
- package/dist/utils/jsDocParser.js.map +1 -1
- package/dist/utils/reactDetection.d.ts +7 -7
- package/dist/utils/reactDetection.d.ts.map +1 -1
- package/dist/utils/reactDetection.js +42 -49
- package/dist/utils/reactDetection.js.map +1 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.d.ts.map +1 -1
- package/dist/version.generated.js +1 -1
- package/dist/version.generated.js.map +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/README.md +5 -4
- package/plugin/hooks/hooks.json +11 -0
- package/plugin/scripts/hook-common.sh +129 -26
- package/plugin/scripts/hook-warm.sh +44 -0
- package/plugin/skills/code-auditor/SKILL-RULE-KINDS.md +28 -21
- package/plugin/skills/code-auditor/SKILL.md +10 -10
- package/server.json +2 -2
|
@@ -7,42 +7,126 @@
|
|
|
7
7
|
#
|
|
8
8
|
# Two rules enforced here are the fix for "the hook died quietly" (three times:
|
|
9
9
|
# unset CLAUDE_PLUGIN_ROOT, a stale global binary, a removed CLI flag):
|
|
10
|
-
# 1. prefer
|
|
11
|
-
#
|
|
10
|
+
# 1. prefer a bundled CLI when it is shipped (npm installs) AND its version
|
|
11
|
+
# matches the manifest — nothing is trusted on presence alone, and
|
|
12
12
|
# 2. a non-zero CLI exit that is NOT a finding (2) is a broken hook and must
|
|
13
13
|
# fail loudly, never degrade to a silent no-op.
|
|
14
14
|
#
|
|
15
15
|
# The plugin cache does NOT ship a bundled CLI (dist/ is gitignored, so a
|
|
16
16
|
# marketplace install from `./plugin` has no `../dist/`), which means the
|
|
17
|
-
# fallback paths (project-local, global/PATH,
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
17
|
+
# fallback paths (project-local, global/PATH, pinned install) are the common case —
|
|
18
|
+
# but a checkout where a developer *did* build dist/ locally ships a `../dist/cli.js`
|
|
19
|
+
# that is a local, possibly stale build, not the npm-paired dist/. The two files
|
|
20
|
+
# differ in more than freshness: npm's bin-links chmod the packaged `dist/cli.js`
|
|
21
|
+
# to `-rwxr-xr-x` at install, while local `tsc` output stays `-rw-r--r--`, so a
|
|
22
|
+
# marketplace checkout's sibling can be both stale AND non-executable — a file the
|
|
23
|
+
# old presence-only check would have trusted and then failed to run. Resolution is
|
|
24
|
+
# version-aware: EVERY candidate — the bundled sibling included — is used only
|
|
25
|
+
# when its `--version` matches the manifest, otherwise it is warned about and
|
|
26
|
+
# skipped, so a mismatched binary falls through to the pinned install instead
|
|
27
|
+
# of hard-failing. `assert_compatible` remains the final loud backstop on whatever
|
|
28
|
+
# resolve_code_audit returns. Together they stop the third quiet failure: a stale
|
|
29
|
+
# binary silently driving a newer plugin.
|
|
21
30
|
#
|
|
22
31
|
# The sourcing hook runs with `set -euo pipefail`.
|
|
23
32
|
|
|
24
33
|
# resolve_code_audit — emit the CLI invocation to use.
|
|
25
34
|
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
35
|
+
# Resolution is version-aware: EVERY candidate — bundled sibling, project-local,
|
|
36
|
+
# global — is used only when its `--version` matches this plugin's manifest
|
|
37
|
+
# version. A stale candidate is warned about and skipped, so a mismatched binary
|
|
38
|
+
# no longer turns the hook into a hard failure; the pinned install below resolves
|
|
39
|
+
# the correct CLI on its own (and warn_stale tells the user to update so the fast
|
|
40
|
+
# path comes back).
|
|
41
|
+
#
|
|
42
|
+
# 1. The plugin's bundled CLI (`${CLAUDE_PLUGIN_ROOT}/../dist/cli.js` ships in the
|
|
43
|
+
# same npm package, so it usually matches) — but a marketplace checkout has no
|
|
44
|
+
# npm-paired dist/, and a locally built one can be stale, so it is
|
|
45
|
+
# version-checked like everything else.
|
|
46
|
+
# 2. Project-local install (consumer project's own node_modules) — if compatible.
|
|
47
|
+
# 3. Global install / PATH — if compatible.
|
|
48
|
+
# 4. Pinned install, exact manifest version — never a range — the guaranteed-
|
|
49
|
+
# correct fallback when nothing compatible is installed. The package is
|
|
50
|
+
# installed to a deterministic dir and its bin invoked by absolute path; npx is
|
|
51
|
+
# deliberately NOT used for execution (see resolve_pinned_bin).
|
|
32
52
|
resolve_code_audit() {
|
|
53
|
+
local candidate
|
|
33
54
|
if [ -n "${CLAUDE_PLUGIN_ROOT:-}" ] && [ -f "${CLAUDE_PLUGIN_ROOT}/../dist/cli.js" ]; then
|
|
34
|
-
|
|
35
|
-
|
|
55
|
+
candidate="${CLAUDE_PLUGIN_ROOT}/../dist/cli.js"
|
|
56
|
+
if cli_is_compatible "${candidate}"; then
|
|
57
|
+
echo "${candidate}"
|
|
58
|
+
return
|
|
59
|
+
fi
|
|
60
|
+
warn_stale "${candidate}"
|
|
36
61
|
fi
|
|
37
62
|
if [ -n "${CLAUDE_PROJECT_DIR:-}" ] && [ -x "${CLAUDE_PROJECT_DIR}/node_modules/.bin/code-audit" ]; then
|
|
38
|
-
|
|
39
|
-
|
|
63
|
+
candidate="${CLAUDE_PROJECT_DIR}/node_modules/.bin/code-audit"
|
|
64
|
+
if cli_is_compatible "${candidate}"; then
|
|
65
|
+
echo "${candidate}"
|
|
66
|
+
return
|
|
67
|
+
fi
|
|
68
|
+
warn_stale "${candidate}"
|
|
40
69
|
fi
|
|
41
70
|
if command -v code-audit &>/dev/null; then
|
|
42
|
-
|
|
43
|
-
|
|
71
|
+
candidate="code-audit"
|
|
72
|
+
if cli_is_compatible "${candidate}"; then
|
|
73
|
+
echo "${candidate}"
|
|
74
|
+
return
|
|
75
|
+
fi
|
|
76
|
+
warn_stale "${candidate}"
|
|
77
|
+
fi
|
|
78
|
+
# Pin to the plugin's exact version, not a range: `@^3.0.0` could resolve a
|
|
79
|
+
# cached older CLI and silently drive this plugin with the wrong analyzer code.
|
|
80
|
+
local pv bin
|
|
81
|
+
pv="$(plugin_version)"
|
|
82
|
+
if [ -n "${pv}" ]; then
|
|
83
|
+
if bin="$(resolve_pinned_bin)"; then
|
|
84
|
+
echo "${bin}"
|
|
85
|
+
else
|
|
86
|
+
# Install failed (offline, registry error, npm missing). Emit the npx form
|
|
87
|
+
# as a last-ditch command so the hook still has something to run;
|
|
88
|
+
# assert_compatible rejects it loudly if it cannot be verified — the same
|
|
89
|
+
# treatment as the unreadable-manifest case below.
|
|
90
|
+
echo "npx -y -p code-auditor-mcp@${pv} code-audit"
|
|
91
|
+
fi
|
|
92
|
+
else
|
|
93
|
+
# Manifest unreadable — assert_compatible will reject whatever this fetches,
|
|
94
|
+
# so `@latest` is only a last-ditch command that never survives the pin.
|
|
95
|
+
echo "npx -y -p code-auditor-mcp@latest code-audit"
|
|
44
96
|
fi
|
|
45
|
-
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# pin_dir — the deterministic directory the pinned CLI is installed into. The
|
|
100
|
+
# version is part of the path so a plugin update installs a fresh copy instead of
|
|
101
|
+
# reusing (and possibly mis-matching) the previous version's install.
|
|
102
|
+
pin_dir() {
|
|
103
|
+
printf '%s' "${XDG_CACHE_HOME:-$HOME/.cache}/code-auditor/cli/$(plugin_version)"
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
# resolve_pinned_bin — ensure the pinned package is installed to pin_dir and echo
|
|
107
|
+
# the absolute path to its bin. Silent: prints only the path on success, nothing
|
|
108
|
+
# on failure (return 1).
|
|
109
|
+
#
|
|
110
|
+
# Installing (not `npx -p <pkg>@<ver> <bin>`) is the whole point. npx's `-p` puts
|
|
111
|
+
# the package's bin on PATH and runs the *name*, so a same-named binary earlier in
|
|
112
|
+
# PATH — a global shim, or a volta shim — shadows the pin, and the "fallback"
|
|
113
|
+
# silently routes back to the stale global it was meant to replace. Installing to
|
|
114
|
+
# a known dir and invoking `node_modules/.bin/code-audit` by absolute path removes
|
|
115
|
+
# PATH from the equation entirely.
|
|
116
|
+
resolve_pinned_bin() {
|
|
117
|
+
local pv dir bin
|
|
118
|
+
pv="$(plugin_version)"
|
|
119
|
+
[ -n "$pv" ] || return 1
|
|
120
|
+
dir="$(pin_dir)"
|
|
121
|
+
bin="${dir}/node_modules/.bin/code-audit"
|
|
122
|
+
if [ ! -x "$bin" ]; then
|
|
123
|
+
mkdir -p "$dir" || return 1
|
|
124
|
+
# --ignore-scripts is safe here (the CLI uses node:sqlite, not better-sqlite3,
|
|
125
|
+
# and ships prebuilt binaries) and avoids any install-script work.
|
|
126
|
+
npm install --prefer-offline --prefix "$dir" "code-auditor-mcp@${pv}" \
|
|
127
|
+
--no-audit --no-fund --ignore-scripts --silent >/dev/null 2>&1 || return 1
|
|
128
|
+
fi
|
|
129
|
+
echo "$bin"
|
|
46
130
|
}
|
|
47
131
|
|
|
48
132
|
# plugin_version — the version this plugin declares in its manifest, or ''.
|
|
@@ -60,21 +144,40 @@ semver_of() {
|
|
|
60
144
|
printf '%s' "$1" | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?' | head -n 1 || true
|
|
61
145
|
}
|
|
62
146
|
|
|
147
|
+
# cli_is_compatible <cmd> — silent; 0 when `<cmd> --version` reports this plugin's
|
|
148
|
+
# exact version, non-zero otherwise (mismatch or undetermined). Resolution uses
|
|
149
|
+
# this to decide fall-through; assert_compatible remains the loud backstop.
|
|
150
|
+
cli_is_compatible() {
|
|
151
|
+
local cmd="$1" pv cv pv_sem cv_sem
|
|
152
|
+
pv="$(plugin_version)"
|
|
153
|
+
cv="$($cmd --version 2>/dev/null || true)"
|
|
154
|
+
pv_sem="$(semver_of "${pv}")"
|
|
155
|
+
cv_sem="$(semver_of "${cv}")"
|
|
156
|
+
[ -n "${pv_sem}" ] && [ -n "${cv_sem}" ] && [ "${pv_sem}" = "${cv_sem}" ]
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# warn_stale <cmd> — one stderr line naming a stale installed CLI, so the user
|
|
160
|
+
# knows why the hook is paying the pinned install and how to restore the fast path.
|
|
161
|
+
warn_stale() {
|
|
162
|
+
local cmd="$1" cv pv
|
|
163
|
+
pv="$(semver_of "$(plugin_version)")"
|
|
164
|
+
cv="$(semver_of "$($cmd --version 2>/dev/null || true)")"
|
|
165
|
+
echo "[code-auditor] warn: ${cmd} is ${cv:-unidentified} but this plugin needs ${pv:-its version} — using the pinned install instead; update the install to restore the fast path" >&2
|
|
166
|
+
}
|
|
167
|
+
|
|
63
168
|
# assert_compatible <bin> — pin the plugin to a compatible CLI.
|
|
64
169
|
#
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
170
|
+
# Every candidate can drift — the bundled sibling in a marketplace checkout, a
|
|
171
|
+
# stale global, a project-local pin, or a stale pinned install — and a 3.4.0
|
|
172
|
+
# plugin silently driving a 3.5.0 CLI is exactly the failure this guards. No
|
|
173
|
+
# candidate is trusted on presence alone: `resolve_code_audit` version-checks up
|
|
174
|
+
# front, and this is the loud backstop that re-checks whatever actually resolves.
|
|
69
175
|
#
|
|
70
176
|
# The comparison is semver-vs-semver (the CLI's real `--version`, not its full
|
|
71
177
|
# banner), and it fails loudly on a mismatch OR when either version cannot be
|
|
72
178
|
# determined — an unidentified binary is never trusted.
|
|
73
179
|
assert_compatible() {
|
|
74
180
|
local bin="$1" pv cv pv_sem cv_sem
|
|
75
|
-
case "${bin}" in
|
|
76
|
-
"${CLAUDE_PLUGIN_ROOT}/../dist/cli.js") return 0 ;; # pinned by construction
|
|
77
|
-
esac
|
|
78
181
|
pv="$(plugin_version)"
|
|
79
182
|
cv="$($bin --version 2>/dev/null || true)"
|
|
80
183
|
pv_sem="$(semver_of "${pv}")"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# code-auditor SessionStart hook — warm the pinned CLI install before the first edit.
|
|
3
|
+
#
|
|
4
|
+
# A marketplace install has no lifecycle step, so the pinned fallback's cold fetch
|
|
5
|
+
# (~5.7s download of the package's native binaries) would otherwise land on the
|
|
6
|
+
# first Write/Edit after install — the kind of apparent hang people disable hooks
|
|
7
|
+
# over. This hook installs the pinned CLI at session start, before any edit.
|
|
8
|
+
#
|
|
9
|
+
# Deliberately non-blocking and silent:
|
|
10
|
+
# - the install is backgrounded (nohup + &) and this script returns immediately,
|
|
11
|
+
# so it never delays session start;
|
|
12
|
+
# - every failure (offline, npm missing, unreadable manifest) is a quiet no-op —
|
|
13
|
+
# a warm-the-cache nicety must never complain or fail the session.
|
|
14
|
+
# `--prefer-offline` makes a warm npm cache a pure cache hit (no registry metadata
|
|
15
|
+
# re-check on every launch) while still fetching on a cold cache. When the CLI is
|
|
16
|
+
# already installed at its deterministic dir, the script exits without touching npm
|
|
17
|
+
# at all — a warm session must not re-check on every launch.
|
|
18
|
+
set -uo pipefail
|
|
19
|
+
|
|
20
|
+
# Belt-and-suspenders: the hooks.json command already guards an unset
|
|
21
|
+
# CLAUDE_PLUGIN_ROOT, but keep the warm a no-op if it is somehow absent here.
|
|
22
|
+
[ -n "${CLAUDE_PLUGIN_ROOT:-}" ] || exit 0
|
|
23
|
+
|
|
24
|
+
# Shared version lookup (plugin_version / semver_of / pin_dir).
|
|
25
|
+
. "${CLAUDE_PLUGIN_ROOT}/scripts/hook-common.sh"
|
|
26
|
+
|
|
27
|
+
# Nothing safe to warm if the manifest version can't be read: warming @latest
|
|
28
|
+
# could pin a different version than resolve_code_audit's fallback would fetch.
|
|
29
|
+
pv="$(plugin_version)"
|
|
30
|
+
[ -n "${pv}" ] || exit 0
|
|
31
|
+
|
|
32
|
+
dir="$(pin_dir)"
|
|
33
|
+
bin="${dir}/node_modules/.bin/code-audit"
|
|
34
|
+
|
|
35
|
+
# Already installed — nothing to warm. Re-running npm install here would re-check
|
|
36
|
+
# the registry on every session, which is exactly the cost this hook exists to avoid.
|
|
37
|
+
[ -x "${bin}" ] && exit 0
|
|
38
|
+
|
|
39
|
+
# Background the exact install the hook's last-resort path runs. Output to
|
|
40
|
+
# /dev/null (silent), stdin from /dev/null (don't hold the hook's stdin open),
|
|
41
|
+
# nohup so the install survives this hook's exit.
|
|
42
|
+
nohup npm install --prefer-offline --prefix "${dir}" "code-auditor-mcp@${pv}" \
|
|
43
|
+
--no-audit --no-fund --ignore-scripts --silent >/dev/null 2>&1 </dev/null &
|
|
44
|
+
exit 0
|
|
@@ -103,7 +103,7 @@ Exported symbols in files matching the `path` glob must match the `exports` rege
|
|
|
103
103
|
{
|
|
104
104
|
"id": "constants-upper",
|
|
105
105
|
"kind": "naming",
|
|
106
|
-
"severity": "
|
|
106
|
+
"severity": "advisory",
|
|
107
107
|
"path": "src/**/constants.ts",
|
|
108
108
|
"exports": "^[A-Z][A-Z0-9_]*$",
|
|
109
109
|
"message": "Exported constants should use UPPER_SNAKE_CASE."
|
|
@@ -176,35 +176,42 @@ Require designated CSS properties to reference a design token instead of a raw v
|
|
|
176
176
|
|
|
177
177
|
## Severity Levels
|
|
178
178
|
|
|
179
|
-
Severity is urgency, not permission. There are three levels
|
|
180
|
-
|
|
179
|
+
Severity is urgency, not permission. There are three levels, and the axis is
|
|
180
|
+
*how fast a reading bites you*:
|
|
181
181
|
|
|
182
182
|
| Severity | What it means |
|
|
183
183
|
|----------|---------------|
|
|
184
|
-
| `critical` |
|
|
185
|
-
| `severe` |
|
|
186
|
-
| `
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
>
|
|
196
|
-
>
|
|
197
|
-
>
|
|
198
|
-
>
|
|
199
|
-
>
|
|
200
|
-
>
|
|
184
|
+
| `critical` | Already wrong in production, or will fail when this code runs |
|
|
185
|
+
| `severe` | A real defect that has not bitten yet |
|
|
186
|
+
| `advisory` | Correct, but it does not match a convention |
|
|
187
|
+
|
|
188
|
+
`critical` and `severe` are defects; `advisory` is a convention reading — the
|
|
189
|
+
code works, but it deviates from a documented norm (docs, style, naming).
|
|
190
|
+
Every severity blocks by default. The edit hook gates on any finding from any
|
|
191
|
+
rule — there is no non-blocking tier and no per-rule opt-in. An `advisory`
|
|
192
|
+
finding blocks the edit exactly like a `critical` one; urgency only sets the
|
|
193
|
+
order you fix things, never whether they gate.
|
|
194
|
+
|
|
195
|
+
> **Severity ranks urgency, never whether a finding is real.** `advisory` is
|
|
196
|
+
> not a "noise" tier — a convention reading still blocks the edit until it is
|
|
197
|
+
> resolved or the rule that produces it is edited in `.codeauditor.json`. There
|
|
198
|
+
> is no "waive" — a finding leaves the queue only by being resolved or by
|
|
199
|
+
> changing the rule that fires it. The `next-file` queue orders work worst-first;
|
|
200
|
+
> that ordering is triage, not permission — a finding that surfaces later in the
|
|
201
|
+
> queue still gates. Documentation findings ship at `advisory`: missing JSDoc is
|
|
202
|
+
> a maintainability convention, not a runtime defect — but it still blocks.
|
|
203
|
+
|
|
204
|
+
A fourth channel, **diagnostic**, sits outside the severity ladder. It is not a
|
|
205
|
+
severity tier: it carries tool-failure and coverage notices (`engine-error`,
|
|
206
|
+
`config-error`, `undefined-class-disabled`) that are surfaced regardless of
|
|
207
|
+
`--fail-on` and never counted as findings.
|
|
201
208
|
|
|
202
209
|
## Validation
|
|
203
210
|
|
|
204
211
|
Rules are validated against `invariant-rules.schema.json` on startup. Common errors:
|
|
205
212
|
|
|
206
213
|
- **Missing required field**: each kind has required fields (e.g., `import-ban` requires `module`)
|
|
207
|
-
- **Invalid severity**: must be one of `critical`, `severe`, `
|
|
214
|
+
- **Invalid severity**: must be one of `critical`, `severe`, `advisory`
|
|
208
215
|
- **Invalid kind**: must be one of the seven kinds above
|
|
209
216
|
- **Both allowFrom and denyFrom**: `call-constraint` requires exactly one
|
|
210
217
|
- **Empty pattern**: `ast-pattern` requires a non-empty `pattern` string
|
|
@@ -5,7 +5,7 @@ description: Audit code quality, search the codebase semantically, enforce invar
|
|
|
5
5
|
|
|
6
6
|
# Code Auditor Skill
|
|
7
7
|
|
|
8
|
-
> **Version
|
|
8
|
+
> **Version 4.0.0** • Run `code-audit --version` to check your installed version.
|
|
9
9
|
> If versions differ, the CLI is authoritative — use `code-audit <command> --help` to see what your install actually supports.
|
|
10
10
|
|
|
11
11
|
You have the `code-audit` CLI available. It indexes every function, component, and struct in the codebase for semantic search and invariant enforcement. Use these commands instead of raw grep/find whenever possible.
|
|
@@ -16,7 +16,7 @@ You have the `code-audit` CLI available. It indexes every function, component, a
|
|
|
16
16
|
|
|
17
17
|
- **Reading** — the human-facing name for one rule observation. The machine contract calls the same thing a **violation** (a "finding" in the JSON). The audit *takes* readings; it does not issue verdicts.
|
|
18
18
|
- **Coverage panel** — the report leads with what was measured (which rules fired, which were clean, which were not applicable), so a zero-reading run is not mistaken for a clean tree.
|
|
19
|
-
- **Triage** — severity is urgency, not permission. Three levels,
|
|
19
|
+
- **Triage** — severity is urgency, not permission. Three levels, and the axis is how fast a reading bites you: **critical** (already wrong in production, or will fail when this code runs), **severe** (a real defect that has not bitten yet), **advisory** (correct, but it does not match a convention). `critical` and `severe` are defects; `advisory` is a convention reading. Every reading blocks the edit gate by default. Queue order (`critical` → `severe` → `advisory`) is the order to act, not a license to skip.
|
|
20
20
|
|
|
21
21
|
## When to use which command
|
|
22
22
|
|
|
@@ -51,9 +51,9 @@ code-audit changed --json # Diff-scoped audit (hook c
|
|
|
51
51
|
|
|
52
52
|
Use `code-audit changed` after edits to confirm you haven't introduced violations. If the hook is active it already runs `code-audit changed` automatically on Write/Edit — pay attention to its output.
|
|
53
53
|
|
|
54
|
-
**Every reading is a measurement, not a verdict.** The audit is a diagnostic instrument: it reports what it measured (the coverage panel) and takes one reading per rule violation. Work readings in urgency order — critical first, then severe, then
|
|
54
|
+
**Every reading is a measurement, not a verdict.** The audit is a diagnostic instrument: it reports what it measured (the coverage panel) and takes one reading per rule violation. Work readings in urgency order — critical first, then severe, then advisory — and resolve them all. Severity is urgency, the order to act, never a judgment on whether a reading is real; there is no "noise" tier — an advisory reading still blocks. Documentation readings (missing JSDoc) ship at advisory: maintainability conventions, not stylistic niceties, and still gating. If you choose not to resolve one, record why before moving on — never silently dismiss it.
|
|
55
55
|
|
|
56
|
-
Expected output: JSON violation list (with `--json`) or colored terminal summary. The full `audit` command exits non-zero when violations at or above `--fail-on` severity exist. Every severity blocks: `critical`, `severe`, and `
|
|
56
|
+
Expected output: JSON violation list (with `--json`) or colored terminal summary. The full `audit` command exits non-zero when violations at or above `--fail-on` severity exist. Every severity blocks: `critical`, `severe`, and `advisory` are all gating. The `changed` hook blocks on any violation from any rule — there is no non-blocking tier — and enforcement is not diff-scoped (a pre-existing violation in the audited file blocks exactly like a new one).
|
|
57
57
|
|
|
58
58
|
### `code-audit next-file` — fix violations one file at a time
|
|
59
59
|
|
|
@@ -62,7 +62,7 @@ code-audit next-file --path . # Highest-priority file + all its readings
|
|
|
62
62
|
code-audit next-file --path . --json # Machine-readable
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
This is the refactoring loop. `next-file` audits the project and returns the single highest-priority file — ranked by highest-severity reading, then total reading count — with every reading on it, ordered critical → severe →
|
|
65
|
+
This is the refactoring loop. `next-file` audits the project and returns the single highest-priority file — ranked by highest-severity reading, then total reading count — with every reading on it, ordered critical → severe → advisory. Fix that file, then run it again: a still-broken file comes back, otherwise the next-worst file surfaces. `{done:true}` means the tree is clean.
|
|
66
66
|
|
|
67
67
|
There is **no skip or decline affordance** in `next-file`. A reading leaves the queue only by being fixed, by editing the rule that produces it in `.codeauditor.json` (your rules editor), or — if it is a genuine false positive — by dismissing that one instance with a written reason (`code-audit dismiss`, below). If a rule keeps firing on something you judge correct, change the rule — never work around it.
|
|
68
68
|
|
|
@@ -117,7 +117,7 @@ Path profiles are an ordered array — files matching multiple profiles merge ov
|
|
|
117
117
|
|
|
118
118
|
A **built-in** `scripts-and-tests` profile ships with every install — it excludes `scripts/**`, `tests/**`, `__tests__/**`, `fixtures/**`, and `*.test.*`/`*.spec.*` files from the gate. Disable it with `"builtin": false` in `.codeauditor.json`.
|
|
119
119
|
|
|
120
|
-
Invariant violations are **immune** to path profile gate exclusion — invariants enforce declared laws and block on the same gate as every other rule (all of `critical`, `severe`, and `
|
|
120
|
+
Invariant violations are **immune** to path profile gate exclusion — invariants enforce declared laws and block on the same gate as every other rule (all of `critical`, `severe`, and `advisory`).
|
|
121
121
|
|
|
122
122
|
### `code-audit index` — refresh the index after structural changes
|
|
123
123
|
|
|
@@ -145,7 +145,7 @@ Creates a `.codeauditor.json` configuration file with invariant rules for your p
|
|
|
145
145
|
|
|
146
146
|
### `code-audit conventions` — mine and propose rules
|
|
147
147
|
|
|
148
|
-
Code Auditor learns your codebase's unwritten conventions from the function index and flags deviations at
|
|
148
|
+
Code Auditor learns your codebase's unwritten conventions from the function index and flags deviations at advisory severity. Use these to discover norms an unfamiliar agent would otherwise break:
|
|
149
149
|
|
|
150
150
|
```bash
|
|
151
151
|
code-audit conventions list # See what conventions were mined
|
|
@@ -167,7 +167,7 @@ code-audit conventions propose --json # JSON proposal array
|
|
|
167
167
|
|
|
168
168
|
**Usage:** Run a full audit or `code-audit index sync` to mine conventions from the codebase index. Then `code-audit conventions list` to see what was found, and `code-audit conventions propose` to get the rules. Paste the proposals into the `rules` array in `.codeauditor.json`.
|
|
169
169
|
|
|
170
|
-
Convention readings ship at `
|
|
170
|
+
Convention readings ship at `advisory` severity by default. Severity is urgency — how fast a reading bites, not whether it matters. `advisory` is a convention reading, not a defect, but it still blocks the edit gate by default — resolve it or edit the rule, never ignore it.
|
|
171
171
|
|
|
172
172
|
### `code-audit hotspots` — identify churn-prone code
|
|
173
173
|
|
|
@@ -209,9 +209,9 @@ When an edit hook blocks your edit with a violation message:
|
|
|
209
209
|
1. **Read the violation** — it includes the invariant rule's `message` field explaining *why* the edit was blocked
|
|
210
210
|
2. **Fix the violation** — change your approach to comply with the invariant
|
|
211
211
|
3. **Do NOT retry the same edit** — the hook will block it again
|
|
212
|
-
4. The hook runs `code-audit changed`, and its gate blocks on every violation from any rule — `critical`, `severe`, and `
|
|
212
|
+
4. The hook runs `code-audit changed`, and its gate blocks on every violation from any rule — `critical`, `severe`, and `advisory` all block; there is no non-blocking severity tier. An `advisory` reading blocks the edit exactly like a `critical` one; urgency only sets the order you fix things, never whether they gate.
|
|
213
213
|
|
|
214
|
-
The hook auto-installs the package
|
|
214
|
+
The hook auto-installs the package to a cache dir on first use — no manual npm step needed. If the hook reports `[code-auditor] code-audit could not run`, the auto-install failed (network, unsupported platform). The agent should try again; if it persists, `npm install code-auditor-mcp` is the manual fix.
|
|
215
215
|
|
|
216
216
|
## Host-specific notes
|
|
217
217
|
|
package/server.json
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
"url": "https://github.com/BenAHammond/code-auditor-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "
|
|
9
|
+
"version": "4.0.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
14
14
|
"identifier": "code-auditor-mcp",
|
|
15
|
-
"version": "
|
|
15
|
+
"version": "4.0.0",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
}
|