code-auditor-mcp 4.1.0 → 5.0.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +374 -0
- package/README.md +4 -4
- package/configs/hhra-compat.json +0 -8
- package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts +1 -1
- package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.d.ts.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js +7 -1
- package/dist/__tests__/fixtures/spec-52/item-03-exec-in-loop.js.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts +2 -8
- package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.d.ts.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js +4 -4
- package/dist/__tests__/fixtures/spec-52/item-04-storage-sql-exec-in-loop.js.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts +1 -1
- package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.d.ts.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-06-chained-prepare-run-in-loop.js.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts +2 -2
- package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.d.ts.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-07-chained-prepare-bind-first-in-loop.js.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts +1 -1
- package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.d.ts.map +1 -1
- package/dist/__tests__/fixtures/spec-52/item-10-promise-all-map-of-eager-all-in-loop.js.map +1 -1
- package/dist/analyzers/applicability.d.ts +42 -0
- package/dist/analyzers/applicability.d.ts.map +1 -1
- package/dist/analyzers/applicability.js +74 -0
- package/dist/analyzers/applicability.js.map +1 -1
- package/dist/analyzers/cross-language/APIContractAnalyzer.js +18 -24
- package/dist/analyzers/cross-language/APIContractAnalyzer.js.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts +30 -23
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js +113 -76
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
- package/dist/analyzers/cross-language/SchemaValidator.d.ts +2 -0
- package/dist/analyzers/cross-language/SchemaValidator.d.ts.map +1 -1
- package/dist/analyzers/cross-language/SchemaValidator.js +8 -3
- package/dist/analyzers/cross-language/SchemaValidator.js.map +1 -1
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js +210 -148
- package/dist/analyzers/crossDomain/CrossDomainAnalyzer.js.map +1 -1
- package/dist/analyzers/documentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/documentationAnalyzer.js +23 -28
- package/dist/analyzers/documentationAnalyzer.js.map +1 -1
- package/dist/analyzers/handleIdentification.d.ts +356 -0
- package/dist/analyzers/handleIdentification.d.ts.map +1 -0
- package/dist/analyzers/handleIdentification.js +424 -0
- package/dist/analyzers/handleIdentification.js.map +1 -0
- package/dist/analyzers/manifestStaleness.d.ts +64 -0
- package/dist/analyzers/manifestStaleness.d.ts.map +1 -0
- package/dist/analyzers/manifestStaleness.js +115 -0
- package/dist/analyzers/manifestStaleness.js.map +1 -0
- package/dist/analyzers/orgFilterTiers.d.ts +73 -1
- package/dist/analyzers/orgFilterTiers.d.ts.map +1 -1
- package/dist/analyzers/orgFilterTiers.js +166 -1
- package/dist/analyzers/orgFilterTiers.js.map +1 -1
- package/dist/analyzers/provenance.d.ts +251 -57
- package/dist/analyzers/provenance.d.ts.map +1 -1
- package/dist/analyzers/provenance.js +1109 -429
- package/dist/analyzers/provenance.js.map +1 -1
- package/dist/analyzers/reactAnalyzer.d.ts +2 -0
- package/dist/analyzers/reactAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/reactAnalyzer.js +2 -0
- package/dist/analyzers/reactAnalyzer.js.map +1 -1
- package/dist/analyzers/receiverResolution.d.ts +183 -0
- package/dist/analyzers/receiverResolution.d.ts.map +1 -0
- package/dist/analyzers/receiverResolution.js +540 -0
- package/dist/analyzers/receiverResolution.js.map +1 -0
- package/dist/analyzers/receiverRoot.d.ts +328 -0
- package/dist/analyzers/receiverRoot.d.ts.map +1 -0
- package/dist/analyzers/receiverRoot.js +990 -0
- package/dist/analyzers/receiverRoot.js.map +1 -0
- package/dist/analyzers/ruleRegistry.d.ts +12 -68
- package/dist/analyzers/ruleRegistry.d.ts.map +1 -1
- package/dist/analyzers/ruleRegistry.js +32 -342
- package/dist/analyzers/ruleRegistry.js.map +1 -1
- package/dist/analyzers/ruleTiming.d.ts +10 -0
- package/dist/analyzers/ruleTiming.d.ts.map +1 -1
- package/dist/analyzers/ruleTiming.js +20 -0
- package/dist/analyzers/ruleTiming.js.map +1 -1
- package/dist/analyzers/sqlLiteral.d.ts +76 -0
- package/dist/analyzers/sqlLiteral.d.ts.map +1 -0
- package/dist/analyzers/sqlLiteral.js +419 -0
- package/dist/analyzers/sqlLiteral.js.map +1 -0
- package/dist/analyzers/tsEcosystem.d.ts +115 -0
- package/dist/analyzers/tsEcosystem.d.ts.map +1 -0
- package/dist/analyzers/tsEcosystem.js +231 -0
- package/dist/analyzers/tsEcosystem.js.map +1 -0
- package/dist/analyzers/tsExpressionDescriptor.d.ts +156 -0
- package/dist/analyzers/tsExpressionDescriptor.d.ts.map +1 -0
- package/dist/analyzers/tsExpressionDescriptor.js +374 -0
- package/dist/analyzers/tsExpressionDescriptor.js.map +1 -0
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.d.ts +6 -0
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.js +107 -44
- package/dist/analyzers/universal/UniversalConventionsAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +1 -12
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js +24 -101
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +287 -49
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +2130 -512
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +2 -18
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +0 -33
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +20 -143
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts +4 -3
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +36 -13
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSecretsAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSecretsAnalyzer.js +6 -0
- package/dist/analyzers/universal/UniversalSecretsAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSecurityAnalyzer.d.ts +15 -0
- package/dist/analyzers/universal/UniversalSecurityAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSecurityAnalyzer.js +25 -0
- package/dist/analyzers/universal/UniversalSecurityAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts +21 -32
- package/dist/analyzers/universal/UniversalStylesAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalStylesAnalyzer.js +166 -196
- package/dist/analyzers/universal/UniversalStylesAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/functionConcerns.d.ts +3 -0
- package/dist/analyzers/universal/functionConcerns.d.ts.map +1 -1
- package/dist/analyzers/universal/functionConcerns.js +4 -1
- package/dist/analyzers/universal/functionConcerns.js.map +1 -1
- package/dist/analyzers/universal/schema/codeAnalysis.d.ts +310 -69
- package/dist/analyzers/universal/schema/codeAnalysis.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/codeAnalysis.js +709 -383
- package/dist/analyzers/universal/schema/codeAnalysis.js.map +1 -1
- package/dist/analyzers/universal/schema/config.d.ts +3 -14
- package/dist/analyzers/universal/schema/config.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/config.js +3 -16
- package/dist/analyzers/universal/schema/config.js.map +1 -1
- package/dist/analyzers/universal/schema/discovery.d.ts +22 -1
- package/dist/analyzers/universal/schema/discovery.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/discovery.js +36 -20
- package/dist/analyzers/universal/schema/discovery.js.map +1 -1
- package/dist/analyzers/universal/schema/jsonSchema.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/jsonSchema.js +13 -3
- package/dist/analyzers/universal/schema/jsonSchema.js.map +1 -1
- package/dist/analyzers/universal/schema/migrations.d.ts +187 -27
- package/dist/analyzers/universal/schema/migrations.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/migrations.js +443 -186
- package/dist/analyzers/universal/schema/migrations.js.map +1 -1
- package/dist/analyzers/universal/schema/types.d.ts +17 -3
- package/dist/analyzers/universal/schema/types.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/violations.js +1 -1
- package/dist/analyzers/universal/schema/violations.js.map +1 -1
- package/dist/analyzers/universal/styleScale.d.ts +52 -0
- package/dist/analyzers/universal/styleScale.d.ts.map +1 -0
- package/dist/analyzers/universal/styleScale.js +95 -0
- package/dist/analyzers/universal/styleScale.js.map +1 -0
- package/dist/applyDataDirEnv.js +1 -1
- package/dist/applyDataDirEnv.js.map +1 -1
- package/dist/auditRouter.d.ts +26 -30
- package/dist/auditRouter.d.ts.map +1 -1
- package/dist/auditRouter.js +373 -143
- package/dist/auditRouter.js.map +1 -1
- package/dist/auditRunner.d.ts +64 -1
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +1537 -1051
- package/dist/auditRunner.js.map +1 -1
- package/dist/baseline.d.ts +30 -3
- package/dist/baseline.d.ts.map +1 -1
- package/dist/baseline.js +70 -9
- package/dist/baseline.js.map +1 -1
- package/dist/cli.js +997 -812
- package/dist/cli.js.map +1 -1
- package/dist/codeIndex/analyzerConfig.d.ts +60 -0
- package/dist/codeIndex/analyzerConfig.d.ts.map +1 -0
- package/dist/codeIndex/analyzerConfig.js +98 -0
- package/dist/codeIndex/analyzerConfig.js.map +1 -0
- package/dist/codeIndex/auditResults.d.ts +39 -0
- package/dist/codeIndex/auditResults.d.ts.map +1 -0
- package/dist/codeIndex/auditResults.js +99 -0
- package/dist/codeIndex/auditResults.js.map +1 -0
- package/dist/codeIndex/codeMap.d.ts +59 -0
- package/dist/codeIndex/codeMap.d.ts.map +1 -0
- package/dist/codeIndex/codeMap.js +72 -0
- package/dist/codeIndex/codeMap.js.map +1 -0
- package/dist/codeIndex/conventions.d.ts +33 -0
- package/dist/codeIndex/conventions.d.ts.map +1 -0
- package/dist/codeIndex/conventions.js +84 -0
- package/dist/codeIndex/conventions.js.map +1 -0
- package/dist/codeIndex/coverage.d.ts +78 -0
- package/dist/codeIndex/coverage.d.ts.map +1 -0
- package/dist/codeIndex/coverage.js +164 -0
- package/dist/codeIndex/coverage.js.map +1 -0
- package/dist/codeIndex/dependencyGraph.d.ts +97 -0
- package/dist/codeIndex/dependencyGraph.d.ts.map +1 -0
- package/dist/codeIndex/dependencyGraph.js +241 -0
- package/dist/codeIndex/dependencyGraph.js.map +1 -0
- package/dist/codeIndex/functionIndex.d.ts +111 -0
- package/dist/codeIndex/functionIndex.d.ts.map +1 -0
- package/dist/codeIndex/functionIndex.js +306 -0
- package/dist/codeIndex/functionIndex.js.map +1 -0
- package/dist/codeIndex/inferredReceivers.d.ts +32 -0
- package/dist/codeIndex/inferredReceivers.d.ts.map +1 -0
- package/dist/codeIndex/inferredReceivers.js +41 -0
- package/dist/codeIndex/inferredReceivers.js.map +1 -0
- package/dist/codeIndex/meta.d.ts +30 -0
- package/dist/codeIndex/meta.d.ts.map +1 -0
- package/dist/codeIndex/meta.js +37 -0
- package/dist/codeIndex/meta.js.map +1 -0
- package/dist/codeIndex/migrations.d.ts +96 -0
- package/dist/codeIndex/migrations.d.ts.map +1 -0
- package/dist/codeIndex/migrations.js +1302 -0
- package/dist/codeIndex/migrations.js.map +1 -0
- package/dist/codeIndex/projectTasks.d.ts +54 -0
- package/dist/codeIndex/projectTasks.d.ts.map +1 -0
- package/dist/codeIndex/projectTasks.js +81 -0
- package/dist/codeIndex/projectTasks.js.map +1 -0
- package/dist/codeIndex/provenance.d.ts +47 -0
- package/dist/codeIndex/provenance.d.ts.map +1 -0
- package/dist/codeIndex/provenance.js +48 -0
- package/dist/codeIndex/provenance.js.map +1 -0
- package/dist/codeIndex/rawSql.d.ts +54 -0
- package/dist/codeIndex/rawSql.d.ts.map +1 -0
- package/dist/codeIndex/rawSql.js +71 -0
- package/dist/codeIndex/rawSql.js.map +1 -0
- package/dist/codeIndex/schema.d.ts +99 -0
- package/dist/codeIndex/schema.d.ts.map +1 -0
- package/dist/codeIndex/schema.js +174 -0
- package/dist/codeIndex/schema.js.map +1 -0
- package/dist/codeIndex/search.d.ts +40 -0
- package/dist/codeIndex/search.d.ts.map +1 -0
- package/dist/codeIndex/search.js +316 -0
- package/dist/codeIndex/search.js.map +1 -0
- package/dist/codeIndex/shared.d.ts +27 -0
- package/dist/codeIndex/shared.d.ts.map +1 -0
- package/dist/codeIndex/shared.js +46 -0
- package/dist/codeIndex/shared.js.map +1 -0
- package/dist/codeIndex/sqliteCollection.d.ts +81 -0
- package/dist/codeIndex/sqliteCollection.d.ts.map +1 -0
- package/dist/codeIndex/sqliteCollection.js +250 -0
- package/dist/codeIndex/sqliteCollection.js.map +1 -0
- package/dist/codeIndex/whitelist.d.ts +59 -0
- package/dist/codeIndex/whitelist.d.ts.map +1 -0
- package/dist/codeIndex/whitelist.js +188 -0
- package/dist/codeIndex/whitelist.js.map +1 -0
- package/dist/codeIndexDB.d.ts +130 -277
- package/dist/codeIndexDB.d.ts.map +1 -1
- package/dist/codeIndexDB.js +364 -2748
- package/dist/codeIndexDB.js.map +1 -1
- package/dist/codeIndexService.d.ts +87 -12
- package/dist/codeIndexService.d.ts.map +1 -1
- package/dist/codeIndexService.js +110 -34
- package/dist/codeIndexService.js.map +1 -1
- package/dist/componentScanner.d.ts +35 -0
- package/dist/componentScanner.d.ts.map +1 -1
- package/dist/componentScanner.js +114 -80
- package/dist/componentScanner.js.map +1 -1
- package/dist/config/configGeneratePath.d.ts +4 -0
- package/dist/config/configGeneratePath.d.ts.map +1 -1
- package/dist/config/configGeneratePath.js +4 -0
- package/dist/config/configGeneratePath.js.map +1 -1
- package/dist/config/configLoader.d.ts +16 -1
- package/dist/config/configLoader.d.ts.map +1 -1
- package/dist/config/configLoader.js +26 -23
- package/dist/config/configLoader.js.map +1 -1
- package/dist/config/defaults.d.ts +11 -7
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +21 -20
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/effectiveConfig.d.ts +17 -2
- package/dist/config/effectiveConfig.d.ts.map +1 -1
- package/dist/config/effectiveConfig.js +32 -25
- package/dist/config/effectiveConfig.js.map +1 -1
- package/dist/config/lintConfigReader.d.ts +6 -0
- package/dist/config/lintConfigReader.d.ts.map +1 -1
- package/dist/config/lintConfigReader.js +6 -0
- package/dist/config/lintConfigReader.js.map +1 -1
- package/dist/config/staticObjectExtract.d.ts +4 -0
- package/dist/config/staticObjectExtract.d.ts.map +1 -1
- package/dist/config/staticObjectExtract.js +7 -3
- package/dist/config/staticObjectExtract.js.map +1 -1
- package/dist/config/thresholdRationales.d.ts +2 -0
- package/dist/config/thresholdRationales.d.ts.map +1 -1
- package/dist/config/thresholdRationales.js +5 -2
- package/dist/config/thresholdRationales.js.map +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +10 -5
- package/dist/constants.js.map +1 -1
- package/dist/conventions/conventionMiner.d.ts +105 -2
- package/dist/conventions/conventionMiner.d.ts.map +1 -1
- package/dist/conventions/conventionMiner.js +334 -259
- package/dist/conventions/conventionMiner.js.map +1 -1
- package/dist/coverage/coverageService.js +4 -4
- package/dist/coverage/coverageService.js.map +1 -1
- package/dist/daemon/args.d.ts +3 -0
- package/dist/daemon/args.d.ts.map +1 -1
- package/dist/daemon/args.js +3 -0
- package/dist/daemon/args.js.map +1 -1
- package/dist/daemon/core.d.ts +33 -27
- package/dist/daemon/core.d.ts.map +1 -1
- package/dist/daemon/core.js +198 -162
- package/dist/daemon/core.js.map +1 -1
- package/dist/daemon/lspServer.d.ts +8 -0
- package/dist/daemon/lspServer.d.ts.map +1 -1
- package/dist/daemon/lspServer.js +8 -0
- package/dist/daemon/lspServer.js.map +1 -1
- package/dist/daemon/main.d.ts +2 -0
- package/dist/daemon/main.d.ts.map +1 -1
- package/dist/daemon/main.js +2 -0
- package/dist/daemon/main.js.map +1 -1
- package/dist/daemon/resolve.d.ts +22 -7
- package/dist/daemon/resolve.d.ts.map +1 -1
- package/dist/daemon/resolve.js +29 -8
- package/dist/daemon/resolve.js.map +1 -1
- package/dist/daemon/socketClient.d.ts +10 -1
- package/dist/daemon/socketClient.d.ts.map +1 -1
- package/dist/daemon/socketClient.js +10 -1
- package/dist/daemon/socketClient.js.map +1 -1
- package/dist/daemon/socketServer.d.ts +13 -0
- package/dist/daemon/socketServer.d.ts.map +1 -1
- package/dist/daemon/socketServer.js +13 -0
- package/dist/daemon/socketServer.js.map +1 -1
- package/dist/dataPaths.d.ts +27 -8
- package/dist/dataPaths.d.ts.map +1 -1
- package/dist/dataPaths.js +28 -44
- package/dist/dataPaths.js.map +1 -1
- package/dist/dismissals.d.ts +22 -1
- package/dist/dismissals.d.ts.map +1 -1
- package/dist/dismissals.js +22 -1
- package/dist/dismissals.js.map +1 -1
- package/dist/enforcement/gate.d.ts +1 -0
- package/dist/enforcement/gate.d.ts.map +1 -1
- package/dist/enforcement/gate.js +1 -0
- package/dist/enforcement/gate.js.map +1 -1
- package/dist/fingerprint.d.ts +6 -0
- package/dist/fingerprint.d.ts.map +1 -1
- package/dist/fingerprint.js +46 -1
- package/dist/fingerprint.js.map +1 -1
- package/dist/functionScanner.d.ts +30 -1
- package/dist/functionScanner.d.ts.map +1 -1
- package/dist/functionScanner.js +258 -256
- package/dist/functionScanner.js.map +1 -1
- package/dist/generators/AWSQConfigGenerator.d.ts +23 -0
- package/dist/generators/AWSQConfigGenerator.d.ts.map +1 -1
- package/dist/generators/AWSQConfigGenerator.js +23 -0
- package/dist/generators/AWSQConfigGenerator.js.map +1 -1
- package/dist/generators/BaseConfigGenerator.d.ts +7 -0
- package/dist/generators/BaseConfigGenerator.d.ts.map +1 -1
- package/dist/generators/BaseConfigGenerator.js +7 -0
- package/dist/generators/BaseConfigGenerator.js.map +1 -1
- package/dist/generators/ClaudeConfigGenerator.d.ts +23 -0
- package/dist/generators/ClaudeConfigGenerator.d.ts.map +1 -1
- package/dist/generators/ClaudeConfigGenerator.js +23 -0
- package/dist/generators/ClaudeConfigGenerator.js.map +1 -1
- package/dist/generators/ClineConfigGenerator.d.ts +23 -0
- package/dist/generators/ClineConfigGenerator.d.ts.map +1 -1
- package/dist/generators/ClineConfigGenerator.js +23 -0
- package/dist/generators/ClineConfigGenerator.js.map +1 -1
- package/dist/generators/CodeiumConfigGenerator.d.ts +23 -0
- package/dist/generators/CodeiumConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CodeiumConfigGenerator.js +23 -0
- package/dist/generators/CodeiumConfigGenerator.js.map +1 -1
- package/dist/generators/CodexConfigGenerator.d.ts +23 -0
- package/dist/generators/CodexConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CodexConfigGenerator.js +23 -0
- package/dist/generators/CodexConfigGenerator.js.map +1 -1
- package/dist/generators/ConfigGeneratorFactory.d.ts +9 -0
- package/dist/generators/ConfigGeneratorFactory.d.ts.map +1 -1
- package/dist/generators/ConfigGeneratorFactory.js +9 -0
- package/dist/generators/ConfigGeneratorFactory.js.map +1 -1
- package/dist/generators/ContinueConfigGenerator.d.ts +23 -0
- package/dist/generators/ContinueConfigGenerator.d.ts.map +1 -1
- package/dist/generators/ContinueConfigGenerator.js +23 -0
- package/dist/generators/ContinueConfigGenerator.js.map +1 -1
- package/dist/generators/CopilotConfigGenerator.d.ts +23 -0
- package/dist/generators/CopilotConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CopilotConfigGenerator.js +23 -0
- package/dist/generators/CopilotConfigGenerator.js.map +1 -1
- package/dist/generators/CursorConfigGenerator.d.ts +23 -0
- package/dist/generators/CursorConfigGenerator.d.ts.map +1 -1
- package/dist/generators/CursorConfigGenerator.js +23 -0
- package/dist/generators/CursorConfigGenerator.js.map +1 -1
- package/dist/generators/GeminiConfigGenerator.d.ts +23 -0
- package/dist/generators/GeminiConfigGenerator.d.ts.map +1 -1
- package/dist/generators/GeminiConfigGenerator.js +23 -0
- package/dist/generators/GeminiConfigGenerator.js.map +1 -1
- package/dist/generators/VSCodeConfigGenerator.d.ts +23 -0
- package/dist/generators/VSCodeConfigGenerator.d.ts.map +1 -1
- package/dist/generators/VSCodeConfigGenerator.js +23 -0
- package/dist/generators/VSCodeConfigGenerator.js.map +1 -1
- package/dist/generators/ZCodeConfigGenerator.d.ts +23 -0
- package/dist/generators/ZCodeConfigGenerator.d.ts.map +1 -1
- package/dist/generators/ZCodeConfigGenerator.js +23 -0
- package/dist/generators/ZCodeConfigGenerator.js.map +1 -1
- package/dist/graph/blastRadius.d.ts.map +1 -1
- package/dist/graph/blastRadius.js +12 -7
- package/dist/graph/blastRadius.js.map +1 -1
- package/dist/graph/callGraph.d.ts +31 -0
- package/dist/graph/callGraph.d.ts.map +1 -1
- package/dist/graph/callGraph.js +62 -32
- package/dist/graph/callGraph.js.map +1 -1
- package/dist/graph/importClassification.d.ts +28 -0
- package/dist/graph/importClassification.d.ts.map +1 -1
- package/dist/graph/importClassification.js +57 -0
- package/dist/graph/importClassification.js.map +1 -1
- package/dist/graph/importGraph.d.ts +38 -0
- package/dist/graph/importGraph.d.ts.map +1 -1
- package/dist/graph/importGraph.js +38 -0
- package/dist/graph/importGraph.js.map +1 -1
- package/dist/graph/outputFormatter.d.ts +12 -4
- package/dist/graph/outputFormatter.d.ts.map +1 -1
- package/dist/graph/outputFormatter.js +12 -62
- package/dist/graph/outputFormatter.js.map +1 -1
- package/dist/hooks/codex.d.ts +8 -1
- package/dist/hooks/codex.d.ts.map +1 -1
- package/dist/hooks/codex.js +7 -0
- package/dist/hooks/codex.js.map +1 -1
- package/dist/hooks/core.d.ts +6 -0
- package/dist/hooks/core.d.ts.map +1 -1
- package/dist/hooks/core.js +6 -1
- package/dist/hooks/core.js.map +1 -1
- package/dist/hooks/cursor.d.ts +11 -1
- package/dist/hooks/cursor.d.ts.map +1 -1
- package/dist/hooks/cursor.js +10 -0
- package/dist/hooks/cursor.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/installConfig.d.ts +23 -5
- package/dist/installConfig.d.ts.map +1 -1
- package/dist/installConfig.js +23 -5
- package/dist/installConfig.js.map +1 -1
- package/dist/installer.d.ts +6 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +6 -0
- package/dist/installer.js.map +1 -1
- package/dist/invariants/ruleEngine.d.ts +3 -0
- package/dist/invariants/ruleEngine.d.ts.map +1 -1
- package/dist/invariants/ruleEngine.js +156 -119
- package/dist/invariants/ruleEngine.js.map +1 -1
- package/dist/invariants/ruleValidator.d.ts +3 -0
- package/dist/invariants/ruleValidator.d.ts.map +1 -1
- package/dist/invariants/ruleValidator.js +185 -178
- package/dist/invariants/ruleValidator.js.map +1 -1
- package/dist/languages/LanguageOrchestrator.d.ts +4 -1
- package/dist/languages/LanguageOrchestrator.d.ts.map +1 -1
- package/dist/languages/LanguageOrchestrator.js +8 -19
- package/dist/languages/LanguageOrchestrator.js.map +1 -1
- package/dist/languages/RuntimeManager.d.ts +8 -0
- package/dist/languages/RuntimeManager.d.ts.map +1 -1
- package/dist/languages/RuntimeManager.js +55 -5
- package/dist/languages/RuntimeManager.js.map +1 -1
- package/dist/languages/UniversalAnalyzer.js +1 -1
- package/dist/languages/UniversalAnalyzer.js.map +1 -1
- package/dist/languages/adapterBridge.d.ts +4 -0
- package/dist/languages/adapterBridge.d.ts.map +1 -1
- package/dist/languages/adapterBridge.js +37 -3
- package/dist/languages/adapterBridge.js.map +1 -1
- package/dist/languages/go/GoAdapter.d.ts.map +1 -1
- package/dist/languages/go/GoAdapter.js +11 -14
- package/dist/languages/go/GoAdapter.js.map +1 -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 +2 -0
- package/dist/languages/go/analyzer-src/dataaccess.go +388 -0
- package/dist/languages/go/analyzer-src/types.go +8 -0
- package/dist/languages/go/analyzer-windows-amd64.exe +0 -0
- package/dist/languages/go/database-packages.json +8 -0
- package/dist/languages/go/goResolution.d.ts +229 -0
- package/dist/languages/go/goResolution.d.ts.map +1 -0
- package/dist/languages/go/goResolution.js +799 -0
- package/dist/languages/go/goResolution.js.map +1 -0
- package/dist/languages/go/stdlib-packages.json +353 -0
- package/dist/languages/go/tenantInputs.d.ts +37 -0
- package/dist/languages/go/tenantInputs.d.ts.map +1 -0
- package/dist/languages/go/tenantInputs.js +121 -0
- package/dist/languages/go/tenantInputs.js.map +1 -0
- package/dist/languages/index.d.ts +1 -0
- package/dist/languages/index.d.ts.map +1 -1
- package/dist/languages/index.js +5 -0
- package/dist/languages/index.js.map +1 -1
- package/dist/languages/json/JsonAdapter.d.ts +177 -0
- package/dist/languages/json/JsonAdapter.d.ts.map +1 -0
- package/dist/languages/json/JsonAdapter.js +531 -0
- package/dist/languages/json/JsonAdapter.js.map +1 -0
- package/dist/languages/locationIndex.d.ts +41 -0
- package/dist/languages/locationIndex.d.ts.map +1 -0
- package/dist/languages/locationIndex.js +42 -0
- package/dist/languages/locationIndex.js.map +1 -0
- package/dist/languages/sql/dialectDetection.d.ts +57 -0
- package/dist/languages/sql/dialectDetection.d.ts.map +1 -0
- package/dist/languages/sql/dialectDetection.js +135 -0
- package/dist/languages/sql/dialectDetection.js.map +1 -0
- package/dist/languages/sql/sqlAst.d.ts +494 -0
- package/dist/languages/sql/sqlAst.d.ts.map +1 -0
- package/dist/languages/sql/sqlAst.js +1817 -0
- package/dist/languages/sql/sqlAst.js.map +1 -0
- package/dist/languages/testConventions.d.ts +12 -1
- package/dist/languages/testConventions.d.ts.map +1 -1
- package/dist/languages/testConventions.js +13 -1
- package/dist/languages/testConventions.js.map +1 -1
- package/dist/languages/tree-sitter/TreeSitterCssAdapter.js +1 -1
- package/dist/languages/tree-sitter/TreeSitterCssAdapter.js.map +1 -1
- package/dist/languages/tree-sitter/converter.js +2 -2
- package/dist/languages/tree-sitter/converter.js.map +1 -1
- package/dist/languages/tree-sitter/parser.d.ts +3 -4
- package/dist/languages/tree-sitter/parser.d.ts.map +1 -1
- package/dist/languages/tree-sitter/parser.js +10 -4
- package/dist/languages/tree-sitter/parser.js.map +1 -1
- package/dist/languages/tree-sitter/rawNode.d.ts +3 -0
- package/dist/languages/tree-sitter/rawNode.d.ts.map +1 -1
- package/dist/languages/tree-sitter/rawNode.js +3 -0
- package/dist/languages/tree-sitter/rawNode.js.map +1 -1
- package/dist/languages/types.d.ts +7 -0
- package/dist/languages/types.d.ts.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts +36 -0
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.d.ts.map +1 -1
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js +168 -45
- package/dist/languages/typescript/TreeSitterTypeScriptAdapter.js.map +1 -1
- package/dist/languages/typescript/database-packages.json +19 -0
- package/dist/ledger.d.ts +118 -2
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +167 -45
- package/dist/ledger.js.map +1 -1
- package/dist/legacyIndexNotice.d.ts +32 -0
- package/dist/legacyIndexNotice.d.ts.map +1 -0
- package/dist/legacyIndexNotice.js +89 -0
- package/dist/legacyIndexNotice.js.map +1 -0
- package/dist/mcp-tools/discoveryQueries.d.ts +55 -0
- package/dist/mcp-tools/discoveryQueries.d.ts.map +1 -0
- package/dist/mcp-tools/discoveryQueries.js +157 -0
- package/dist/mcp-tools/discoveryQueries.js.map +1 -0
- package/dist/mcp-tools/projectTasks.d.ts +9 -123
- package/dist/mcp-tools/projectTasks.d.ts.map +1 -1
- package/dist/mcp-tools/projectTasks.js +180 -170
- package/dist/mcp-tools/projectTasks.js.map +1 -1
- package/dist/mcp-tools/whitelistTools.d.ts +20 -0
- package/dist/mcp-tools/whitelistTools.d.ts.map +1 -1
- package/dist/mcp-tools/whitelistTools.js +20 -0
- package/dist/mcp-tools/whitelistTools.js.map +1 -1
- package/dist/mcp-tools/workflowGuide.d.ts +9 -0
- package/dist/mcp-tools/workflowGuide.d.ts.map +1 -1
- package/dist/mcp-tools/workflowGuide.js +13 -5
- package/dist/mcp-tools/workflowGuide.js.map +1 -1
- package/dist/mcp-tools-shared.d.ts +78 -0
- package/dist/mcp-tools-shared.d.ts.map +1 -1
- package/dist/mcp-tools-shared.js +203 -340
- package/dist/mcp-tools-shared.js.map +1 -1
- package/dist/mcp-ui-simple.d.ts +2 -0
- package/dist/mcp-ui-simple.d.ts.map +1 -1
- package/dist/mcp-ui-simple.js +12 -5
- package/dist/mcp-ui-simple.js.map +1 -1
- package/dist/mcp.d.ts +6 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +832 -851
- package/dist/mcp.js.map +1 -1
- package/dist/mcpAuditJobs.d.ts +29 -33
- package/dist/mcpAuditJobs.d.ts.map +1 -1
- package/dist/mcpAuditJobs.js +102 -791
- package/dist/mcpAuditJobs.js.map +1 -1
- package/dist/mcpAutoIndex.d.ts +5 -0
- package/dist/mcpAutoIndex.d.ts.map +1 -1
- package/dist/mcpAutoIndex.js +7 -2
- package/dist/mcpAutoIndex.js.map +1 -1
- package/dist/mcpDiagnostics.d.ts +7 -0
- package/dist/mcpDiagnostics.d.ts.map +1 -1
- package/dist/mcpDiagnostics.js +34 -9
- package/dist/mcpDiagnostics.js.map +1 -1
- package/dist/mcpToolErrors.d.ts +16 -0
- package/dist/mcpToolErrors.d.ts.map +1 -1
- package/dist/mcpToolErrors.js +16 -0
- package/dist/mcpToolErrors.js.map +1 -1
- package/dist/nextFile.d.ts +6 -0
- package/dist/nextFile.d.ts.map +1 -1
- package/dist/nextFile.js +6 -0
- package/dist/nextFile.js.map +1 -1
- package/dist/nextFileIncremental.d.ts +44 -4
- package/dist/nextFileIncremental.d.ts.map +1 -1
- package/dist/nextFileIncremental.js +47 -7
- package/dist/nextFileIncremental.js.map +1 -1
- package/dist/phase/batchFunctions.d.ts +38 -0
- package/dist/phase/batchFunctions.d.ts.map +1 -0
- package/dist/phase/batchFunctions.js +64 -0
- package/dist/phase/batchFunctions.js.map +1 -0
- package/dist/phase/checks.d.ts +39 -0
- package/dist/phase/checks.d.ts.map +1 -0
- package/dist/phase/checks.js +48 -0
- package/dist/phase/checks.js.map +1 -0
- package/dist/phase/codeBlocks.d.ts +25 -0
- package/dist/phase/codeBlocks.d.ts.map +1 -0
- package/dist/phase/codeBlocks.js +268 -0
- package/dist/phase/codeBlocks.js.map +1 -0
- package/dist/phase/colorMath.d.ts +41 -0
- package/dist/phase/colorMath.d.ts.map +1 -0
- package/dist/phase/colorMath.js +109 -0
- package/dist/phase/colorMath.js.map +1 -0
- package/dist/phase/config.d.ts +29 -0
- package/dist/phase/config.d.ts.map +1 -0
- package/dist/phase/config.js +54 -0
- package/dist/phase/config.js.map +1 -0
- package/dist/phase/consumed.d.ts +47 -0
- package/dist/phase/consumed.d.ts.map +1 -0
- package/dist/phase/consumed.js +22 -0
- package/dist/phase/consumed.js.map +1 -0
- package/dist/phase/conventionMining.d.ts +59 -0
- package/dist/phase/conventionMining.d.ts.map +1 -0
- package/dist/phase/conventionMining.js +152 -0
- package/dist/phase/conventionMining.js.map +1 -0
- package/dist/phase/coverage.d.ts +65 -0
- package/dist/phase/coverage.d.ts.map +1 -0
- package/dist/phase/coverage.js +121 -0
- package/dist/phase/coverage.js.map +1 -0
- package/dist/phase/dag.d.ts +49 -0
- package/dist/phase/dag.d.ts.map +1 -0
- package/dist/phase/dag.js +120 -0
- package/dist/phase/dag.js.map +1 -0
- package/dist/phase/dataAccessCalls.d.ts +33 -0
- package/dist/phase/dataAccessCalls.d.ts.map +1 -0
- package/dist/phase/dataAccessCalls.js +42 -0
- package/dist/phase/dataAccessCalls.js.map +1 -0
- package/dist/phase/dataAccessCallsCandidates.d.ts +25 -0
- package/dist/phase/dataAccessCallsCandidates.d.ts.map +1 -0
- package/dist/phase/dataAccessCallsCandidates.js +27 -0
- package/dist/phase/dataAccessCallsCandidates.js.map +1 -0
- package/dist/phase/dynamicSql.d.ts +18 -0
- package/dist/phase/dynamicSql.d.ts.map +1 -0
- package/dist/phase/dynamicSql.js +20 -0
- package/dist/phase/dynamicSql.js.map +1 -0
- package/dist/phase/exportForm.d.ts +23 -0
- package/dist/phase/exportForm.d.ts.map +1 -0
- package/dist/phase/exportForm.js +29 -0
- package/dist/phase/exportForm.js.map +1 -0
- package/dist/phase/exportSymbols.d.ts +21 -0
- package/dist/phase/exportSymbols.d.ts.map +1 -0
- package/dist/phase/exportSymbols.js +28 -0
- package/dist/phase/exportSymbols.js.map +1 -0
- package/dist/phase/fileHeader.d.ts +15 -0
- package/dist/phase/fileHeader.d.ts.map +1 -0
- package/dist/phase/fileHeader.js +33 -0
- package/dist/phase/fileHeader.js.map +1 -0
- package/dist/phase/fileImports.d.ts +39 -0
- package/dist/phase/fileImports.d.ts.map +1 -0
- package/dist/phase/fileImports.js +138 -0
- package/dist/phase/fileImports.js.map +1 -0
- package/dist/phase/fileSymbols.d.ts +25 -0
- package/dist/phase/fileSymbols.d.ts.map +1 -0
- package/dist/phase/fileSymbols.js +302 -0
- package/dist/phase/fileSymbols.js.map +1 -0
- package/dist/phase/functionBodies.d.ts +28 -0
- package/dist/phase/functionBodies.d.ts.map +1 -0
- package/dist/phase/functionBodies.js +67 -0
- package/dist/phase/functionBodies.js.map +1 -0
- package/dist/phase/functionIndex.d.ts +28 -0
- package/dist/phase/functionIndex.d.ts.map +1 -0
- package/dist/phase/functionIndex.js +152 -0
- package/dist/phase/functionIndex.js.map +1 -0
- package/dist/phase/goFunctionAnalysis.d.ts +47 -0
- package/dist/phase/goFunctionAnalysis.d.ts.map +1 -0
- package/dist/phase/goFunctionAnalysis.js +291 -0
- package/dist/phase/goFunctionAnalysis.js.map +1 -0
- package/dist/phase/goFunctions.d.ts +38 -0
- package/dist/phase/goFunctions.d.ts.map +1 -0
- package/dist/phase/goFunctions.js +154 -0
- package/dist/phase/goFunctions.js.map +1 -0
- package/dist/phase/goImports.d.ts +29 -0
- package/dist/phase/goImports.d.ts.map +1 -0
- package/dist/phase/goImports.js +68 -0
- package/dist/phase/goImports.js.map +1 -0
- package/dist/phase/goPackageBindings.d.ts +22 -0
- package/dist/phase/goPackageBindings.d.ts.map +1 -0
- package/dist/phase/goPackageBindings.js +30 -0
- package/dist/phase/goPackageBindings.js.map +1 -0
- package/dist/phase/goSwitches.d.ts +28 -0
- package/dist/phase/goSwitches.d.ts.map +1 -0
- package/dist/phase/goSwitches.js +52 -0
- package/dist/phase/goSwitches.js.map +1 -0
- package/dist/phase/importForm.d.ts +20 -0
- package/dist/phase/importForm.d.ts.map +1 -0
- package/dist/phase/importForm.js +27 -0
- package/dist/phase/importForm.js.map +1 -0
- package/dist/phase/importSpecifiers.d.ts +20 -0
- package/dist/phase/importSpecifiers.d.ts.map +1 -0
- package/dist/phase/importSpecifiers.js +30 -0
- package/dist/phase/importSpecifiers.js.map +1 -0
- package/dist/phase/imports.d.ts +18 -0
- package/dist/phase/imports.d.ts.map +1 -0
- package/dist/phase/imports.js +25 -0
- package/dist/phase/imports.js.map +1 -0
- package/dist/phase/jsonDocument.d.ts +26 -0
- package/dist/phase/jsonDocument.d.ts.map +1 -0
- package/dist/phase/jsonDocument.js +36 -0
- package/dist/phase/jsonDocument.js.map +1 -0
- package/dist/phase/localBinding.d.ts +33 -0
- package/dist/phase/localBinding.d.ts.map +1 -0
- package/dist/phase/localBinding.js +208 -0
- package/dist/phase/localBinding.js.map +1 -0
- package/dist/phase/loopQueries.d.ts +31 -0
- package/dist/phase/loopQueries.d.ts.map +1 -0
- package/dist/phase/loopQueries.js +44 -0
- package/dist/phase/loopQueries.js.map +1 -0
- package/dist/phase/loopQueryCandidates.d.ts +26 -0
- package/dist/phase/loopQueryCandidates.d.ts.map +1 -0
- package/dist/phase/loopQueryCandidates.js +28 -0
- package/dist/phase/loopQueryCandidates.js.map +1 -0
- package/dist/phase/oracles.d.ts +216 -0
- package/dist/phase/oracles.d.ts.map +1 -0
- package/dist/phase/oracles.js +484 -0
- package/dist/phase/oracles.js.map +1 -0
- package/dist/phase/phaseModel.d.ts +190 -0
- package/dist/phase/phaseModel.d.ts.map +1 -0
- package/dist/phase/phaseModel.js +468 -0
- package/dist/phase/phaseModel.js.map +1 -0
- package/dist/phase/producers.d.ts +450 -0
- package/dist/phase/producers.d.ts.map +1 -0
- package/dist/phase/producers.js +1027 -0
- package/dist/phase/producers.js.map +1 -0
- package/dist/phase/querySiteCandidates.d.ts +27 -0
- package/dist/phase/querySiteCandidates.d.ts.map +1 -0
- package/dist/phase/querySiteCandidates.js +66 -0
- package/dist/phase/querySiteCandidates.js.map +1 -0
- package/dist/phase/querySites.d.ts +30 -0
- package/dist/phase/querySites.d.ts.map +1 -0
- package/dist/phase/querySites.js +93 -0
- package/dist/phase/querySites.js.map +1 -0
- package/dist/phase/reachability.d.ts +61 -0
- package/dist/phase/reachability.d.ts.map +1 -0
- package/dist/phase/reachability.js +104 -0
- package/dist/phase/reachability.js.map +1 -0
- package/dist/phase/reactComponents.d.ts +33 -0
- package/dist/phase/reactComponents.d.ts.map +1 -0
- package/dist/phase/reactComponents.js +47 -0
- package/dist/phase/reactComponents.js.map +1 -0
- package/dist/phase/receiverActivity.d.ts +35 -0
- package/dist/phase/receiverActivity.d.ts.map +1 -0
- package/dist/phase/receiverActivity.js +66 -0
- package/dist/phase/receiverActivity.js.map +1 -0
- package/dist/phase/receiverConsumers.d.ts +200 -0
- package/dist/phase/receiverConsumers.d.ts.map +1 -0
- package/dist/phase/receiverConsumers.js +1025 -0
- package/dist/phase/receiverConsumers.js.map +1 -0
- package/dist/phase/receiverProvenance.d.ts +97 -0
- package/dist/phase/receiverProvenance.d.ts.map +1 -0
- package/dist/phase/receiverProvenance.js +337 -0
- package/dist/phase/receiverProvenance.js.map +1 -0
- package/dist/phase/routing.d.ts +47 -0
- package/dist/phase/routing.d.ts.map +1 -0
- package/dist/phase/routing.js +62 -0
- package/dist/phase/routing.js.map +1 -0
- package/dist/phase/rules/conventions.d.ts +61 -0
- package/dist/phase/rules/conventions.d.ts.map +1 -0
- package/dist/phase/rules/conventions.js +403 -0
- package/dist/phase/rules/conventions.js.map +1 -0
- package/dist/phase/rules/crossDomain.d.ts +102 -0
- package/dist/phase/rules/crossDomain.d.ts.map +1 -0
- package/dist/phase/rules/crossDomain.js +918 -0
- package/dist/phase/rules/crossDomain.js.map +1 -0
- package/dist/phase/rules/dataAccess.d.ts +62 -0
- package/dist/phase/rules/dataAccess.d.ts.map +1 -0
- package/dist/phase/rules/dataAccess.js +480 -0
- package/dist/phase/rules/dataAccess.js.map +1 -0
- package/dist/phase/rules/dependencyGraph.d.ts +44 -0
- package/dist/phase/rules/dependencyGraph.d.ts.map +1 -0
- package/dist/phase/rules/dependencyGraph.js +260 -0
- package/dist/phase/rules/dependencyGraph.js.map +1 -0
- package/dist/phase/rules/documentation.d.ts +45 -0
- package/dist/phase/rules/documentation.d.ts.map +1 -0
- package/dist/phase/rules/documentation.js +340 -0
- package/dist/phase/rules/documentation.js.map +1 -0
- package/dist/phase/rules/dry.d.ts +109 -0
- package/dist/phase/rules/dry.d.ts.map +1 -0
- package/dist/phase/rules/dry.js +803 -0
- package/dist/phase/rules/dry.js.map +1 -0
- package/dist/phase/rules/fileDocumentation.d.ts +36 -0
- package/dist/phase/rules/fileDocumentation.d.ts.map +1 -0
- package/dist/phase/rules/fileDocumentation.js +134 -0
- package/dist/phase/rules/fileDocumentation.js.map +1 -0
- package/dist/phase/rules/functionBodies.d.ts +33 -0
- package/dist/phase/rules/functionBodies.d.ts.map +1 -0
- package/dist/phase/rules/functionBodies.js +71 -0
- package/dist/phase/rules/functionBodies.js.map +1 -0
- package/dist/phase/rules/goRules.d.ts +49 -0
- package/dist/phase/rules/goRules.d.ts.map +1 -0
- package/dist/phase/rules/goRules.js +209 -0
- package/dist/phase/rules/goRules.js.map +1 -0
- package/dist/phase/rules/querySites.d.ts +29 -0
- package/dist/phase/rules/querySites.d.ts.map +1 -0
- package/dist/phase/rules/querySites.js +94 -0
- package/dist/phase/rules/querySites.js.map +1 -0
- package/dist/phase/rules/react.d.ts +38 -0
- package/dist/phase/rules/react.d.ts.map +1 -0
- package/dist/phase/rules/react.js +202 -0
- package/dist/phase/rules/react.js.map +1 -0
- package/dist/phase/rules/registry.d.ts +170 -0
- package/dist/phase/rules/registry.d.ts.map +1 -0
- package/dist/phase/rules/registry.js +103 -0
- package/dist/phase/rules/registry.js.map +1 -0
- package/dist/phase/rules/schema.d.ts +79 -0
- package/dist/phase/rules/schema.d.ts.map +1 -0
- package/dist/phase/rules/schema.js +273 -0
- package/dist/phase/rules/schema.js.map +1 -0
- package/dist/phase/rules/schemaJson.d.ts +32 -0
- package/dist/phase/rules/schemaJson.d.ts.map +1 -0
- package/dist/phase/rules/schemaJson.js +81 -0
- package/dist/phase/rules/schemaJson.js.map +1 -0
- package/dist/phase/rules/schemaValidator.d.ts +38 -0
- package/dist/phase/rules/schemaValidator.d.ts.map +1 -0
- package/dist/phase/rules/schemaValidator.js +107 -0
- package/dist/phase/rules/schemaValidator.js.map +1 -0
- package/dist/phase/rules/secrets.d.ts +34 -0
- package/dist/phase/rules/secrets.d.ts.map +1 -0
- package/dist/phase/rules/secrets.js +208 -0
- package/dist/phase/rules/secrets.js.map +1 -0
- package/dist/phase/rules/security.d.ts +30 -0
- package/dist/phase/rules/security.d.ts.map +1 -0
- package/dist/phase/rules/security.js +85 -0
- package/dist/phase/rules/security.js.map +1 -0
- package/dist/phase/rules/securityDefects.d.ts +37 -0
- package/dist/phase/rules/securityDefects.d.ts.map +1 -0
- package/dist/phase/rules/securityDefects.js +167 -0
- package/dist/phase/rules/securityDefects.js.map +1 -0
- package/dist/phase/rules/solid.d.ts +61 -0
- package/dist/phase/rules/solid.d.ts.map +1 -0
- package/dist/phase/rules/solid.js +562 -0
- package/dist/phase/rules/solid.js.map +1 -0
- package/dist/phase/rules/styles.d.ts +77 -0
- package/dist/phase/rules/styles.d.ts.map +1 -0
- package/dist/phase/rules/styles.js +868 -0
- package/dist/phase/rules/styles.js.map +1 -0
- package/dist/phase/rules/unreferencedModule.d.ts +26 -0
- package/dist/phase/rules/unreferencedModule.d.ts.map +1 -0
- package/dist/phase/rules/unreferencedModule.js +61 -0
- package/dist/phase/rules/unreferencedModule.js.map +1 -0
- package/dist/phase/runner.d.ts +549 -0
- package/dist/phase/runner.d.ts.map +1 -0
- package/dist/phase/runner.js +1098 -0
- package/dist/phase/runner.js.map +1 -0
- package/dist/phase/schemaCode.d.ts +34 -0
- package/dist/phase/schemaCode.d.ts.map +1 -0
- package/dist/phase/schemaCode.js +53 -0
- package/dist/phase/schemaCode.js.map +1 -0
- package/dist/phase/schemaObjects.d.ts +37 -0
- package/dist/phase/schemaObjects.d.ts.map +1 -0
- package/dist/phase/schemaObjects.js +139 -0
- package/dist/phase/schemaObjects.js.map +1 -0
- package/dist/phase/schemaUsage.d.ts +30 -0
- package/dist/phase/schemaUsage.d.ts.map +1 -0
- package/dist/phase/schemaUsage.js +99 -0
- package/dist/phase/schemaUsage.js.map +1 -0
- package/dist/phase/schemaUsageCandidates.d.ts +32 -0
- package/dist/phase/schemaUsageCandidates.d.ts.map +1 -0
- package/dist/phase/schemaUsageCandidates.js +165 -0
- package/dist/phase/schemaUsageCandidates.js.map +1 -0
- package/dist/phase/schemaValidations.d.ts +34 -0
- package/dist/phase/schemaValidations.d.ts.map +1 -0
- package/dist/phase/schemaValidations.js +53 -0
- package/dist/phase/schemaValidations.js.map +1 -0
- package/dist/phase/secretCandidates.d.ts +28 -0
- package/dist/phase/secretCandidates.d.ts.map +1 -0
- package/dist/phase/secretCandidates.js +132 -0
- package/dist/phase/secretCandidates.js.map +1 -0
- package/dist/phase/securityCandidates.d.ts +29 -0
- package/dist/phase/securityCandidates.d.ts.map +1 -0
- package/dist/phase/securityCandidates.js +469 -0
- package/dist/phase/securityCandidates.js.map +1 -0
- package/dist/phase/seeded-defects.d.ts +18 -0
- package/dist/phase/seeded-defects.d.ts.map +1 -0
- package/dist/phase/seeded-defects.js +61 -0
- package/dist/phase/seeded-defects.js.map +1 -0
- package/dist/phase/stringLiterals.d.ts +24 -0
- package/dist/phase/stringLiterals.d.ts.map +1 -0
- package/dist/phase/stringLiterals.js +35 -0
- package/dist/phase/stringLiterals.js.map +1 -0
- package/dist/phase/stylesCss.d.ts +25 -0
- package/dist/phase/stylesCss.d.ts.map +1 -0
- package/dist/phase/stylesCss.js +34 -0
- package/dist/phase/stylesCss.js.map +1 -0
- package/dist/phase/stylesMarkup.d.ts +31 -0
- package/dist/phase/stylesMarkup.d.ts.map +1 -0
- package/dist/phase/stylesMarkup.js +48 -0
- package/dist/phase/stylesMarkup.js.map +1 -0
- package/dist/phase/stylesSource.d.ts +36 -0
- package/dist/phase/stylesSource.d.ts.map +1 -0
- package/dist/phase/stylesSource.js +50 -0
- package/dist/phase/stylesSource.js.map +1 -0
- package/dist/phase/typeDeclarations.d.ts +33 -0
- package/dist/phase/typeDeclarations.d.ts.map +1 -0
- package/dist/phase/typeDeclarations.js +76 -0
- package/dist/phase/typeDeclarations.js.map +1 -0
- package/dist/phase/types.d.ts +2191 -0
- package/dist/phase/types.d.ts.map +1 -0
- package/dist/phase/types.js +27 -0
- package/dist/phase/types.js.map +1 -0
- package/dist/phase/withinFileProvenance.d.ts +50 -0
- package/dist/phase/withinFileProvenance.d.ts.map +1 -0
- package/dist/phase/withinFileProvenance.js +112 -0
- package/dist/phase/withinFileProvenance.js.map +1 -0
- package/dist/pipeline.d.ts +37 -30
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +131 -326
- package/dist/pipeline.js.map +1 -1
- package/dist/pipelineAdapters.d.ts +104 -21
- package/dist/pipelineAdapters.d.ts.map +1 -1
- package/dist/pipelineAdapters.js +1145 -988
- package/dist/pipelineAdapters.js.map +1 -1
- package/dist/pipelineTypes.d.ts +21 -0
- package/dist/pipelineTypes.d.ts.map +1 -1
- package/dist/pipelineTypes.js +21 -10
- package/dist/pipelineTypes.js.map +1 -1
- package/dist/presets/presets.d.ts +9 -2
- package/dist/presets/presets.d.ts.map +1 -1
- package/dist/presets/presets.js +15 -26
- package/dist/presets/presets.js.map +1 -1
- package/dist/reporting/csvReportGenerator.d.ts +14 -3
- package/dist/reporting/csvReportGenerator.d.ts.map +1 -1
- package/dist/reporting/csvReportGenerator.js +14 -3
- package/dist/reporting/csvReportGenerator.js.map +1 -1
- package/dist/reporting/htmlReportGenerator.d.ts +5 -1
- package/dist/reporting/htmlReportGenerator.d.ts.map +1 -1
- package/dist/reporting/htmlReportGenerator.js +5 -1
- package/dist/reporting/htmlReportGenerator.js.map +1 -1
- package/dist/reporting/jsonReportGenerator.d.ts +9 -2
- package/dist/reporting/jsonReportGenerator.d.ts.map +1 -1
- package/dist/reporting/jsonReportGenerator.js +19 -5
- package/dist/reporting/jsonReportGenerator.js.map +1 -1
- package/dist/reporting/reportGenerator.d.ts +9 -2
- package/dist/reporting/reportGenerator.d.ts.map +1 -1
- package/dist/reporting/reportGenerator.js +9 -2
- package/dist/reporting/reportGenerator.js.map +1 -1
- package/dist/reporting/sarifReportGenerator.d.ts +14 -0
- package/dist/reporting/sarifReportGenerator.d.ts.map +1 -1
- package/dist/reporting/sarifReportGenerator.js +14 -0
- package/dist/reporting/sarifReportGenerator.js.map +1 -1
- package/dist/reporting/sizeDistribution.d.ts +19 -2
- package/dist/reporting/sizeDistribution.d.ts.map +1 -1
- package/dist/reporting/sizeDistribution.js +23 -5
- package/dist/reporting/sizeDistribution.js.map +1 -1
- package/dist/ruleAliases.d.ts +6 -8
- package/dist/ruleAliases.d.ts.map +1 -1
- package/dist/ruleAliases.js +29 -4
- package/dist/ruleAliases.js.map +1 -1
- package/dist/search/QueryParser.d.ts +1 -0
- package/dist/search/QueryParser.d.ts.map +1 -1
- package/dist/search/QueryParser.js +32 -91
- package/dist/search/QueryParser.js.map +1 -1
- package/dist/services/CodeMapGenerator.d.ts +19 -20
- package/dist/services/CodeMapGenerator.d.ts.map +1 -1
- package/dist/services/CodeMapGenerator.js +214 -194
- package/dist/services/CodeMapGenerator.js.map +1 -1
- package/dist/services/ProjectTaskRepository.d.ts +65 -3
- package/dist/services/ProjectTaskRepository.d.ts.map +1 -1
- package/dist/services/ProjectTaskRepository.js +94 -25
- package/dist/services/ProjectTaskRepository.js.map +1 -1
- package/dist/services/auditJobService.d.ts +17 -1
- package/dist/services/auditJobService.d.ts.map +1 -1
- package/dist/services/auditJobService.js +16 -0
- package/dist/services/auditJobService.js.map +1 -1
- package/dist/services/fileAccounting.d.ts +43 -5
- package/dist/services/fileAccounting.d.ts.map +1 -1
- package/dist/services/fileAccounting.js +48 -9
- package/dist/services/fileAccounting.js.map +1 -1
- package/dist/services/projectTaskHelpers.d.ts +45 -0
- package/dist/services/projectTaskHelpers.d.ts.map +1 -1
- package/dist/services/projectTaskHelpers.js +45 -0
- package/dist/services/projectTaskHelpers.js.map +1 -1
- package/dist/services/whitelistService.d.ts +40 -5
- package/dist/services/whitelistService.d.ts.map +1 -1
- package/dist/services/whitelistService.js +87 -46
- package/dist/services/whitelistService.js.map +1 -1
- package/dist/sqlite/betterSqlite3.d.ts +35 -1
- package/dist/sqlite/betterSqlite3.d.ts.map +1 -1
- package/dist/sqlite/betterSqlite3.js +35 -1
- package/dist/sqlite/betterSqlite3.js.map +1 -1
- package/dist/sqlite/driver.d.ts +23 -0
- package/dist/sqlite/driver.d.ts.map +1 -1
- package/dist/sqlite/driver.js +23 -0
- package/dist/sqlite/driver.js.map +1 -1
- package/dist/sqlite/nodeSqlite.d.ts +35 -1
- package/dist/sqlite/nodeSqlite.d.ts.map +1 -1
- package/dist/sqlite/nodeSqlite.js +35 -1
- package/dist/sqlite/nodeSqlite.js.map +1 -1
- package/dist/structuralSignature.d.ts +9 -0
- package/dist/structuralSignature.d.ts.map +1 -1
- package/dist/structuralSignature.js +9 -0
- package/dist/structuralSignature.js.map +1 -1
- package/dist/styles/cssAstExtractor.d.ts +15 -0
- package/dist/styles/cssAstExtractor.d.ts.map +1 -1
- package/dist/styles/cssAstExtractor.js +15 -0
- package/dist/styles/cssAstExtractor.js.map +1 -1
- package/dist/styles/normalizer.d.ts +6 -0
- package/dist/styles/normalizer.d.ts.map +1 -1
- package/dist/styles/normalizer.js +6 -0
- package/dist/styles/normalizer.js.map +1 -1
- package/dist/styles/styleExtractor.d.ts +29 -2
- package/dist/styles/styleExtractor.d.ts.map +1 -1
- package/dist/styles/styleExtractor.js +67 -48
- package/dist/styles/styleExtractor.js.map +1 -1
- package/dist/styles/styleIndexer.d.ts +8 -0
- package/dist/styles/styleIndexer.d.ts.map +1 -1
- package/dist/styles/styleIndexer.js +135 -138
- package/dist/styles/styleIndexer.js.map +1 -1
- package/dist/styles/tailwindConfigLoader.d.ts +12 -0
- package/dist/styles/tailwindConfigLoader.d.ts.map +1 -1
- package/dist/styles/tailwindConfigLoader.js +12 -0
- package/dist/styles/tailwindConfigLoader.js.map +1 -1
- package/dist/styles/tailwindExpander.d.ts +3 -0
- package/dist/styles/tailwindExpander.d.ts.map +1 -1
- package/dist/styles/tailwindExpander.js +8 -4
- package/dist/styles/tailwindExpander.js.map +1 -1
- package/dist/styles/tailwindProbe.d.ts +9 -0
- package/dist/styles/tailwindProbe.d.ts.map +1 -1
- package/dist/styles/tailwindProbe.js +181 -166
- package/dist/styles/tailwindProbe.js.map +1 -1
- package/dist/styles/tailwindUtilityExpander.d.ts +13 -0
- package/dist/styles/tailwindUtilityExpander.d.ts.map +1 -1
- package/dist/styles/tailwindUtilityExpander.js +13 -0
- package/dist/styles/tailwindUtilityExpander.js.map +1 -1
- package/dist/symbols.d.ts +13 -11
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +14 -21
- package/dist/symbols.js.map +1 -1
- package/dist/telemetry.d.ts +31 -3
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +31 -3
- package/dist/telemetry.js.map +1 -1
- package/dist/tool-registry.d.ts +37 -1
- package/dist/tool-registry.d.ts.map +1 -1
- package/dist/tool-registry.js +37 -1
- package/dist/tool-registry.js.map +1 -1
- package/dist/types.d.ts +106 -92
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -16
- package/dist/types.js.map +1 -1
- package/dist/ui/InteractivePrompts.d.ts +12 -0
- package/dist/ui/InteractivePrompts.d.ts.map +1 -1
- package/dist/ui/InteractivePrompts.js +12 -0
- package/dist/ui/InteractivePrompts.js.map +1 -1
- package/dist/utils/astParser.d.ts +15 -0
- package/dist/utils/astParser.d.ts.map +1 -1
- package/dist/utils/astParser.js +15 -0
- package/dist/utils/astParser.js.map +1 -1
- package/dist/utils/astUtils.d.ts +60 -0
- package/dist/utils/astUtils.d.ts.map +1 -1
- package/dist/utils/astUtils.js +350 -362
- package/dist/utils/astUtils.js.map +1 -1
- package/dist/utils/contentHash.d.ts +22 -0
- package/dist/utils/contentHash.d.ts.map +1 -0
- package/dist/utils/contentHash.js +26 -0
- package/dist/utils/contentHash.js.map +1 -0
- package/dist/utils/dependencyExtractor.d.ts +28 -0
- package/dist/utils/dependencyExtractor.d.ts.map +1 -1
- package/dist/utils/dependencyExtractor.js +28 -1
- package/dist/utils/dependencyExtractor.js.map +1 -1
- package/dist/utils/errorMessage.d.ts +10 -0
- package/dist/utils/errorMessage.d.ts.map +1 -0
- package/dist/utils/errorMessage.js +12 -0
- package/dist/utils/errorMessage.js.map +1 -0
- package/dist/utils/fileDiscovery.d.ts +61 -2
- package/dist/utils/fileDiscovery.d.ts.map +1 -1
- package/dist/utils/fileDiscovery.js +131 -23
- package/dist/utils/fileDiscovery.js.map +1 -1
- package/dist/utils/reactDetection.d.ts +34 -5
- package/dist/utils/reactDetection.d.ts.map +1 -1
- package/dist/utils/reactDetection.js +73 -52
- package/dist/utils/reactDetection.js.map +1 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/dist/workers/auditWorker.js +7 -3
- package/dist/workers/auditWorker.js.map +1 -1
- package/examples/.auditrc.example.json +0 -8
- package/examples/.auditrc.json +0 -11
- package/examples/.code-auditor.json +0 -2
- package/examples/nextjs.auditrc.json +0 -8
- package/examples/node-api.auditrc.json +0 -7
- package/examples/react.auditrc.json +0 -6
- package/examples/tolerant-solid.auditrc.json +0 -5
- package/package.json +14 -8
- package/plugin/.claude-plugin/manifest.json +16 -0
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/hooks/hooks.json +6 -2
- package/plugin/scripts/hook-audit.sh +41 -14
- package/plugin/scripts/hook-common.sh +50 -5
- package/plugin/scripts/hook-drift-check.sh +72 -0
- package/plugin/scripts/hook-self-audit.sh +17 -12
- package/plugin/skills/code-auditor/SKILL.md +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,803 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spec 68 §3.2 — the DRY rules, migrated to `analyze(ctx)`.
|
|
3
|
+
*
|
|
4
|
+
* `duplicate-import` re-homes `UniversalDRYAnalyzer.checkDuplicateImports`:
|
|
5
|
+
* group the `imports` fact by `(file, source)` and flag any source imported more
|
|
6
|
+
* than once within a single file, anchored at the first import's location. The
|
|
7
|
+
* legacy detector ran per AST, so the `(file, …)` grouping is load-bearing — two
|
|
8
|
+
* files importing the same module once are not duplicates. The message and the
|
|
9
|
+
* first-import anchoring are verbatim from `checkDuplicateImports`; `symbol`
|
|
10
|
+
* carries the module source exactly as the legacy `createViolation` set
|
|
11
|
+
* `functionName` to it.
|
|
12
|
+
*
|
|
13
|
+
* `duplicate-string-literal` re-homes `checkDuplicateStrings`: group the
|
|
14
|
+
* `string-literals` fact by `(file, value)` and flag any raw string text that
|
|
15
|
+
* appears more than twice within a single file, anchored at the first
|
|
16
|
+
* occurrence. The same per-file grouping holds here (the legacy detector ran
|
|
17
|
+
* per AST), and `value` is the raw `getNodeText` (quotes included) so a
|
|
18
|
+
* `'…'` and `"…"` literal are distinct values — the same key the legacy code
|
|
19
|
+
* compared.
|
|
20
|
+
*
|
|
21
|
+
* The three block rules (`dry/duplicate`, `dry/structural-similarity`,
|
|
22
|
+
* `dry/similar-expression`) read the `code-block` fact — blocks and shape
|
|
23
|
+
* fragments the `codeBlocks.ts` producer extracted from the AST. They re-home
|
|
24
|
+
* `reportExactDuplicates` / `reportStructuralDuplicates` /
|
|
25
|
+
* `reportExpressionSimilarities` over the projected data. The legacy
|
|
26
|
+
* `analyzeAST` ran **once per file**, so each rule partitions the corpus fact by
|
|
27
|
+
* `file` and runs its filter → dedupe → compare within one file (a block in file
|
|
28
|
+
* A is never compared against a block in file B).
|
|
29
|
+
*
|
|
30
|
+
* `dry/diverging-clone` is the cross-run pair-tracking pass (Spec 13 R5): it
|
|
31
|
+
* reads the `clone-pair-history` fact — the `dry_pair_history` similarity series
|
|
32
|
+
* the DRY bundle seeds each run — and flags a pair whose similarity has fallen by
|
|
33
|
+
* `divergenceThreshold` for `divergenceRuns` consecutive runs. It re-homes the
|
|
34
|
+
* legacy auditRunner Phase 2 divergence pass verbatim, over the grouped fact.
|
|
35
|
+
*/
|
|
36
|
+
import { RULE_REGISTRY } from '../../analyzers/ruleRegistry.js';
|
|
37
|
+
import * as crypto from 'crypto';
|
|
38
|
+
const META = RULE_REGISTRY['duplicate-import'];
|
|
39
|
+
const STRING_META = RULE_REGISTRY['duplicate-string-literal'];
|
|
40
|
+
const DUP_META = RULE_REGISTRY['dry/duplicate'];
|
|
41
|
+
const STRUCT_META = RULE_REGISTRY['dry/structural-similarity'];
|
|
42
|
+
const EXPR_META = RULE_REGISTRY['dry/similar-expression'];
|
|
43
|
+
const DIVERGING_META = RULE_REGISTRY['dry/diverging-clone'];
|
|
44
|
+
/** Re-homes `checkDuplicateImports`, grouping per file. */
|
|
45
|
+
function detectDuplicateImport(facts) {
|
|
46
|
+
const byFile = new Map();
|
|
47
|
+
for (const imp of facts) {
|
|
48
|
+
// The `imports` fact is shared with the Go `import-organization`/`import-style`
|
|
49
|
+
// rules (a mixed corpus concatenates both producers' output). This rule is
|
|
50
|
+
// TS/JS-only: the Go producer always sets `alias` (null for an unnamed
|
|
51
|
+
// import), the TS producer leaves it absent, so `alias !== undefined` marks
|
|
52
|
+
// a Go import and it is skipped here.
|
|
53
|
+
if (imp.alias !== undefined)
|
|
54
|
+
continue;
|
|
55
|
+
let fileMap = byFile.get(imp.file);
|
|
56
|
+
if (!fileMap) {
|
|
57
|
+
fileMap = new Map();
|
|
58
|
+
byFile.set(imp.file, fileMap);
|
|
59
|
+
}
|
|
60
|
+
const locs = fileMap.get(imp.source) ?? [];
|
|
61
|
+
locs.push({ line: imp.line, column: imp.column });
|
|
62
|
+
fileMap.set(imp.source, locs);
|
|
63
|
+
}
|
|
64
|
+
const findings = [];
|
|
65
|
+
for (const [file, fileMap] of byFile) {
|
|
66
|
+
for (const [source, locs] of fileMap) {
|
|
67
|
+
if (locs.length <= 1)
|
|
68
|
+
continue;
|
|
69
|
+
findings.push({
|
|
70
|
+
ruleId: 'duplicate-import',
|
|
71
|
+
severity: 'high',
|
|
72
|
+
message: `Module "${source}" is imported ${locs.length} times`,
|
|
73
|
+
file,
|
|
74
|
+
line: locs[0].line,
|
|
75
|
+
column: locs[0].column,
|
|
76
|
+
symbol: source,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return findings;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* A single identifier-like token is code *vocabulary*, not a duplicated *value*:
|
|
84
|
+
* `'typescript'`, `'function_declaration'`, `'conventions/usage-pair'`,
|
|
85
|
+
* `'margin-top'` name concepts in the code's own vocabulary (a format name, a
|
|
86
|
+
* tree-sitter node type, a rule id, a CSS property) and are correct to repeat
|
|
87
|
+
* inline — extracting them to a constant adds indirection, not clarity. A magic
|
|
88
|
+
* string worth naming is a value with *content*: whitespace (a message, a query,
|
|
89
|
+
* a sentence) or punctuation outside the slug set (an email, a URL, a format
|
|
90
|
+
* string). This is the precision boundary the legacy `checkDuplicateStrings`
|
|
91
|
+
* lacked — it flagged any repeated string, so a code-analysis tool's own source
|
|
92
|
+
* (full of node-type and fact-name literals) read as hundreds of false positives.
|
|
93
|
+
*/
|
|
94
|
+
const VOCABULARY_TOKEN = /^[A-Za-z_$][A-Za-z0-9_$./:-]*$/;
|
|
95
|
+
/** A relative module specifier (`'./x.js'`, `'../x.js'`) names a file, not a value. */
|
|
96
|
+
const RELATIVE_MODULE = /^\.\.?\//;
|
|
97
|
+
/** A CLI flag/option spec (`--overwrite`, `-p, --path <path>`, `--limit <n>`):
|
|
98
|
+
* the commander `.option()` signature string, repeated verbatim across the
|
|
99
|
+
* option definition, help text and docs. A flag *name* (with an optional
|
|
100
|
+
* `<arg>`/`[arg]` placeholder), not a duplicated value — extracting it to a
|
|
101
|
+
* constant adds indirection, not clarity (the same rationale as a vocabulary
|
|
102
|
+
* token). */
|
|
103
|
+
const CLI_OPTION = /^--?[A-Za-z][\w-]*(?:, --?[A-Za-z][\w-]*)*(?:\s+<[^>]+>|\s+\[[^\]]+\])*$/;
|
|
104
|
+
/** A decorative separator — a run of box-drawing/punctuation with no alphanumeric
|
|
105
|
+
* content (`════…`, `──…`). Pure presentation, never a value worth extracting. */
|
|
106
|
+
const SEPARATOR_ONLY = /^[^A-Za-z0-9]*$/;
|
|
107
|
+
/** A dotted/versioned name or IP literal (`.codeauditor.json`, `127.0.0.1`,
|
|
108
|
+
* `v1.2.3`): an identifier-like token whose first character is a digit or dot
|
|
109
|
+
* rather than a letter, so `VOCABULARY_TOKEN` (which starts `[A-Za-z_$]`) misses
|
|
110
|
+
* it. A filename or constant address is a *name*, not a duplicated value. */
|
|
111
|
+
const DOTTED_NAME = /^\.?[A-Za-z0-9_$][A-Za-z0-9_$./:-]*$/;
|
|
112
|
+
/** True when a quoted literal is a *name*, not a duplicated value: a single
|
|
113
|
+
* identifier-like token (vocabulary), a relative module path, a CLI flag spec,
|
|
114
|
+
* a decorative separator, or a dotted filename/IP. */
|
|
115
|
+
function isNameLiteral(value) {
|
|
116
|
+
const inner = value.replace(/^['"`]/, '').replace(/['"`]$/, '');
|
|
117
|
+
return VOCABULARY_TOKEN.test(inner)
|
|
118
|
+
|| RELATIVE_MODULE.test(inner)
|
|
119
|
+
|| CLI_OPTION.test(inner)
|
|
120
|
+
|| SEPARATOR_ONLY.test(inner)
|
|
121
|
+
|| DOTTED_NAME.test(inner);
|
|
122
|
+
}
|
|
123
|
+
/** Re-homes `checkDuplicateStrings`, grouping per `(file, value)`. */
|
|
124
|
+
function detectDuplicateStringLiteral(facts) {
|
|
125
|
+
const byFile = new Map();
|
|
126
|
+
for (const lit of facts) {
|
|
127
|
+
if (lit.value.length <= 10)
|
|
128
|
+
continue; // non-trivial strings only
|
|
129
|
+
if (isNameLiteral(lit.value))
|
|
130
|
+
continue; // a name (vocabulary/path), not a value
|
|
131
|
+
let fileMap = byFile.get(lit.file);
|
|
132
|
+
if (!fileMap) {
|
|
133
|
+
fileMap = new Map();
|
|
134
|
+
byFile.set(lit.file, fileMap);
|
|
135
|
+
}
|
|
136
|
+
const locs = fileMap.get(lit.value) ?? [];
|
|
137
|
+
locs.push({ line: lit.line, column: lit.column });
|
|
138
|
+
fileMap.set(lit.value, locs);
|
|
139
|
+
}
|
|
140
|
+
const findings = [];
|
|
141
|
+
for (const [file, fileMap] of byFile) {
|
|
142
|
+
for (const [value, locs] of fileMap) {
|
|
143
|
+
if (locs.length <= 2)
|
|
144
|
+
continue; // more than 2 occurrences
|
|
145
|
+
findings.push({
|
|
146
|
+
ruleId: 'duplicate-string-literal',
|
|
147
|
+
severity: 'high',
|
|
148
|
+
message: `String literal "${value.substring(0, 30)}..." is duplicated ${locs.length} times`,
|
|
149
|
+
file,
|
|
150
|
+
line: locs[0].line,
|
|
151
|
+
column: locs[0].column,
|
|
152
|
+
symbol: value.substring(0, 50),
|
|
153
|
+
fix: { oldText: value, newText: '// Consider extracting to a constant' },
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return findings;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The defaults re-declared from `DEFAULT_DRY_CONFIG` (UniversalDRYAnalyzer.ts) —
|
|
161
|
+
* the same merge the legacy `analyzeAST` did before extraction. `excludePatterns`
|
|
162
|
+
* is verbatim (the test/spec/tests-dir globs). The `checkStructuralSimilarity` /
|
|
163
|
+
* `checkExpressionSimilarity` booleans are no longer read as gates (§10 — config
|
|
164
|
+
* tunes, never selects); they remain in the merged shape only for config-surface
|
|
165
|
+
* compatibility until the §15 deletions drop them.
|
|
166
|
+
*/
|
|
167
|
+
const DRY_BLOCK_DEFAULTS = {
|
|
168
|
+
minLineThreshold: 15,
|
|
169
|
+
similarityThreshold: 0.85,
|
|
170
|
+
excludePatterns: [
|
|
171
|
+
'**/*.test.ts', '**/*.spec.ts',
|
|
172
|
+
'**/*.test.tsx', '**/*.spec.tsx',
|
|
173
|
+
'**/*.test.js', '**/*.spec.js',
|
|
174
|
+
'**/*.test.jsx', '**/*.spec.jsx',
|
|
175
|
+
'**/test/**', '**/tests/**',
|
|
176
|
+
],
|
|
177
|
+
checkStructuralSimilarity: false,
|
|
178
|
+
checkExpressionSimilarity: true,
|
|
179
|
+
minShapeNames: 4,
|
|
180
|
+
};
|
|
181
|
+
/** Merge the (default-merged) thresholds onto the block defaults. */
|
|
182
|
+
export function resolveBlockConfig(t) {
|
|
183
|
+
return { ...DRY_BLOCK_DEFAULTS, ...t };
|
|
184
|
+
}
|
|
185
|
+
/** True if the two blocks share code spans (same file + overlapping lines). */
|
|
186
|
+
function spansOverlap(a, b) {
|
|
187
|
+
if (a.file !== b.file)
|
|
188
|
+
return false;
|
|
189
|
+
return !(a.end.line < b.start.line || b.end.line < a.start.line);
|
|
190
|
+
}
|
|
191
|
+
/** Sort comparator: earliest file+line first. */
|
|
192
|
+
function byFileAndLine(a, b) {
|
|
193
|
+
if (a.file !== b.file)
|
|
194
|
+
return a.file.localeCompare(b.file);
|
|
195
|
+
return a.start.line - b.start.line;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Deduplicate overlapping blocks (re-homed verbatim): prefer the innermost block
|
|
199
|
+
* when one fully contains another, the earliest when only partially overlapping.
|
|
200
|
+
*/
|
|
201
|
+
function deduplicateBlocks(blocks) {
|
|
202
|
+
if (blocks.length <= 1)
|
|
203
|
+
return blocks;
|
|
204
|
+
const sorted = [...blocks].sort(byFileAndLine);
|
|
205
|
+
const result = [];
|
|
206
|
+
let last = null;
|
|
207
|
+
for (const block of sorted) {
|
|
208
|
+
if (last && last.file === block.file) {
|
|
209
|
+
if (last.start.line <= block.start.line && last.end.line >= block.end.line) {
|
|
210
|
+
result.pop();
|
|
211
|
+
result.push(block);
|
|
212
|
+
last = block;
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (block.start.line <= last.start.line && block.end.line >= last.end.line) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (!(last.end.line < block.start.line)) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
result.push(block);
|
|
223
|
+
last = block;
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
/** Overlapping bigrams of a token sequence — an order-aware fingerprint. A
|
|
228
|
+
* sequence shorter than two tokens yields no bigrams (similarity 0). */
|
|
229
|
+
function tokenBigrams(tokens) {
|
|
230
|
+
const out = [];
|
|
231
|
+
for (let i = 0; i + 1 < tokens.length; i++) {
|
|
232
|
+
out.push(tokens[i] + '' + tokens[i + 1]);
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}
|
|
236
|
+
/** Jaccard similarity over the token *bigrams* of two whitespace-tokenized
|
|
237
|
+
* strings, [0, 1]. Bigrams are order- and frequency-aware where a bare token
|
|
238
|
+
* SET is not: two blocks sharing the same token vocabulary but in a different
|
|
239
|
+
* order (or a large block whose vocabulary subsumes a smaller block's) no
|
|
240
|
+
* longer compare as ~100% structurally similar. */
|
|
241
|
+
function computeJaccardSimilarity(text1, text2) {
|
|
242
|
+
const grams1 = new Set(tokenBigrams(text1.split(/\s+/).filter(Boolean)));
|
|
243
|
+
const grams2 = new Set(tokenBigrams(text2.split(/\s+/).filter(Boolean)));
|
|
244
|
+
let intersection = 0;
|
|
245
|
+
for (const g of grams1) {
|
|
246
|
+
if (grams2.has(g))
|
|
247
|
+
intersection++;
|
|
248
|
+
}
|
|
249
|
+
const union = grams1.size + grams2.size - intersection;
|
|
250
|
+
return union === 0 ? 0 : intersection / union;
|
|
251
|
+
}
|
|
252
|
+
/** Translate a minimal glob (`*`, `**`, `?`) to an anchored regex (re-homed). */
|
|
253
|
+
function globToRegExp(pattern) {
|
|
254
|
+
const out = ['^'];
|
|
255
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
256
|
+
const ch = pattern[i];
|
|
257
|
+
if (ch === '*') {
|
|
258
|
+
if (pattern[i + 1] === '*') {
|
|
259
|
+
i += 1;
|
|
260
|
+
if (pattern[i + 1] === '/') {
|
|
261
|
+
i += 1;
|
|
262
|
+
out.push('(?:.*/)?');
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
out.push('.*');
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
out.push('[^/]*');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if (ch === '?') {
|
|
273
|
+
out.push('[^/]');
|
|
274
|
+
}
|
|
275
|
+
else if ('^$\\.+?()[]{}|'.includes(ch)) {
|
|
276
|
+
out.push('\\', ch);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
out.push(ch);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
out.push('$');
|
|
283
|
+
return new RegExp(out.join(''));
|
|
284
|
+
}
|
|
285
|
+
/** True when a file path matches any of the given glob-ish exclude patterns. */
|
|
286
|
+
function isExcluded(filePath, patterns) {
|
|
287
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
288
|
+
return patterns.some((pattern) => globToRegExp(pattern).test(normalized));
|
|
289
|
+
}
|
|
290
|
+
/** True when `outer`'s span fully contains `inner`'s span in the same file. */
|
|
291
|
+
function shapeSpansContain(outer, inner) {
|
|
292
|
+
if (outer.file !== inner.file)
|
|
293
|
+
return false;
|
|
294
|
+
const startLte = outer.start.line < inner.start.line ||
|
|
295
|
+
(outer.start.line === inner.start.line && outer.start.column <= inner.start.column);
|
|
296
|
+
const endGte = outer.end.line > inner.end.line ||
|
|
297
|
+
(outer.end.line === inner.end.line && outer.end.column >= inner.end.column);
|
|
298
|
+
return startLte && endGte;
|
|
299
|
+
}
|
|
300
|
+
/** Drop nested fragments, keeping the outermost (re-homed `dedupeShapeFragments`). */
|
|
301
|
+
function dedupeShapeFragments(fragments) {
|
|
302
|
+
const sorted = [...fragments].sort((a, b) => {
|
|
303
|
+
if (a.file !== b.file)
|
|
304
|
+
return a.file.localeCompare(b.file);
|
|
305
|
+
if (a.start.line !== b.start.line)
|
|
306
|
+
return a.start.line - b.start.line;
|
|
307
|
+
if (a.start.column !== b.start.column)
|
|
308
|
+
return a.start.column - b.start.column;
|
|
309
|
+
if (a.end.line !== b.end.line)
|
|
310
|
+
return b.end.line - a.end.line;
|
|
311
|
+
return b.end.column - a.end.column;
|
|
312
|
+
});
|
|
313
|
+
const kept = [];
|
|
314
|
+
for (const f of sorted) {
|
|
315
|
+
if (!kept.some((k) => shapeSpansContain(k, f)))
|
|
316
|
+
kept.push(f);
|
|
317
|
+
}
|
|
318
|
+
return kept;
|
|
319
|
+
}
|
|
320
|
+
/** Longest common subsequence of two string arrays, as the actual shared sequence. */
|
|
321
|
+
function longestCommonSubsequence(a, b) {
|
|
322
|
+
const m = a.length;
|
|
323
|
+
const n = b.length;
|
|
324
|
+
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
325
|
+
for (let i = 1; i <= m; i++) {
|
|
326
|
+
for (let j = 1; j <= n; j++) {
|
|
327
|
+
dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1]);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const seq = [];
|
|
331
|
+
let i = m;
|
|
332
|
+
let j = n;
|
|
333
|
+
while (i > 0 && j > 0) {
|
|
334
|
+
if (a[i - 1] === b[j - 1]) {
|
|
335
|
+
seq.push(a[i - 1]);
|
|
336
|
+
i--;
|
|
337
|
+
j--;
|
|
338
|
+
}
|
|
339
|
+
else if (dp[i - 1][j] >= dp[i][j - 1]) {
|
|
340
|
+
i--;
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
j--;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return seq.reverse();
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Method names from well-known fluent APIs (query/schema builders, validators,
|
|
350
|
+
* commander, promises, DOM/stdlib chains) — "structurally similar by design",
|
|
351
|
+
* so the default-on expression rule stays quiet on them (re-homed verbatim).
|
|
352
|
+
*/
|
|
353
|
+
const FLUENT_CHAIN_METHODS = new Set([
|
|
354
|
+
// SQL query builders (knex, Kysely, Drizzle, …)
|
|
355
|
+
'select', 'selectDistinct', 'from', 'where', 'andWhere', 'orWhere', 'whereRaw',
|
|
356
|
+
'whereIn', 'whereNotIn', 'whereNull', 'whereNotNull', 'whereExists', 'whereBetween',
|
|
357
|
+
'orderBy', 'groupBy', 'having', 'join', 'innerJoin', 'leftJoin', 'rightJoin',
|
|
358
|
+
'crossJoin', 'fullOuterJoin', 'limit', 'offset', 'distinct', 'count', 'sum', 'avg',
|
|
359
|
+
'first', 'pluck', 'forUpdate', 'forShare', 'skipLocked', 'union', 'unionAll',
|
|
360
|
+
'insert', 'update', 'del', 'delete', 'into', 'returning', 'onConflict', 'ignore',
|
|
361
|
+
'merge', 'increment', 'decrement', 'transacting', 'using', 'updateFrom', 'testSql',
|
|
362
|
+
'toSQL', 'toQuery', 'raw', 'table', 'schemaBuilder', 'queryBuilder', 'partitionBy',
|
|
363
|
+
// Schema builders (knex `table.integer().unsigned().references()`)
|
|
364
|
+
'createTable', 'alterTable', 'dropTable', 'dropTableIfExists', 'renameTable',
|
|
365
|
+
'renameColumn', 'dropColumn', 'integer', 'bigInteger', 'text', 'boolean', 'float',
|
|
366
|
+
'double', 'decimal', 'date', 'dateTime', 'timestamp', 'timestamps', 'time',
|
|
367
|
+
'binary', 'json', 'jsonb', 'uuid', 'unsigned', 'references', 'inTable', 'defaultTo',
|
|
368
|
+
'index', 'unique', 'primary', 'comment', 'foreign', 'onDelete', 'onUpdate',
|
|
369
|
+
'deferrable', 'withKeyName', 'notNullable', 'collate', 'check',
|
|
370
|
+
// Zod / Valibot schema validators
|
|
371
|
+
'trim', 'min', 'max', 'length', 'int', 'positive', 'nonnegative', 'negative',
|
|
372
|
+
'regex', 'email', 'url', 'datetime', 'optional', 'nullish', 'nullable', 'default',
|
|
373
|
+
'describe', 'refine', 'superRefine', 'transform', 'safeParse', 'parse', 'array',
|
|
374
|
+
'object', 'enum', 'record', 'union', 'intersection', 'tuple', 'literal', 'number',
|
|
375
|
+
'string', 'nativeEnum', 'lazy', 'preprocess', 'brand',
|
|
376
|
+
// commander / CLI builders
|
|
377
|
+
'command', 'description', 'option', 'requiredOption', 'action', 'argument',
|
|
378
|
+
'version', 'usage', 'name', 'alias', 'allowUnknownOption', 'exitOverride',
|
|
379
|
+
// Promises
|
|
380
|
+
'then', 'catch', 'finally',
|
|
381
|
+
// DOM / jQuery traversal and JS stdlib array/string method chains
|
|
382
|
+
'closest', 'find', 'text', 'map', 'filter', 'reduce', 'forEach', 'slice', 'split',
|
|
383
|
+
'join', 'replace', 'replaceAll', 'toLowerCase', 'toUpperCase', 'flatMap', 'concat',
|
|
384
|
+
]);
|
|
385
|
+
/** True when the chain is a fluent library/builder API (not duplicated logic). */
|
|
386
|
+
function isFluentChain(names) {
|
|
387
|
+
return names.some((n) => FLUENT_CHAIN_METHODS.has(n));
|
|
388
|
+
}
|
|
389
|
+
/** Partition the corpus `code-block` fact by file, dropping excluded files. */
|
|
390
|
+
function perFileGroups(facts, patterns) {
|
|
391
|
+
const byFile = new Map();
|
|
392
|
+
for (const fact of facts) {
|
|
393
|
+
if (isExcluded(fact.file, patterns))
|
|
394
|
+
continue;
|
|
395
|
+
const group = byFile.get(fact.file) ?? { blocks: [], fragments: [] };
|
|
396
|
+
if (fact.kind === 'block')
|
|
397
|
+
group.blocks.push(fact);
|
|
398
|
+
else
|
|
399
|
+
group.fragments.push(fact);
|
|
400
|
+
byFile.set(fact.file, group);
|
|
401
|
+
}
|
|
402
|
+
return byFile;
|
|
403
|
+
}
|
|
404
|
+
/** Re-homes `reportExactDuplicates` (per file): group by hash, flag repeats. */
|
|
405
|
+
function detectExactDuplicates(blocks, cfg) {
|
|
406
|
+
const minLine = cfg.minLineThreshold || 5;
|
|
407
|
+
const large = blocks.filter((b) => b.lineCount >= minLine);
|
|
408
|
+
const deduped = deduplicateBlocks(large);
|
|
409
|
+
const byHash = new Map();
|
|
410
|
+
for (const block of deduped) {
|
|
411
|
+
const group = byHash.get(block.hash) ?? [];
|
|
412
|
+
group.push(block);
|
|
413
|
+
byHash.set(block.hash, group);
|
|
414
|
+
}
|
|
415
|
+
const findings = [];
|
|
416
|
+
for (const group of byHash.values()) {
|
|
417
|
+
if (group.length < 2)
|
|
418
|
+
continue;
|
|
419
|
+
const sorted = [...group].sort(byFileAndLine);
|
|
420
|
+
const original = sorted[0];
|
|
421
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
422
|
+
const block = sorted[i];
|
|
423
|
+
if (spansOverlap(original, block))
|
|
424
|
+
continue;
|
|
425
|
+
findings.push({
|
|
426
|
+
ruleId: 'dry/duplicate',
|
|
427
|
+
severity: 'high',
|
|
428
|
+
message: `Duplicate code block detected (${block.lineCount} lines). ` +
|
|
429
|
+
`First occurrence at ${original.file}:${original.start.line}`,
|
|
430
|
+
file: block.file,
|
|
431
|
+
line: block.start.line,
|
|
432
|
+
column: block.start.column,
|
|
433
|
+
symbol: block.hash,
|
|
434
|
+
resolution: {
|
|
435
|
+
action: 'extract-duplicate',
|
|
436
|
+
summary: `Extract the ${block.lineCount}-line block duplicated at ${original.file}:${original.start.line} into a shared function both sites call.`,
|
|
437
|
+
files: [block.file, original.file],
|
|
438
|
+
lines: [block.start.line, original.start.line],
|
|
439
|
+
},
|
|
440
|
+
fix: { oldText: block.text, newText: '// Consider extracting to a shared function' },
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return findings;
|
|
445
|
+
}
|
|
446
|
+
/** Re-homes `reportStructuralDuplicates` (per file): Jaccard over token-kind skeletons. */
|
|
447
|
+
function detectStructuralDuplicates(blocks, cfg) {
|
|
448
|
+
const minLine = cfg.minLineThreshold || 5;
|
|
449
|
+
const threshold = cfg.similarityThreshold ?? 0.85;
|
|
450
|
+
const large = blocks.filter((b) => b.lineCount >= minLine);
|
|
451
|
+
const deduped = deduplicateBlocks(large);
|
|
452
|
+
const findings = [];
|
|
453
|
+
for (let i = 0; i < deduped.length; i++) {
|
|
454
|
+
const original = deduped[i];
|
|
455
|
+
for (let j = i + 1; j < deduped.length; j++) {
|
|
456
|
+
const block = deduped[j];
|
|
457
|
+
if (original.hash === block.hash)
|
|
458
|
+
continue;
|
|
459
|
+
if (spansOverlap(original, block))
|
|
460
|
+
continue;
|
|
461
|
+
const similarity = computeJaccardSimilarity(original.structuralSkeleton, block.structuralSkeleton);
|
|
462
|
+
if (similarity < threshold)
|
|
463
|
+
continue;
|
|
464
|
+
findings.push({
|
|
465
|
+
ruleId: 'dry/structural-similarity',
|
|
466
|
+
severity: 'high',
|
|
467
|
+
message: `Structurally similar code block detected (${Math.round(similarity * 100)}% similar). ` +
|
|
468
|
+
`First occurrence at ${original.file}:${original.start.line}`,
|
|
469
|
+
file: block.file,
|
|
470
|
+
line: block.start.line,
|
|
471
|
+
column: block.start.column,
|
|
472
|
+
symbol: block.hash,
|
|
473
|
+
fix: { oldText: block.text, newText: '// Consider extracting to a shared function' },
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return findings;
|
|
478
|
+
}
|
|
479
|
+
/** Build the `dry/similar-expression` finding for `fragment` resembling `first`. */
|
|
480
|
+
function buildSimilarityViolation(fragment, first, shared) {
|
|
481
|
+
const isObject = fragment.fragmentKind === 'object';
|
|
482
|
+
const label = isObject ? 'object literal' : 'call chain';
|
|
483
|
+
const unit = isObject ? 'fields' : 'methods';
|
|
484
|
+
const targetClause = isObject && fragment.target
|
|
485
|
+
? ` built for "${fragment.target}"`
|
|
486
|
+
: '';
|
|
487
|
+
return {
|
|
488
|
+
ruleId: 'dry/similar-expression',
|
|
489
|
+
severity: 'high',
|
|
490
|
+
message: `Near-identical ${label}${targetClause} detected (${shared.length} shared ${unit}: ${shared.join(', ')}). ` +
|
|
491
|
+
`First occurrence at ${first.file}:${first.start.line}`,
|
|
492
|
+
file: fragment.file,
|
|
493
|
+
line: fragment.start.line,
|
|
494
|
+
column: fragment.start.column,
|
|
495
|
+
symbol: shared.join('.'),
|
|
496
|
+
resolution: {
|
|
497
|
+
action: 'extract-shared-expression',
|
|
498
|
+
summary: `Extract the shared ${isObject ? 'field list' : 'method chain'} (${shared.join(', ')}) into a shared helper, builder, or constant both sites use.`,
|
|
499
|
+
files: [fragment.file, first.file],
|
|
500
|
+
lines: [fragment.start.line, first.start.line],
|
|
501
|
+
},
|
|
502
|
+
fix: { oldText: fragment.text, newText: `// Consider extracting the shared ${unit} into a shared helper` },
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
/** Re-homes `reportExpressionSimilarities` (per file): LCS over fragment names. */
|
|
506
|
+
function detectExpressionSimilarities(fragments, cfg) {
|
|
507
|
+
const min = cfg.minShapeNames || 4;
|
|
508
|
+
// The legacy walk filtered fragments during collection: object literals were
|
|
509
|
+
// dropped only for having too few names, while call chains were also dropped
|
|
510
|
+
// when they were fluent library/builder APIs. Re-apply that same split here —
|
|
511
|
+
// a fluent-chain exclusion on an object literal would wrongly drop a
|
|
512
|
+
// `{ select, from, where, orderBy }` literal that the legacy code compared.
|
|
513
|
+
const eligible = fragments.filter((f) => {
|
|
514
|
+
if (f.names.length < min)
|
|
515
|
+
return false;
|
|
516
|
+
if (f.fragmentKind === 'chain' && isFluentChain(f.names))
|
|
517
|
+
return false;
|
|
518
|
+
return true;
|
|
519
|
+
});
|
|
520
|
+
const deduped = dedupeShapeFragments(eligible);
|
|
521
|
+
const reported = new Set();
|
|
522
|
+
const findings = [];
|
|
523
|
+
for (let j = 1; j < deduped.length; j++) {
|
|
524
|
+
if (reported.has(j))
|
|
525
|
+
continue;
|
|
526
|
+
for (let i = 0; i < j; i++) {
|
|
527
|
+
if (deduped[i].fragmentKind !== deduped[j].fragmentKind)
|
|
528
|
+
continue;
|
|
529
|
+
if (deduped[i].target !== deduped[j].target)
|
|
530
|
+
continue;
|
|
531
|
+
const shared = longestCommonSubsequence(deduped[i].names, deduped[j].names);
|
|
532
|
+
if (shared.length < min)
|
|
533
|
+
continue;
|
|
534
|
+
findings.push(buildSimilarityViolation(deduped[j], deduped[i], shared));
|
|
535
|
+
reported.add(j);
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return findings;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* The legacy `computeJaccardSimilarity` (UniversalDRYAnalyzer.ts) — a bare
|
|
543
|
+
* token-SET Jaccard over the whitespace-split skeleton. The migrated
|
|
544
|
+
* `dry/structural-similarity` rule deliberately uses a *bigram* Jaccard
|
|
545
|
+
* (`computeJaccardSimilarity` above), but the seed write must reproduce the
|
|
546
|
+
* *legacy* `dry_pair_history` series byte-for-byte, so it re-homes the legacy
|
|
547
|
+
* bare-token-set metric rather than the migrated bigram.
|
|
548
|
+
*/
|
|
549
|
+
function computeBareTokenJaccard(text1, text2) {
|
|
550
|
+
const tokens1 = new Set(text1.split(/\s+/).filter(Boolean));
|
|
551
|
+
const tokens2 = new Set(text2.split(/\s+/).filter(Boolean));
|
|
552
|
+
let intersection = 0;
|
|
553
|
+
for (const t of tokens1) {
|
|
554
|
+
if (tokens2.has(t))
|
|
555
|
+
intersection++;
|
|
556
|
+
}
|
|
557
|
+
const union = tokens1.size + tokens2.size - intersection;
|
|
558
|
+
return union === 0 ? 0 : intersection / union;
|
|
559
|
+
}
|
|
560
|
+
/** The legacy order-independent pair identity: SHA256 of the sorted
|
|
561
|
+
* `file|nodeType|line` ids. */
|
|
562
|
+
function computePairFingerprint(original, block) {
|
|
563
|
+
const id1 = `${original.file}|${original.nodeType}|${original.start.line}`;
|
|
564
|
+
const id2 = `${block.file}|${block.nodeType}|${block.start.line}`;
|
|
565
|
+
const sorted = [id1, id2].sort();
|
|
566
|
+
return crypto.createHash('sha256').update(sorted.join('||')).digest('hex');
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Seed the `dry_pair_history` rows the legacy `createDryVisitor` accumulated,
|
|
570
|
+
* from the phase `code-block` fact. This re-homes the pair half of the legacy
|
|
571
|
+
* `analyzeAST` — per-file filter → dedupe → compare — over the projected data,
|
|
572
|
+
* and writes the *legacy* gates:
|
|
573
|
+
*
|
|
574
|
+
* - exact-duplicate pairs (`dry/duplicate`, similarity 1.0) always seed;
|
|
575
|
+
* - structural pairs (`dry/structural-similarity`) seed only when
|
|
576
|
+
* `checkStructuralSimilarity` is true, with the legacy bare-token-set Jaccard
|
|
577
|
+
* (not the migrated rule's bigram) and the legacy `similarityThreshold`.
|
|
578
|
+
*
|
|
579
|
+
* The three block *rules* re-apply `minLineThreshold`/`similarityThreshold` in
|
|
580
|
+
* `detectExactDuplicates`/`detectStructuralDuplicates`; the seed repeats the
|
|
581
|
+
* same per-file filter/dedupe so the written `(fingerprint, contentHash, line)`
|
|
582
|
+
* tuple is byte-identical to what the legacy visitor accumulated.
|
|
583
|
+
*
|
|
584
|
+
* @param codeBlocks - The assembled `code-block` corpus fact.
|
|
585
|
+
* @param config - The default-merged dry config (the rule's `resolveBlockConfig`).
|
|
586
|
+
* @returns The seeded pairs, in per-file walk order.
|
|
587
|
+
*/
|
|
588
|
+
export function seedDryPairs(codeBlocks, config) {
|
|
589
|
+
const minLine = config.minLineThreshold || 5;
|
|
590
|
+
const threshold = config.similarityThreshold ?? 0.85;
|
|
591
|
+
const pairs = [];
|
|
592
|
+
const seed = (original, block, similarity, rule) => {
|
|
593
|
+
pairs.push({
|
|
594
|
+
pairFingerprint: computePairFingerprint(original, block),
|
|
595
|
+
file1: original.file,
|
|
596
|
+
symbol1: `${original.nodeType}:${original.start.line}`,
|
|
597
|
+
line1: original.start.line,
|
|
598
|
+
contentHash1: original.hash,
|
|
599
|
+
file2: block.file,
|
|
600
|
+
symbol2: `${block.nodeType}:${block.start.line}`,
|
|
601
|
+
line2: block.start.line,
|
|
602
|
+
contentHash2: block.hash,
|
|
603
|
+
similarity,
|
|
604
|
+
rule,
|
|
605
|
+
});
|
|
606
|
+
};
|
|
607
|
+
for (const { blocks } of perFileGroups(codeBlocks, config.excludePatterns ?? []).values()) {
|
|
608
|
+
const large = blocks.filter((b) => b.lineCount >= minLine);
|
|
609
|
+
const deduped = deduplicateBlocks(large);
|
|
610
|
+
// Exact duplicates — group by hash, seed each later block against the earliest.
|
|
611
|
+
const byHash = new Map();
|
|
612
|
+
for (const block of deduped) {
|
|
613
|
+
const group = byHash.get(block.hash) ?? [];
|
|
614
|
+
group.push(block);
|
|
615
|
+
byHash.set(block.hash, group);
|
|
616
|
+
}
|
|
617
|
+
for (const group of byHash.values()) {
|
|
618
|
+
if (group.length < 2)
|
|
619
|
+
continue;
|
|
620
|
+
const sorted = [...group].sort(byFileAndLine);
|
|
621
|
+
const original = sorted[0];
|
|
622
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
623
|
+
const block = sorted[i];
|
|
624
|
+
if (spansOverlap(original, block))
|
|
625
|
+
continue;
|
|
626
|
+
seed(original, block, 1.0, 'dry/duplicate');
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
// Structural similarity — legacy-gated, bare-token-set Jaccard.
|
|
630
|
+
if (config.checkStructuralSimilarity) {
|
|
631
|
+
for (let i = 0; i < deduped.length; i++) {
|
|
632
|
+
const original = deduped[i];
|
|
633
|
+
for (let j = i + 1; j < deduped.length; j++) {
|
|
634
|
+
const block = deduped[j];
|
|
635
|
+
if (original.hash === block.hash)
|
|
636
|
+
continue;
|
|
637
|
+
if (spansOverlap(original, block))
|
|
638
|
+
continue;
|
|
639
|
+
const similarity = computeBareTokenJaccard(original.structuralSkeleton, block.structuralSkeleton);
|
|
640
|
+
if (similarity < threshold)
|
|
641
|
+
continue;
|
|
642
|
+
seed(original, block, similarity, 'dry/structural-similarity');
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return pairs;
|
|
648
|
+
}
|
|
649
|
+
/** The fallback the legacy auditRunner Phase 2 hardcoded when no divergence
|
|
650
|
+
* config was set (mirrors `DEFAULT_ANALYZER_CONFIGS.dry.divergence`). */
|
|
651
|
+
const DIVERGENCE_DEFAULTS = {
|
|
652
|
+
divergenceThreshold: 0.05,
|
|
653
|
+
divergenceRuns: 2,
|
|
654
|
+
minPairSimilarity: 0.5,
|
|
655
|
+
};
|
|
656
|
+
/** Re-homes auditRunner Phase 2 verbatim: flag a pair whose similarity fell by
|
|
657
|
+
* `divergenceThreshold` for `divergenceRuns` consecutive runs. The
|
|
658
|
+
* `clone-pair-history` fact is grouped by fingerprint with its series already
|
|
659
|
+
* in timestamp order, so the anchor (file/line) is the group's most recent row. */
|
|
660
|
+
function detectDivergingClone(facts, cfg) {
|
|
661
|
+
const threshold = cfg.divergenceThreshold ?? 0.05;
|
|
662
|
+
const requiredDeclines = cfg.divergenceRuns ?? 2;
|
|
663
|
+
if (threshold <= 0)
|
|
664
|
+
return [];
|
|
665
|
+
const findings = [];
|
|
666
|
+
for (const group of facts) {
|
|
667
|
+
const rows = group.rows;
|
|
668
|
+
if (rows.length < requiredDeclines + 1)
|
|
669
|
+
continue;
|
|
670
|
+
// Check the last `requiredDeclines` consecutive pairs for a decline.
|
|
671
|
+
let consecutiveDeclines = 0;
|
|
672
|
+
for (let i = rows.length - requiredDeclines; i < rows.length; i++) {
|
|
673
|
+
if (rows[i].similarity < rows[i - 1].similarity - threshold) {
|
|
674
|
+
consecutiveDeclines++;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
if (consecutiveDeclines >= requiredDeclines) {
|
|
678
|
+
const currentSim = rows[rows.length - 1].similarity;
|
|
679
|
+
const prevSim = rows[rows.length - 2].similarity;
|
|
680
|
+
const drop = Math.round((prevSim - currentSim) * 1000) / 1000;
|
|
681
|
+
const fp = group.fingerprint;
|
|
682
|
+
findings.push({
|
|
683
|
+
ruleId: 'dry/diverging-clone',
|
|
684
|
+
severity: 'severe',
|
|
685
|
+
message: `Clone pair has diverged: similarity dropped ${drop} (from ${prevSim.toFixed(3)} to ${currentSim.toFixed(3)}) across ${requiredDeclines} consecutive runs (pair: ${fp.slice(0, 12)}…). Review ${group.file1}:${group.line1} and ${group.file2}:${group.line2} for diverged logic.`,
|
|
686
|
+
file: group.file1,
|
|
687
|
+
line: group.line1,
|
|
688
|
+
// §7 — the pair fingerprint is the stable identity that located this finding.
|
|
689
|
+
symbol: fp,
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
return findings;
|
|
694
|
+
}
|
|
695
|
+
// ── The rules ─────────────────────────────────────────────────────────────────
|
|
696
|
+
const duplicateImport = {
|
|
697
|
+
id: 'duplicate-import',
|
|
698
|
+
analyzer: 'dry',
|
|
699
|
+
needs: { formats: ['typescript', 'tsx', 'javascript'], facts: ['imports'] },
|
|
700
|
+
severity: 'high',
|
|
701
|
+
message: META.message,
|
|
702
|
+
docs: META.docs,
|
|
703
|
+
thresholds: META.thresholds,
|
|
704
|
+
samples: META.samples,
|
|
705
|
+
analyze(ctx) {
|
|
706
|
+
return detectDuplicateImport(ctx.facts['imports']);
|
|
707
|
+
},
|
|
708
|
+
};
|
|
709
|
+
const duplicateStringLiteral = {
|
|
710
|
+
id: 'duplicate-string-literal',
|
|
711
|
+
analyzer: 'dry',
|
|
712
|
+
needs: { formats: ['typescript', 'tsx', 'javascript'], facts: ['string-literals'] },
|
|
713
|
+
severity: 'high',
|
|
714
|
+
message: STRING_META.message,
|
|
715
|
+
docs: STRING_META.docs,
|
|
716
|
+
thresholds: STRING_META.thresholds,
|
|
717
|
+
samples: STRING_META.samples,
|
|
718
|
+
analyze(ctx) {
|
|
719
|
+
return detectDuplicateStringLiteral(ctx.facts['string-literals']);
|
|
720
|
+
},
|
|
721
|
+
};
|
|
722
|
+
const dryDuplicate = {
|
|
723
|
+
id: 'dry/duplicate',
|
|
724
|
+
analyzer: 'dry',
|
|
725
|
+
needs: { formats: ['typescript', 'tsx', 'javascript'], facts: ['code-block'] },
|
|
726
|
+
severity: 'high',
|
|
727
|
+
message: DUP_META.message,
|
|
728
|
+
docs: DUP_META.docs,
|
|
729
|
+
thresholds: DUP_META.thresholds,
|
|
730
|
+
samples: DUP_META.samples,
|
|
731
|
+
analyze(ctx) {
|
|
732
|
+
const cfg = resolveBlockConfig(ctx.thresholds);
|
|
733
|
+
const findings = [];
|
|
734
|
+
for (const { blocks } of perFileGroups(ctx.facts['code-block'], cfg.excludePatterns ?? []).values()) {
|
|
735
|
+
findings.push(...detectExactDuplicates(blocks, cfg));
|
|
736
|
+
}
|
|
737
|
+
return findings;
|
|
738
|
+
},
|
|
739
|
+
};
|
|
740
|
+
const dryStructuralSimilarity = {
|
|
741
|
+
id: 'dry/structural-similarity',
|
|
742
|
+
analyzer: 'dry',
|
|
743
|
+
needs: { formats: ['typescript', 'tsx', 'javascript'], facts: ['code-block'] },
|
|
744
|
+
severity: 'high',
|
|
745
|
+
message: STRUCT_META.message,
|
|
746
|
+
docs: STRUCT_META.docs,
|
|
747
|
+
thresholds: STRUCT_META.thresholds,
|
|
748
|
+
samples: STRUCT_META.samples,
|
|
749
|
+
analyze(ctx) {
|
|
750
|
+
const cfg = resolveBlockConfig(ctx.thresholds);
|
|
751
|
+
const findings = [];
|
|
752
|
+
for (const { blocks } of perFileGroups(ctx.facts['code-block'], cfg.excludePatterns ?? []).values()) {
|
|
753
|
+
findings.push(...detectStructuralDuplicates(blocks, cfg));
|
|
754
|
+
}
|
|
755
|
+
return findings;
|
|
756
|
+
},
|
|
757
|
+
};
|
|
758
|
+
const drySimilarExpression = {
|
|
759
|
+
id: 'dry/similar-expression',
|
|
760
|
+
analyzer: 'dry',
|
|
761
|
+
needs: { formats: ['typescript', 'tsx', 'javascript'], facts: ['code-block'] },
|
|
762
|
+
severity: 'high',
|
|
763
|
+
message: EXPR_META.message,
|
|
764
|
+
docs: EXPR_META.docs,
|
|
765
|
+
thresholds: EXPR_META.thresholds,
|
|
766
|
+
samples: EXPR_META.samples,
|
|
767
|
+
analyze(ctx) {
|
|
768
|
+
const cfg = resolveBlockConfig(ctx.thresholds);
|
|
769
|
+
const findings = [];
|
|
770
|
+
for (const { fragments } of perFileGroups(ctx.facts['code-block'], cfg.excludePatterns ?? []).values()) {
|
|
771
|
+
findings.push(...detectExpressionSimilarities(fragments, cfg));
|
|
772
|
+
}
|
|
773
|
+
return findings;
|
|
774
|
+
},
|
|
775
|
+
};
|
|
776
|
+
const divergingClone = {
|
|
777
|
+
id: 'dry/diverging-clone',
|
|
778
|
+
analyzer: 'dry',
|
|
779
|
+
needs: { formats: ['typescript', 'tsx', 'javascript'], facts: ['clone-pair-history'] },
|
|
780
|
+
severity: 'severe',
|
|
781
|
+
message: DIVERGING_META.message,
|
|
782
|
+
docs: DIVERGING_META.docs,
|
|
783
|
+
thresholds: DIVERGING_META.thresholds,
|
|
784
|
+
samples: DIVERGING_META.samples,
|
|
785
|
+
analyze(ctx) {
|
|
786
|
+
// The divergence knobs resolve the same way the legacy Phase 2 did: the
|
|
787
|
+
// dry namespace's `divergence` object, or the hardcoded fallback. The
|
|
788
|
+
// top-level `divergence` config is threaded into `dry.divergence` by the
|
|
789
|
+
// caller (§11.1), so `ctx.thresholds['divergence']` is the effective value.
|
|
790
|
+
const divergence = ctx.thresholds['divergence'] ?? DIVERGENCE_DEFAULTS;
|
|
791
|
+
return detectDivergingClone(ctx.facts['clone-pair-history'], divergence);
|
|
792
|
+
},
|
|
793
|
+
};
|
|
794
|
+
/** The DRY rules, in registry order. */
|
|
795
|
+
export const dryRules = [
|
|
796
|
+
duplicateImport,
|
|
797
|
+
duplicateStringLiteral,
|
|
798
|
+
dryDuplicate,
|
|
799
|
+
dryStructuralSimilarity,
|
|
800
|
+
drySimilarExpression,
|
|
801
|
+
divergingClone,
|
|
802
|
+
];
|
|
803
|
+
//# sourceMappingURL=dry.js.map
|