code-auditor-mcp 5.0.2 → 5.2.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 +184 -3
- package/README.md +24 -2
- package/configs/hhra-compat.json +12 -118
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js +11 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js +57 -52
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js.map +1 -1
- package/dist/analyzers/provenance.d.ts +9 -4
- package/dist/analyzers/provenance.d.ts.map +1 -1
- package/dist/analyzers/provenance.js +8 -25
- package/dist/analyzers/provenance.js.map +1 -1
- package/dist/analyzers/reactAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/reactAnalyzer.js +0 -5
- package/dist/analyzers/reactAnalyzer.js.map +1 -1
- package/dist/analyzers/ruleRegistry.js +4 -4
- package/dist/analyzers/ruleRegistry.js.map +1 -1
- package/dist/analyzers/ruleTiming.d.ts +1 -1
- package/dist/analyzers/ruleTiming.js +2 -2
- package/dist/analyzers/ruleTiming.js.map +1 -1
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.js +22 -26
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +32 -15
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +189 -115
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +0 -2
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +0 -5
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts +2 -10
- package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalStylesAnalyzer.js +7 -49
- package/dist/analyzers/universal/UniversalStylesAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/schema/config.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/config.js +0 -2
- package/dist/analyzers/universal/schema/config.js.map +1 -1
- package/dist/analyzers/universal/schema/types.d.ts +0 -2
- package/dist/analyzers/universal/schema/types.d.ts.map +1 -1
- package/dist/analyzers/vendorSurfaces.d.ts +126 -0
- package/dist/analyzers/vendorSurfaces.d.ts.map +1 -0
- package/dist/analyzers/vendorSurfaces.js +580 -0
- package/dist/analyzers/vendorSurfaces.js.map +1 -0
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +136 -142
- package/dist/auditRunner.js.map +1 -1
- package/dist/churn/churnExtractor.d.ts +0 -1
- package/dist/churn/churnExtractor.d.ts.map +1 -1
- package/dist/churn/churnExtractor.js +2 -4
- package/dist/churn/churnExtractor.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +195 -26
- package/dist/cli.js.map +1 -1
- package/dist/codeIndex/migrations.d.ts.map +1 -1
- package/dist/codeIndex/migrations.js +4 -3
- package/dist/codeIndex/migrations.js.map +1 -1
- package/dist/codeIndexDB.d.ts +11 -2
- package/dist/codeIndexDB.d.ts.map +1 -1
- package/dist/codeIndexDB.js +27 -2
- package/dist/codeIndexDB.js.map +1 -1
- package/dist/config/configLoader.d.ts +60 -7
- package/dist/config/configLoader.d.ts.map +1 -1
- package/dist/config/configLoader.js +252 -60
- package/dist/config/configLoader.js.map +1 -1
- package/dist/config/defaults.d.ts +77 -18
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +105 -43
- package/dist/config/defaults.js.map +1 -1
- package/dist/constants.d.ts +2 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -1
- package/dist/daemon/main.d.ts +0 -1
- package/dist/daemon/main.d.ts.map +1 -1
- package/dist/daemon/main.js +11 -4
- package/dist/daemon/main.js.map +1 -1
- package/dist/dataPaths.d.ts +17 -11
- package/dist/dataPaths.d.ts.map +1 -1
- package/dist/dataPaths.js +51 -16
- package/dist/dataPaths.js.map +1 -1
- package/dist/hookLog.d.ts +54 -0
- package/dist/hookLog.d.ts.map +1 -0
- package/dist/hookLog.js +105 -0
- package/dist/hookLog.js.map +1 -0
- package/dist/hookLogPath.generated.d.ts +3 -0
- package/dist/hookLogPath.generated.d.ts.map +1 -0
- package/dist/hookLogPath.generated.js +8 -0
- package/dist/hookLogPath.generated.js.map +1 -0
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -7
- package/dist/index.js.map +1 -1
- package/dist/installConfig.d.ts +15 -2
- package/dist/installConfig.d.ts.map +1 -1
- package/dist/installConfig.js +17 -2
- package/dist/installConfig.js.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +18 -3
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -1
- package/dist/mcp-tools/workflowGuide.js +8 -8
- package/dist/mcp-tools/workflowGuide.js.map +1 -1
- package/dist/mcp-tools-shared.d.ts.map +1 -1
- package/dist/mcp-tools-shared.js +5 -2
- package/dist/mcp-tools-shared.js.map +1 -1
- package/dist/mcp-ui-simple.d.ts +5 -0
- package/dist/mcp-ui-simple.d.ts.map +1 -1
- package/dist/mcp-ui-simple.js +9 -2
- package/dist/mcp-ui-simple.js.map +1 -1
- package/dist/mcp.d.ts +0 -1
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +36 -33
- package/dist/mcp.js.map +1 -1
- package/dist/mcpAuditJobs.d.ts +10 -0
- package/dist/mcpAuditJobs.d.ts.map +1 -1
- package/dist/mcpAuditJobs.js +10 -1
- package/dist/mcpAuditJobs.js.map +1 -1
- package/dist/mcpAutoIndex.d.ts.map +1 -1
- package/dist/mcpAutoIndex.js +2 -1
- package/dist/mcpAutoIndex.js.map +1 -1
- package/dist/phase/colorMath.d.ts +18 -5
- package/dist/phase/colorMath.d.ts.map +1 -1
- package/dist/phase/colorMath.js +88 -5
- package/dist/phase/colorMath.js.map +1 -1
- package/dist/phase/dataAccessCallsCandidates.js +1 -1
- package/dist/phase/dataAccessCallsCandidates.js.map +1 -1
- package/dist/phase/goFunctionAnalysis.d.ts +2 -2
- package/dist/phase/goFunctionAnalysis.js +2 -2
- package/dist/phase/goFunctions.d.ts +2 -2
- package/dist/phase/goFunctions.js +2 -2
- package/dist/phase/goImports.d.ts +2 -2
- package/dist/phase/goImports.js +2 -2
- package/dist/phase/goSwitches.d.ts +2 -2
- package/dist/phase/goSwitches.js +2 -2
- package/dist/phase/loopQueryCandidates.js +1 -1
- package/dist/phase/loopQueryCandidates.js.map +1 -1
- package/dist/phase/phaseModel.d.ts +37 -8
- package/dist/phase/phaseModel.d.ts.map +1 -1
- package/dist/phase/phaseModel.js +33 -8
- package/dist/phase/phaseModel.js.map +1 -1
- package/dist/phase/producers.d.ts.map +1 -1
- package/dist/phase/producers.js +24 -17
- package/dist/phase/producers.js.map +1 -1
- package/dist/phase/reachability.d.ts +44 -1
- package/dist/phase/reachability.d.ts.map +1 -1
- package/dist/phase/reachability.js +79 -0
- package/dist/phase/reachability.js.map +1 -1
- package/dist/phase/rules/crossDomain.d.ts.map +1 -1
- package/dist/phase/rules/crossDomain.js +16 -6
- package/dist/phase/rules/crossDomain.js.map +1 -1
- package/dist/phase/rules/dry.d.ts.map +1 -1
- package/dist/phase/rules/dry.js +0 -1
- package/dist/phase/rules/dry.js.map +1 -1
- package/dist/phase/rules/goRules.d.ts +2 -2
- package/dist/phase/rules/goRules.js +2 -2
- package/dist/phase/rules/secrets.d.ts +22 -8
- package/dist/phase/rules/secrets.d.ts.map +1 -1
- package/dist/phase/rules/secrets.js +48 -67
- package/dist/phase/rules/secrets.js.map +1 -1
- package/dist/phase/rules/styles.d.ts +23 -9
- package/dist/phase/rules/styles.d.ts.map +1 -1
- package/dist/phase/rules/styles.js +47 -15
- package/dist/phase/rules/styles.js.map +1 -1
- package/dist/phase/rules/unreferencedModule.d.ts.map +1 -1
- package/dist/phase/rules/unreferencedModule.js +16 -5
- package/dist/phase/rules/unreferencedModule.js.map +1 -1
- package/dist/phase/runner.d.ts +16 -7
- package/dist/phase/runner.d.ts.map +1 -1
- package/dist/phase/runner.js +32 -20
- package/dist/phase/runner.js.map +1 -1
- package/dist/phase/stylesCss.d.ts.map +1 -1
- package/dist/phase/stylesCss.js +4 -0
- package/dist/phase/stylesCss.js.map +1 -1
- package/dist/phase/stylesMarkup.d.ts.map +1 -1
- package/dist/phase/stylesMarkup.js +4 -0
- package/dist/phase/stylesMarkup.js.map +1 -1
- package/dist/phase/stylesSource.d.ts.map +1 -1
- package/dist/phase/stylesSource.js +6 -0
- package/dist/phase/stylesSource.js.map +1 -1
- package/dist/phase/testProgram.d.ts +57 -0
- package/dist/phase/testProgram.d.ts.map +1 -0
- package/dist/phase/testProgram.js +244 -0
- package/dist/phase/testProgram.js.map +1 -0
- package/dist/phase/typeDeclarations.d.ts +2 -2
- package/dist/phase/typeDeclarations.js +2 -2
- package/dist/phase/types.d.ts +46 -0
- package/dist/phase/types.d.ts.map +1 -1
- package/dist/pipelineAdapters.d.ts +1 -171
- package/dist/pipelineAdapters.d.ts.map +1 -1
- package/dist/pipelineAdapters.js +47 -1281
- package/dist/pipelineAdapters.js.map +1 -1
- package/dist/reporting/csvReportGenerator.d.ts.map +1 -1
- package/dist/reporting/csvReportGenerator.js +0 -6
- package/dist/reporting/csvReportGenerator.js.map +1 -1
- package/dist/reporting/htmlReportGenerator.d.ts.map +1 -1
- package/dist/reporting/htmlReportGenerator.js +0 -4
- package/dist/reporting/htmlReportGenerator.js.map +1 -1
- package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
- package/dist/reporting/jsonReportGenerator.js +0 -1
- package/dist/reporting/jsonReportGenerator.js.map +1 -1
- package/dist/reporting/sarifReportGenerator.d.ts.map +1 -1
- package/dist/reporting/sarifReportGenerator.js +0 -7
- package/dist/reporting/sarifReportGenerator.js.map +1 -1
- package/dist/sqlite/driver.d.ts +17 -1
- package/dist/sqlite/driver.d.ts.map +1 -1
- package/dist/sqlite/driver.js +28 -5
- package/dist/sqlite/driver.js.map +1 -1
- package/dist/styles/cssInJsHarvest.d.ts +36 -0
- package/dist/styles/cssInJsHarvest.d.ts.map +1 -0
- package/dist/styles/cssInJsHarvest.js +78 -0
- package/dist/styles/cssInJsHarvest.js.map +1 -0
- package/dist/styles/definedClasses.d.ts +95 -0
- package/dist/styles/definedClasses.d.ts.map +1 -0
- package/dist/styles/definedClasses.js +129 -0
- package/dist/styles/definedClasses.js.map +1 -0
- package/dist/styles/markupStyleHarvest.d.ts +33 -0
- package/dist/styles/markupStyleHarvest.d.ts.map +1 -0
- package/dist/styles/markupStyleHarvest.js +73 -0
- package/dist/styles/markupStyleHarvest.js.map +1 -0
- package/dist/styles/styleExtractor.d.ts +37 -0
- package/dist/styles/styleExtractor.d.ts.map +1 -1
- package/dist/styles/styleExtractor.js +89 -33
- package/dist/styles/styleExtractor.js.map +1 -1
- package/dist/styles/styleIndexer.d.ts.map +1 -1
- package/dist/styles/styleIndexer.js +11 -10
- package/dist/styles/styleIndexer.js.map +1 -1
- package/dist/styles/tailwindExpander.d.ts.map +1 -1
- package/dist/styles/tailwindExpander.js +31 -10
- package/dist/styles/tailwindExpander.js.map +1 -1
- package/dist/telemetry.d.ts +67 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +100 -20
- package/dist/telemetry.js.map +1 -1
- package/dist/types/crossLanguage.d.ts +1 -0
- package/dist/types/crossLanguage.d.ts.map +1 -1
- package/dist/types.d.ts +23 -56
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -4
- package/dist/types.js.map +1 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/examples/.auditrc.example.json +7 -22
- package/examples/.auditrc.json +12 -155
- package/examples/.code-auditor.json +8 -51
- package/examples/nextjs.auditrc.json +7 -34
- package/examples/node-api.auditrc.json +6 -46
- package/examples/react.auditrc.json +8 -25
- package/examples/tolerant-solid.auditrc.json +12 -44
- package/package.json +6 -5
- package/plugin/.claude-plugin/manifest.json +10 -9
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/hooks/hooks.json +4 -4
- package/plugin/scripts/hook-audit.sh +9 -0
- package/plugin/scripts/hook-common.sh +8 -2
- package/plugin/scripts/hook-drift-check.sh +10 -1
- package/plugin/scripts/hook-log-path.sh +7 -0
- package/plugin/scripts/hook-self-audit.sh +9 -0
- package/plugin/scripts/hook-warm.sh +17 -11
- package/plugin/skills/code-auditor/SKILL.md +26 -3
- package/dist/__tests__/fixtures/spec-20/scripts/tool.d.ts +0 -6
- package/dist/__tests__/fixtures/spec-20/scripts/tool.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-20/scripts/tool.js +0 -12
- package/dist/__tests__/fixtures/spec-20/scripts/tool.js.map +0 -1
- package/dist/__tests__/fixtures/spec-20/src/demo-module.d.ts +0 -7
- package/dist/__tests__/fixtures/spec-20/src/demo-module.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-20/src/demo-module.js +0 -13
- package/dist/__tests__/fixtures/spec-20/src/demo-module.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.d.ts +0 -14
- package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.js +0 -16
- package/dist/__tests__/fixtures/spec-52/item-01-prepare-in-loop.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.d.ts +0 -15
- package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.js +0 -17
- package/dist/__tests__/fixtures/spec-52/item-02-prepare-bind-accumulate-batch.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts +0 -14
- package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js +0 -19
- package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts +0 -18
- package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js +0 -19
- package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.d.ts +0 -19
- package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.js +0 -19
- package/dist/__tests__/fixtures/spec-52/item-05-upsert-forms.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts +0 -17
- package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.js +0 -19
- package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts +0 -25
- package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.js +0 -21
- package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.d.ts +0 -15
- package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.js +0 -19
- package/dist/__tests__/fixtures/spec-52/item-08-promise-all-of-statements-in-loop.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.d.ts +0 -14
- package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.js +0 -14
- package/dist/__tests__/fixtures/spec-52/item-09-promise-all-map-of-statements-in-loop.js.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts +0 -15
- package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts.map +0 -1
- package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.js +0 -16
- package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.js.map +0 -1
- package/dist/languages/go/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-src/analyzer.go +0 -643
- package/dist/languages/go/analyzer-src/dataaccess.go +0 -388
- package/dist/languages/go/analyzer-src/go.mod +0 -3
- package/dist/languages/go/analyzer-src/indexer.go +0 -268
- package/dist/languages/go/analyzer-src/parser.go +0 -461
- package/dist/languages/go/analyzer-src/solid.go +0 -311
- package/dist/languages/go/analyzer-src/testconventions.go +0 -25
- package/dist/languages/go/analyzer-src/types.go +0 -156
- package/dist/languages/go/analyzer-windows-amd64.exe +0 -0
- package/dist/languages/go/go.mod +0 -7
- package/dist/languages/go/main.go +0 -203
- package/dist/native/ast-grep-napi.darwin-arm64.node +0 -0
- package/dist/native/ast-grep-napi.darwin-x64.node +0 -0
- package/dist/native/ast-grep-napi.linux-arm64-gnu.node +0 -0
- package/dist/native/ast-grep-napi.linux-arm64-musl.node +0 -0
- package/dist/native/ast-grep-napi.linux-x64-gnu.node +0 -0
- package/dist/native/ast-grep-napi.linux-x64-musl.node +0 -0
- package/dist/native/ast-grep-napi.win32-x64-msvc.node +0 -0
- package/dist/native-bootstrap.d.ts +0 -15
- package/dist/native-bootstrap.d.ts.map +0 -1
- package/dist/native-bootstrap.js +0 -75
- package/dist/native-bootstrap.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Code Auditor CLI - Enhanced with AI Tool Integration
|
|
4
4
|
*/
|
|
5
|
-
// MUST be first import: sets NAPI_RS_NATIVE_LIBRARY_PATH before @ast-grep/napi loads
|
|
6
|
-
import './native-bootstrap.js';
|
|
7
5
|
import { Command } from 'commander';
|
|
8
6
|
import chalk from 'chalk';
|
|
9
7
|
import { createAuditRunner } from './auditRunner.js';
|
|
8
|
+
import { readHookNotice } from './hookLog.js';
|
|
10
9
|
import { promises as fs } from 'fs';
|
|
11
10
|
import { createInterface } from 'readline';
|
|
12
11
|
import { dirname, isAbsolute, join, relative, resolve } from 'path';
|
|
13
|
-
import { PACKAGE_VERSION } from './constants.js';
|
|
12
|
+
import { PACKAGE_VERSION, DEFAULT_RULE_REQUEST_BASE_URL } from './constants.js';
|
|
14
13
|
import inquirer from 'inquirer';
|
|
15
14
|
import { CodeMapGenerator } from './services/CodeMapGenerator.js';
|
|
16
15
|
import { initParsers } from './languages/index.js';
|
|
@@ -20,13 +19,14 @@ import { getFilesProcessed, getFactsConsumed, isVisitorStatus, isReducerStatus }
|
|
|
20
19
|
import { createBaselineFromFindings, saveBaseline, loadBaseline, diffBaselines } from './baseline.js';
|
|
21
20
|
import { fingerprint, buildFingerprintInput } from './fingerprint.js';
|
|
22
21
|
import { buildDismissalEntry, upsertDismissal } from './dismissals.js';
|
|
23
|
-
import { resolveTelemetryConfig, signatureForFinding, buildTelemetryPayload, formatTelemetryPreview, sendTelemetry, languageHint } from './telemetry.js';
|
|
22
|
+
import { resolveTelemetryConfig, signatureForFinding, buildTelemetryPayload, formatTelemetryPreview, sendTelemetry, languageHint, telemetryStatus, telemetryEnable, telemetryDisable, postJson } from './telemetry.js';
|
|
24
23
|
import { getInstallId } from './installConfig.js';
|
|
25
24
|
import { computeGatingDecision } from './enforcement/gate.js';
|
|
26
25
|
import { BLOCKING_SEVERITIES, SEVERITIES } from './types.js';
|
|
27
26
|
import { rankFilesByPriority, orderFindingsWithinFile } from './nextFile.js';
|
|
28
27
|
import { runNextFile } from './nextFileIncremental.js';
|
|
29
28
|
import { describeSqliteBackend } from './sqlite/driver.js';
|
|
29
|
+
import { isRuleTimingEnabled } from './analyzers/ruleTiming.js';
|
|
30
30
|
const program = new Command();
|
|
31
31
|
// Legacy severity names that were renamed off Spec-54's "advisory" back to "high"
|
|
32
32
|
// (Spec-54's third tier rendered as "advisory", which read as optional — the very
|
|
@@ -142,17 +142,6 @@ function printAuditDiagnostics(result) {
|
|
|
142
142
|
`${covCannotFire} cannot-fire · ${unprovenSiteCount} unproven sites · ` +
|
|
143
143
|
`${heldOutByProfile} held out by profile`));
|
|
144
144
|
}
|
|
145
|
-
// ── Skipped analyzers (Spec 61) ──────────────────────────────
|
|
146
|
-
const skippedAnalyzers = (result.metadata?.diagnostics ?? []).filter((d) => d.kind === 'go-toolchain-missing' ||
|
|
147
|
-
d.kind === 'go-analyzer-wrong-arch' ||
|
|
148
|
-
d.kind === 'go-analyzer-build-failed');
|
|
149
|
-
if (skippedAnalyzers.length > 0) {
|
|
150
|
-
console.log(chalk.yellow(`── Skipped analyzers ── ${skippedAnalyzers.length}`));
|
|
151
|
-
for (const d of skippedAnalyzers) {
|
|
152
|
-
const name = d.analyzerName || 'go';
|
|
153
|
-
console.log(chalk.yellow(` ${name} [${d.kind}] — ${d.message}`));
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
145
|
// ── Ignored config keys (Spec 61 R1.4) ─────────────────────────
|
|
157
146
|
const ignoredConfigKeys = (result.metadata?.diagnostics ?? []).filter((d) => d.kind === 'config-key-rejected');
|
|
158
147
|
if (ignoredConfigKeys.length > 0) {
|
|
@@ -600,6 +589,13 @@ program
|
|
|
600
589
|
outputDirectory: options.output,
|
|
601
590
|
presets: presetIds
|
|
602
591
|
}).run();
|
|
592
|
+
// Hook-liveness notice — a top-level notice, not a per-file finding. A live
|
|
593
|
+
// "hook not running" condition means the PostToolUse hook is not enqueueing
|
|
594
|
+
// changes, so cached findings may be stale.
|
|
595
|
+
const hookNotice = readHookNotice();
|
|
596
|
+
if (hookNotice) {
|
|
597
|
+
console.log(chalk.yellow(`\n⚠️ ${hookNotice.message}`));
|
|
598
|
+
}
|
|
603
599
|
const violations = Object.values(result.analyzerResults).flatMap((r) => r.violations || []);
|
|
604
600
|
const baseline = result.metadata?.baseline;
|
|
605
601
|
printAuditDiagnostics(result);
|
|
@@ -732,7 +728,7 @@ program
|
|
|
732
728
|
// Emitted to stderr so it never corrupts --json stdout. Slowest rule first.
|
|
733
729
|
// The gate metric is CPU time (auditCpuMs), not wall clock: the budget is
|
|
734
730
|
// about a slow *rule*, and CPU time isolates that from a slow machine.
|
|
735
|
-
if (
|
|
731
|
+
if (isRuleTimingEnabled()) {
|
|
736
732
|
const ruleTiming = result.metadata?.ruleTiming;
|
|
737
733
|
const gateMs = result.metadata?.auditCpuMs;
|
|
738
734
|
const gateWallMs = result.metadata?.auditDuration;
|
|
@@ -889,7 +885,18 @@ async function emitChangedOutput(result, violations, blocking, dismissedCount, o
|
|
|
889
885
|
}
|
|
890
886
|
}
|
|
891
887
|
else {
|
|
892
|
-
|
|
888
|
+
// A bare `changed` scope that found no baseline to diff against must not
|
|
889
|
+
// report a false clean. The diagnostic names both causes (never indexed,
|
|
890
|
+
// or the index was discarded) so the agent sees "cannot determine what
|
|
891
|
+
// changed", never "nothing changed".
|
|
892
|
+
const noBaseline = (result.metadata?.diagnostics ?? []).find((d) => d.kind === 'no-baseline');
|
|
893
|
+
if (noBaseline) {
|
|
894
|
+
console.log(chalk.yellow('\n⚠ Cannot determine what changed.'));
|
|
895
|
+
console.log(chalk.yellow(noBaseline.message));
|
|
896
|
+
}
|
|
897
|
+
else {
|
|
898
|
+
console.log(chalk.green('\n✓ No readings.'));
|
|
899
|
+
}
|
|
893
900
|
}
|
|
894
901
|
}
|
|
895
902
|
}
|
|
@@ -1306,7 +1313,7 @@ program
|
|
|
1306
1313
|
.description('Dismiss one finding by fingerprint — a written reason is required')
|
|
1307
1314
|
.requiredOption('--reason <reason>', 'Why this finding is dismissed (required — a dismissal without a reason is a config error)')
|
|
1308
1315
|
.option('-p, --path <path>', OPTION_PROJECT_PATH, process.cwd())
|
|
1309
|
-
.option('--telemetry-endpoint <url>', 'Feedback service endpoint override (defaults to the opt-in endpoint recorded by the telemetry
|
|
1316
|
+
.option('--telemetry-endpoint <url>', 'Feedback service endpoint override (defaults to the opt-in endpoint recorded by the `code-audit telemetry` command)')
|
|
1310
1317
|
.option('--json', OPTION_OUTPUT_AS_JSON)
|
|
1311
1318
|
.action(async (fingerprintArg, options) => {
|
|
1312
1319
|
try {
|
|
@@ -1334,9 +1341,9 @@ program
|
|
|
1334
1341
|
const entry = buildDismissalEntry(match, reason, PACKAGE_VERSION);
|
|
1335
1342
|
const dismissals = upsertDismissal(projectRoot, entry);
|
|
1336
1343
|
// Spec 57 — opt-in telemetry. Nothing is sent unless the user opted in via
|
|
1337
|
-
// the `telemetry`
|
|
1338
|
-
// payload is printed for review before sending; any send
|
|
1339
|
-
// and never affects the dismissal or the exit code.
|
|
1344
|
+
// the `code-audit telemetry enable` command (default OFF) AND an endpoint is
|
|
1345
|
+
// configured. The payload is printed for review before sending; any send
|
|
1346
|
+
// failure is silent and never affects the dismissal or the exit code.
|
|
1340
1347
|
const telemetry = resolveTelemetryConfig({ endpoint: options.telemetryEndpoint });
|
|
1341
1348
|
if (telemetry.enabled && telemetry.endpoint) {
|
|
1342
1349
|
const signature = signatureForFinding(match.file, match.line ?? match.start?.line ?? 1, match.column ?? match.start?.column ?? 1) ?? 'unknown';
|
|
@@ -1384,6 +1391,153 @@ program
|
|
|
1384
1391
|
process.exit(1);
|
|
1385
1392
|
}
|
|
1386
1393
|
});
|
|
1394
|
+
// Telemetry opt-in (Spec 57) — status/enable/disable call the same three
|
|
1395
|
+
// functions as the telemetry MCP tool (telemetry.ts), so the CLI and the MCP
|
|
1396
|
+
// tool can never disagree about what is enabled or what a submission contains.
|
|
1397
|
+
const telemetry = program
|
|
1398
|
+
.command('telemetry')
|
|
1399
|
+
.description('Manage anonymous dismissal feedback opt-in (default OFF). Actions: status, enable, disable.');
|
|
1400
|
+
telemetry
|
|
1401
|
+
.command('status')
|
|
1402
|
+
.description('Show whether anonymous dismissal feedback is enabled, its endpoint, and the anonymous install ID.')
|
|
1403
|
+
.option('--json', OPTION_OUTPUT_AS_JSON)
|
|
1404
|
+
.action(async (options) => {
|
|
1405
|
+
const s = telemetryStatus();
|
|
1406
|
+
if (options.json) {
|
|
1407
|
+
process.stdout.write(JSON.stringify(s, null, 2) + '\n');
|
|
1408
|
+
}
|
|
1409
|
+
else {
|
|
1410
|
+
console.log(chalk.bold(s.enabled ? 'Telemetry: enabled' : 'Telemetry: disabled'));
|
|
1411
|
+
if (s.enabled) {
|
|
1412
|
+
console.log(chalk.gray(` endpoint: ${s.endpoint}`));
|
|
1413
|
+
console.log(chalk.gray(` install ID: ${s.installId}`));
|
|
1414
|
+
}
|
|
1415
|
+
else {
|
|
1416
|
+
console.log(chalk.gray(' endpoint: (none — enable with `code-audit telemetry enable`)'));
|
|
1417
|
+
}
|
|
1418
|
+
console.log(chalk.gray(`\n${s.message}`));
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
telemetry
|
|
1422
|
+
.command('enable')
|
|
1423
|
+
.description('Opt in to anonymous dismissal feedback. Defaults to the built-in service endpoint. Generates the anonymous install ID on first use.')
|
|
1424
|
+
.option('--endpoint <url>', 'Optional ingest URL. Defaults to the built-in service endpoint.')
|
|
1425
|
+
.option('--json', OPTION_OUTPUT_AS_JSON)
|
|
1426
|
+
.action(async (options) => {
|
|
1427
|
+
try {
|
|
1428
|
+
const s = telemetryEnable(options.endpoint);
|
|
1429
|
+
if (options.json) {
|
|
1430
|
+
process.stdout.write(JSON.stringify(s, null, 2) + '\n');
|
|
1431
|
+
}
|
|
1432
|
+
else {
|
|
1433
|
+
console.log(chalk.green('✓ Telemetry enabled.'));
|
|
1434
|
+
console.log(chalk.gray(` endpoint: ${s.endpoint}`));
|
|
1435
|
+
console.log(chalk.gray(` install ID: ${s.installId}`));
|
|
1436
|
+
console.log(chalk.gray(`\n${s.message}`));
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
catch (error) {
|
|
1440
|
+
console.error(chalk.red('Error:'), error);
|
|
1441
|
+
process.exit(1);
|
|
1442
|
+
}
|
|
1443
|
+
});
|
|
1444
|
+
telemetry
|
|
1445
|
+
.command('disable')
|
|
1446
|
+
.description('Turn off anonymous dismissal feedback. The endpoint is remembered; nothing further is sent.')
|
|
1447
|
+
.option('--json', OPTION_OUTPUT_AS_JSON)
|
|
1448
|
+
.action(async (options) => {
|
|
1449
|
+
const s = telemetryDisable();
|
|
1450
|
+
if (options.json) {
|
|
1451
|
+
process.stdout.write(JSON.stringify(s, null, 2) + '\n');
|
|
1452
|
+
}
|
|
1453
|
+
else {
|
|
1454
|
+
console.log(chalk.green('✓ Telemetry disabled.'));
|
|
1455
|
+
console.log(chalk.gray(s.message));
|
|
1456
|
+
}
|
|
1457
|
+
});
|
|
1458
|
+
// Accumulate a repeatable option (commander's default keeps only the last value).
|
|
1459
|
+
function collectOption(value, previous) {
|
|
1460
|
+
return [...(previous ?? []), value];
|
|
1461
|
+
}
|
|
1462
|
+
// Request a new rule (rule-request intake). POSTs to the docs site's HTTP tool
|
|
1463
|
+
// API, which validates and forwards to the shared feedback service. The CLI does
|
|
1464
|
+
// no own validation: it reads the example files, sends them with the client
|
|
1465
|
+
// surface, and prints whatever the server decides (receipt id, or field errors).
|
|
1466
|
+
program
|
|
1467
|
+
.command('request-rule')
|
|
1468
|
+
.description('Submit a request for a new Code Auditor rule (an unflagged defect class)')
|
|
1469
|
+
.requiredOption('--title <title>', 'Short rule title (10-120 chars)')
|
|
1470
|
+
.requiredOption('--symptom <text>', 'Symptom this rule should catch (40-2000 chars)')
|
|
1471
|
+
.requiredOption('--signal <text>', 'Signal/pattern the rule should look for (40-2000 chars)')
|
|
1472
|
+
.option('--language <lang>', 'Language the rule applies to (repeatable)', collectOption, [])
|
|
1473
|
+
.option('--fires <path>', 'Example file that SHOULD be flagged (repeatable)', collectOption, [])
|
|
1474
|
+
.option('--clean <path>', 'Example file that should NOT be flagged (repeatable)', collectOption, [])
|
|
1475
|
+
.option('--endpoint <url>', `Docs API base URL (default ${DEFAULT_RULE_REQUEST_BASE_URL})`)
|
|
1476
|
+
.option('--json', OPTION_OUTPUT_AS_JSON)
|
|
1477
|
+
.action(async (options) => {
|
|
1478
|
+
try {
|
|
1479
|
+
const readFiles = async (paths) => {
|
|
1480
|
+
const out = [];
|
|
1481
|
+
for (const p of paths) {
|
|
1482
|
+
out.push({ path: p, content: await fs.readFile(resolve(p), 'utf-8') });
|
|
1483
|
+
}
|
|
1484
|
+
return out;
|
|
1485
|
+
};
|
|
1486
|
+
const [firingExample, cleanExample] = await Promise.all([
|
|
1487
|
+
readFiles(options.fires ?? []),
|
|
1488
|
+
readFiles(options.clean ?? []),
|
|
1489
|
+
]);
|
|
1490
|
+
const body = {
|
|
1491
|
+
title: options.title,
|
|
1492
|
+
symptom: options.symptom,
|
|
1493
|
+
signal: options.signal,
|
|
1494
|
+
languages: options.language ?? [],
|
|
1495
|
+
firingExample,
|
|
1496
|
+
cleanExample,
|
|
1497
|
+
toolVersion: PACKAGE_VERSION,
|
|
1498
|
+
};
|
|
1499
|
+
const base = (options.endpoint ?? DEFAULT_RULE_REQUEST_BASE_URL).replace(/\/+$/, '');
|
|
1500
|
+
const url = `${base}/api/tools/request_rule`;
|
|
1501
|
+
const result = await postJson(url, body, {
|
|
1502
|
+
timeoutMs: 5000,
|
|
1503
|
+
headers: { 'x-code-auditor-client': 'cli' },
|
|
1504
|
+
});
|
|
1505
|
+
if (result.error) {
|
|
1506
|
+
console.error(chalk.red('Error:'), result.error);
|
|
1507
|
+
process.exit(1);
|
|
1508
|
+
}
|
|
1509
|
+
if (!result.ok) {
|
|
1510
|
+
const res = result.body;
|
|
1511
|
+
if (res?.fields) {
|
|
1512
|
+
console.error(chalk.red(`Error: request rejected (${res.error ?? 'validation failed'})`));
|
|
1513
|
+
for (const [field, msgs] of Object.entries(res.fields)) {
|
|
1514
|
+
console.error(chalk.gray(` ${field}: ${msgs.join('; ')}`));
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
else if (res?.retryAfterSeconds !== undefined) {
|
|
1518
|
+
console.error(chalk.red(`Error: rate limited — retry in ${res.retryAfterSeconds}s`));
|
|
1519
|
+
}
|
|
1520
|
+
else {
|
|
1521
|
+
console.error(chalk.red(`Error: ${res?.message ?? res?.error ?? `HTTP ${result.status}`}`));
|
|
1522
|
+
}
|
|
1523
|
+
process.exit(1);
|
|
1524
|
+
}
|
|
1525
|
+
const out = result.body;
|
|
1526
|
+
if (options.json) {
|
|
1527
|
+
process.stdout.write(JSON.stringify(out, null, 2) + '\n');
|
|
1528
|
+
}
|
|
1529
|
+
else {
|
|
1530
|
+
console.log(chalk.green(`✓ Rule request submitted${out.duplicateSubmission ? ' (duplicate — already received)' : ''}`));
|
|
1531
|
+
console.log(chalk.gray(` receipt id: ${out.id}`));
|
|
1532
|
+
const matches = out.existingRuleMatches ?? [];
|
|
1533
|
+
console.log(chalk.gray(` existingRuleMatches: ${matches.length ? matches.join(', ') : '(none)'}`));
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
catch (error) {
|
|
1537
|
+
console.error(chalk.red('Error:'), error);
|
|
1538
|
+
process.exit(1);
|
|
1539
|
+
}
|
|
1540
|
+
});
|
|
1387
1541
|
// Generate configuration command
|
|
1388
1542
|
program
|
|
1389
1543
|
.command('generate-config')
|
|
@@ -2298,8 +2452,18 @@ program
|
|
|
2298
2452
|
if (existing.cnt === 0 && options.path) {
|
|
2299
2453
|
const { extractChurn } = await import('./churn/churnExtractor.js');
|
|
2300
2454
|
const { computeHotspots } = await import('./hotspots/hotspotScorer.js');
|
|
2455
|
+
const { findConfigFileUp, loadConfig } = await import('./config/configLoader.js');
|
|
2456
|
+
const { DEFAULT_CHURN_CONFIG } = await import('./config/defaults.js');
|
|
2301
2457
|
try {
|
|
2302
|
-
|
|
2458
|
+
// Read the `churn` config key (Spec 13 R1) — the literal
|
|
2459
|
+
// `{ churnWindowMonths: 12 }` was the orphan; the window now resolves
|
|
2460
|
+
// from `.codeauditor.json` with DEFAULT_CHURN_CONFIG as the default.
|
|
2461
|
+
const configPath = await findConfigFileUp(options.path);
|
|
2462
|
+
const { config } = await loadConfig({
|
|
2463
|
+
configPath: configPath ?? undefined,
|
|
2464
|
+
projectRoot: options.path,
|
|
2465
|
+
});
|
|
2466
|
+
extractChurn(rawDb, options.path, config.churn ?? DEFAULT_CHURN_CONFIG);
|
|
2303
2467
|
computeHotspots(rawDb);
|
|
2304
2468
|
}
|
|
2305
2469
|
catch (err) {
|
|
@@ -2586,8 +2750,6 @@ ledgerCmd
|
|
|
2586
2750
|
// `audit --detach` forks workers/auditJobRunner; `status`/`result`/`jobs` read
|
|
2587
2751
|
// the persisted ledger. One job model (the ledger run), one write path — these
|
|
2588
2752
|
// are thin wrappers over ledger.ts + mcpAuditJobs.ts, not a second store.
|
|
2589
|
-
/** Lease TTL used by read-path reclaim, mirroring mcpAuditJobs.jobLeaseTtlMs. */
|
|
2590
|
-
const CLI_JOB_LEASE_TTL_MS = Number(process.env.CODE_AUDITOR_JOB_LEASE_TTL_MS) || 30_000;
|
|
2591
2753
|
function spec41StatusBadge(status) {
|
|
2592
2754
|
switch (status) {
|
|
2593
2755
|
case 'completed':
|
|
@@ -2692,10 +2854,11 @@ program
|
|
|
2692
2854
|
.action(async (jobId, options) => {
|
|
2693
2855
|
try {
|
|
2694
2856
|
const { getLedgerRun, reclaimStaleRunning, computeStaleness } = await import('./ledger.js');
|
|
2857
|
+
const { jobLeaseTtlMs } = await import('./mcpAuditJobs.js');
|
|
2695
2858
|
const projectRoot = resolve(options.path);
|
|
2696
2859
|
const db = CodeIndexDB.getInstance(undefined, projectRoot);
|
|
2697
2860
|
await db.initialize();
|
|
2698
|
-
reclaimStaleRunning(db.rawDb, projectRoot,
|
|
2861
|
+
reclaimStaleRunning(db.rawDb, projectRoot, jobLeaseTtlMs());
|
|
2699
2862
|
const run = getLedgerRun(db.rawDb, jobId);
|
|
2700
2863
|
if (!run) {
|
|
2701
2864
|
console.error(chalk.red(`Job not found: ${jobId}`));
|
|
@@ -2853,10 +3016,11 @@ program
|
|
|
2853
3016
|
.action(async (options) => {
|
|
2854
3017
|
try {
|
|
2855
3018
|
const { listLedgerRuns, reclaimStaleRunning, pruneLedgerRuns, computeStaleness } = await import('./ledger.js');
|
|
3019
|
+
const { jobLeaseTtlMs } = await import('./mcpAuditJobs.js');
|
|
2856
3020
|
const projectRoot = resolve(options.path);
|
|
2857
3021
|
const db = CodeIndexDB.getInstance(undefined, projectRoot);
|
|
2858
3022
|
await db.initialize();
|
|
2859
|
-
reclaimStaleRunning(db.rawDb, projectRoot,
|
|
3023
|
+
reclaimStaleRunning(db.rawDb, projectRoot, jobLeaseTtlMs());
|
|
2860
3024
|
if (options.prune) {
|
|
2861
3025
|
const keep = parseInt(options.keep, 10) || 10;
|
|
2862
3026
|
const n = pruneLedgerRuns(db.rawDb, projectRoot, keep);
|
|
@@ -3069,6 +3233,11 @@ program
|
|
|
3069
3233
|
hooks: options.hooks,
|
|
3070
3234
|
list: options.list,
|
|
3071
3235
|
});
|
|
3236
|
+
// Nudge an undecided user toward the one-time telemetry choice. Only after
|
|
3237
|
+
// a real install (not `--list`), and never once they've already decided.
|
|
3238
|
+
if (!options.list && !telemetryStatus().decided) {
|
|
3239
|
+
console.log('Anonymous dismissal feedback is off. Run `code-audit telemetry enable` to opt in, or `code-audit telemetry disable` to decline.');
|
|
3240
|
+
}
|
|
3072
3241
|
}
|
|
3073
3242
|
catch (error) {
|
|
3074
3243
|
console.error(chalk.red('Error:'), error);
|