@optave/codegraph 3.13.0 → 3.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -34
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +38 -40
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/rules/b2.d.ts +7 -0
- package/dist/ast-analysis/rules/b2.d.ts.map +1 -0
- package/dist/ast-analysis/rules/b2.js +240 -0
- package/dist/ast-analysis/rules/b2.js.map +1 -0
- package/dist/ast-analysis/rules/b3.d.ts +6 -0
- package/dist/ast-analysis/rules/b3.d.ts.map +1 -0
- package/dist/ast-analysis/rules/b3.js +105 -0
- package/dist/ast-analysis/rules/b3.js.map +1 -0
- package/dist/ast-analysis/rules/b4.d.ts +9 -0
- package/dist/ast-analysis/rules/b4.d.ts.map +1 -0
- package/dist/ast-analysis/rules/b4.js +361 -0
- package/dist/ast-analysis/rules/b4.js.map +1 -0
- package/dist/ast-analysis/rules/b5.d.ts +4 -0
- package/dist/ast-analysis/rules/b5.d.ts.map +1 -0
- package/dist/ast-analysis/rules/b5.js +52 -0
- package/dist/ast-analysis/rules/b5.js.map +1 -0
- package/dist/ast-analysis/rules/c.d.ts +4 -0
- package/dist/ast-analysis/rules/c.d.ts.map +1 -0
- package/dist/ast-analysis/rules/c.js +143 -0
- package/dist/ast-analysis/rules/c.js.map +1 -0
- package/dist/ast-analysis/rules/index.d.ts.map +1 -1
- package/dist/ast-analysis/rules/index.js +34 -0
- package/dist/ast-analysis/rules/index.js.map +1 -1
- package/dist/ast-analysis/rules/javascript.d.ts.map +1 -1
- package/dist/ast-analysis/rules/javascript.js +3 -0
- package/dist/ast-analysis/rules/javascript.js.map +1 -1
- package/dist/ast-analysis/shared.d.ts.map +1 -1
- package/dist/ast-analysis/shared.js +2 -0
- package/dist/ast-analysis/shared.js.map +1 -1
- package/dist/ast-analysis/visitor-utils.d.ts +1 -0
- package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
- package/dist/ast-analysis/visitor-utils.js +5 -0
- package/dist/ast-analysis/visitor-utils.js.map +1 -1
- package/dist/ast-analysis/visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitor.js +60 -47
- package/dist/ast-analysis/visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/cfg-visitor.js +126 -76
- package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.js +27 -15
- package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.js +54 -21
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +137 -134
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/roles.d.ts.map +1 -1
- package/dist/cli/commands/roles.js +6 -1
- package/dist/cli/commands/roles.js.map +1 -1
- package/dist/db/better-sqlite3.d.ts +2 -1
- package/dist/db/better-sqlite3.d.ts.map +1 -1
- package/dist/db/better-sqlite3.js.map +1 -1
- package/dist/db/connection.d.ts +7 -1
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +20 -5
- package/dist/db/connection.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +68 -0
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/repository/build-stmts.d.ts.map +1 -1
- package/dist/db/repository/build-stmts.js +18 -0
- package/dist/db/repository/build-stmts.js.map +1 -1
- package/dist/db/repository/dataflow.d.ts +5 -0
- package/dist/db/repository/dataflow.d.ts.map +1 -1
- package/dist/db/repository/dataflow.js +14 -0
- package/dist/db/repository/dataflow.js.map +1 -1
- package/dist/db/repository/index.d.ts +1 -1
- package/dist/db/repository/index.d.ts.map +1 -1
- package/dist/db/repository/index.js +1 -1
- package/dist/db/repository/index.js.map +1 -1
- package/dist/db/repository/native-repository.d.ts.map +1 -1
- package/dist/db/repository/native-repository.js +47 -34
- package/dist/db/repository/native-repository.js.map +1 -1
- package/dist/domain/analysis/context.d.ts +2 -2
- package/dist/domain/analysis/dependencies.d.ts +2 -2
- package/dist/domain/analysis/diff-impact.d.ts +2 -2
- package/dist/domain/analysis/fn-impact.d.ts +3 -1
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
- package/dist/domain/analysis/fn-impact.js +4 -0
- package/dist/domain/analysis/fn-impact.js.map +1 -1
- package/dist/domain/analysis/implementations.d.ts +2 -2
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +32 -5
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/analysis/roles.d.ts +7 -1
- package/dist/domain/analysis/roles.d.ts.map +1 -1
- package/dist/domain/analysis/roles.js +16 -0
- package/dist/domain/analysis/roles.js.map +1 -1
- package/dist/domain/analysis/symbol-lookup.d.ts +4 -4
- package/dist/domain/graph/builder/call-resolver.d.ts +17 -5
- package/dist/domain/graph/builder/call-resolver.d.ts.map +1 -1
- package/dist/domain/graph/builder/call-resolver.js +85 -220
- package/dist/domain/graph/builder/call-resolver.js.map +1 -1
- package/dist/domain/graph/builder/context.d.ts +1 -0
- package/dist/domain/graph/builder/context.d.ts.map +1 -1
- package/dist/domain/graph/builder/context.js.map +1 -1
- package/dist/domain/graph/builder/helpers.d.ts +16 -1
- package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
- package/dist/domain/graph/builder/helpers.js +162 -72
- package/dist/domain/graph/builder/helpers.js.map +1 -1
- package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
- package/dist/domain/graph/builder/incremental.js +166 -97
- package/dist/domain/graph/builder/incremental.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +10 -4
- package/dist/domain/graph/builder/pipeline.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.js +496 -250
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/collect-files.js +10 -7
- package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.js +2 -1
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/native-orchestrator.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/native-orchestrator.js +895 -545
- package/dist/domain/graph/builder/stages/native-orchestrator.js.map +1 -1
- package/dist/domain/graph/resolver/points-to.d.ts.map +1 -1
- package/dist/domain/graph/resolver/points-to.js +105 -57
- package/dist/domain/graph/resolver/points-to.js.map +1 -1
- package/dist/domain/graph/resolver/strategy.d.ts +61 -0
- package/dist/domain/graph/resolver/strategy.d.ts.map +1 -0
- package/dist/domain/graph/resolver/strategy.js +222 -0
- package/dist/domain/graph/resolver/strategy.js.map +1 -0
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +16 -9
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts +12 -0
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +12 -2
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/queries.d.ts +1 -1
- package/dist/domain/queries.d.ts.map +1 -1
- package/dist/domain/queries.js +1 -1
- package/dist/domain/queries.js.map +1 -1
- package/dist/domain/wasm-worker-entry.js +3 -0
- package/dist/domain/wasm-worker-entry.js.map +1 -1
- package/dist/domain/wasm-worker-pool.d.ts.map +1 -1
- package/dist/domain/wasm-worker-pool.js +24 -5
- package/dist/domain/wasm-worker-pool.js.map +1 -1
- package/dist/domain/wasm-worker-protocol.d.ts +7 -0
- package/dist/domain/wasm-worker-protocol.d.ts.map +1 -1
- package/dist/extractors/dart.js +48 -3
- package/dist/extractors/dart.js.map +1 -1
- package/dist/extractors/groovy.js +62 -3
- package/dist/extractors/groovy.js.map +1 -1
- package/dist/extractors/helpers.d.ts +4 -2
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +5 -1
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/java.js +77 -1
- package/dist/extractors/java.js.map +1 -1
- package/dist/extractors/javascript.d.ts.map +1 -1
- package/dist/extractors/javascript.js +549 -163
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/kotlin.js +58 -3
- package/dist/extractors/kotlin.js.map +1 -1
- package/dist/extractors/objc.js +25 -2
- package/dist/extractors/objc.js.map +1 -1
- package/dist/extractors/scala.js +62 -2
- package/dist/extractors/scala.js.map +1 -1
- package/dist/extractors/swift.js +52 -3
- package/dist/extractors/swift.js.map +1 -1
- package/dist/features/audit.js +26 -23
- package/dist/features/audit.js.map +1 -1
- package/dist/features/boundaries.d.ts.map +1 -1
- package/dist/features/boundaries.js +12 -9
- package/dist/features/boundaries.js.map +1 -1
- package/dist/features/cfg.d.ts.map +1 -1
- package/dist/features/cfg.js +25 -18
- package/dist/features/cfg.js.map +1 -1
- package/dist/features/check.d.ts.map +1 -1
- package/dist/features/check.js +18 -5
- package/dist/features/check.js.map +1 -1
- package/dist/features/communities.d.ts +4 -2
- package/dist/features/communities.d.ts.map +1 -1
- package/dist/features/communities.js +6 -4
- package/dist/features/communities.js.map +1 -1
- package/dist/features/dataflow.d.ts +60 -0
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +530 -6
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/manifesto.d.ts.map +1 -1
- package/dist/features/manifesto.js +59 -72
- package/dist/features/manifesto.js.map +1 -1
- package/dist/features/sequence.d.ts.map +1 -1
- package/dist/features/sequence.js +27 -22
- package/dist/features/sequence.js.map +1 -1
- package/dist/features/snapshot.d.ts.map +1 -1
- package/dist/features/snapshot.js +36 -28
- package/dist/features/snapshot.js.map +1 -1
- package/dist/features/structure.d.ts.map +1 -1
- package/dist/features/structure.js +150 -62
- package/dist/features/structure.js.map +1 -1
- package/dist/features/triage.d.ts.map +1 -1
- package/dist/features/triage.js +18 -11
- package/dist/features/triage.js.map +1 -1
- package/dist/graph/algorithms/bfs.d.ts +1 -1
- package/dist/graph/algorithms/bfs.d.ts.map +1 -1
- package/dist/graph/algorithms/bfs.js +14 -13
- package/dist/graph/algorithms/bfs.js.map +1 -1
- package/dist/graph/algorithms/tarjan.d.ts.map +1 -1
- package/dist/graph/algorithms/tarjan.js +5 -0
- package/dist/graph/algorithms/tarjan.js.map +1 -1
- package/dist/graph/builders/dependency.js +28 -22
- package/dist/graph/builders/dependency.js.map +1 -1
- package/dist/graph/classifiers/roles.d.ts +10 -1
- package/dist/graph/classifiers/roles.d.ts.map +1 -1
- package/dist/graph/classifiers/roles.js +60 -6
- package/dist/graph/classifiers/roles.js.map +1 -1
- package/dist/infrastructure/config.d.ts +10 -0
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +31 -3
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/infrastructure/registry.d.ts +0 -7
- package/dist/infrastructure/registry.d.ts.map +1 -1
- package/dist/infrastructure/registry.js +29 -13
- package/dist/infrastructure/registry.js.map +1 -1
- package/dist/infrastructure/update-check.d.ts.map +1 -1
- package/dist/infrastructure/update-check.js +49 -31
- package/dist/infrastructure/update-check.js.map +1 -1
- package/dist/mcp/server.d.ts +2 -10
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/ast-query.d.ts +1 -1
- package/dist/mcp/tools/ast-query.d.ts.map +1 -1
- package/dist/mcp/tools/audit.d.ts +1 -1
- package/dist/mcp/tools/audit.d.ts.map +1 -1
- package/dist/mcp/tools/batch-query.d.ts +1 -1
- package/dist/mcp/tools/batch-query.d.ts.map +1 -1
- package/dist/mcp/tools/branch-compare.d.ts +1 -1
- package/dist/mcp/tools/branch-compare.d.ts.map +1 -1
- package/dist/mcp/tools/brief.d.ts +1 -1
- package/dist/mcp/tools/brief.d.ts.map +1 -1
- package/dist/mcp/tools/cfg.d.ts +1 -1
- package/dist/mcp/tools/cfg.d.ts.map +1 -1
- package/dist/mcp/tools/check.d.ts +1 -1
- package/dist/mcp/tools/check.d.ts.map +1 -1
- package/dist/mcp/tools/co-changes.d.ts +1 -1
- package/dist/mcp/tools/co-changes.d.ts.map +1 -1
- package/dist/mcp/tools/code-owners.d.ts +1 -1
- package/dist/mcp/tools/code-owners.d.ts.map +1 -1
- package/dist/mcp/tools/communities.d.ts +1 -1
- package/dist/mcp/tools/communities.d.ts.map +1 -1
- package/dist/mcp/tools/complexity.d.ts +1 -1
- package/dist/mcp/tools/complexity.d.ts.map +1 -1
- package/dist/mcp/tools/context.d.ts +1 -1
- package/dist/mcp/tools/context.d.ts.map +1 -1
- package/dist/mcp/tools/dataflow.d.ts +1 -1
- package/dist/mcp/tools/dataflow.d.ts.map +1 -1
- package/dist/mcp/tools/diff-impact.d.ts +1 -1
- package/dist/mcp/tools/diff-impact.d.ts.map +1 -1
- package/dist/mcp/tools/execution-flow.d.ts +1 -1
- package/dist/mcp/tools/execution-flow.d.ts.map +1 -1
- package/dist/mcp/tools/export-graph.d.ts +1 -1
- package/dist/mcp/tools/export-graph.d.ts.map +1 -1
- package/dist/mcp/tools/file-deps.d.ts +1 -1
- package/dist/mcp/tools/file-deps.d.ts.map +1 -1
- package/dist/mcp/tools/file-exports.d.ts +1 -1
- package/dist/mcp/tools/file-exports.d.ts.map +1 -1
- package/dist/mcp/tools/find-cycles.d.ts +1 -1
- package/dist/mcp/tools/find-cycles.d.ts.map +1 -1
- package/dist/mcp/tools/fn-impact.d.ts +1 -1
- package/dist/mcp/tools/fn-impact.d.ts.map +1 -1
- package/dist/mcp/tools/impact-analysis.d.ts +1 -1
- package/dist/mcp/tools/impact-analysis.d.ts.map +1 -1
- package/dist/mcp/tools/implementations.d.ts +1 -1
- package/dist/mcp/tools/implementations.d.ts.map +1 -1
- package/dist/mcp/tools/index.d.ts +2 -5
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/interfaces.d.ts +1 -1
- package/dist/mcp/tools/interfaces.d.ts.map +1 -1
- package/dist/mcp/tools/list-functions.d.ts +1 -1
- package/dist/mcp/tools/list-functions.d.ts.map +1 -1
- package/dist/mcp/tools/list-repos.d.ts +1 -1
- package/dist/mcp/tools/list-repos.d.ts.map +1 -1
- package/dist/mcp/tools/module-map.d.ts +1 -1
- package/dist/mcp/tools/module-map.d.ts.map +1 -1
- package/dist/mcp/tools/node-roles.d.ts +1 -1
- package/dist/mcp/tools/node-roles.d.ts.map +1 -1
- package/dist/mcp/tools/path.d.ts +1 -1
- package/dist/mcp/tools/path.d.ts.map +1 -1
- package/dist/mcp/tools/query.d.ts +1 -1
- package/dist/mcp/tools/query.d.ts.map +1 -1
- package/dist/mcp/tools/semantic-search.d.ts +1 -1
- package/dist/mcp/tools/semantic-search.d.ts.map +1 -1
- package/dist/mcp/tools/sequence.d.ts +1 -1
- package/dist/mcp/tools/sequence.d.ts.map +1 -1
- package/dist/mcp/tools/structure.d.ts +1 -1
- package/dist/mcp/tools/structure.d.ts.map +1 -1
- package/dist/mcp/tools/symbol-children.d.ts +1 -1
- package/dist/mcp/tools/symbol-children.d.ts.map +1 -1
- package/dist/mcp/tools/triage.d.ts +1 -1
- package/dist/mcp/tools/triage.d.ts.map +1 -1
- package/dist/mcp/tools/where.d.ts +1 -1
- package/dist/mcp/tools/where.d.ts.map +1 -1
- package/dist/mcp/types.d.ts +19 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +6 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/presentation/queries-cli/index.d.ts +1 -1
- package/dist/presentation/queries-cli/index.d.ts.map +1 -1
- package/dist/presentation/queries-cli/index.js +1 -1
- package/dist/presentation/queries-cli/index.js.map +1 -1
- package/dist/presentation/queries-cli/overview.d.ts +1 -0
- package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
- package/dist/presentation/queries-cli/overview.js +20 -1
- package/dist/presentation/queries-cli/overview.js.map +1 -1
- package/dist/presentation/queries-cli.d.ts +1 -1
- package/dist/presentation/queries-cli.d.ts.map +1 -1
- package/dist/presentation/queries-cli.js +1 -1
- package/dist/presentation/queries-cli.js.map +1 -1
- package/dist/presentation/viewer.d.ts.map +1 -1
- package/dist/presentation/viewer.js +45 -32
- package/dist/presentation/viewer.js.map +1 -1
- package/dist/shared/constants.d.ts +21 -0
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +25 -0
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/normalize.d.ts.map +1 -1
- package/dist/shared/normalize.js +12 -22
- package/dist/shared/normalize.js.map +1 -1
- package/dist/shared/paginate.d.ts +4 -17
- package/dist/shared/paginate.d.ts.map +1 -1
- package/dist/shared/paginate.js.map +1 -1
- package/dist/types.d.ts +76 -1
- package/dist/types.d.ts.map +1 -1
- package/grammars/tree-sitter-erlang.wasm +0 -0
- package/package.json +7 -7
- package/src/ast-analysis/engine.ts +43 -63
- package/src/ast-analysis/rules/b2.ts +263 -0
- package/src/ast-analysis/rules/b3.ts +127 -0
- package/src/ast-analysis/rules/b4.ts +378 -0
- package/src/ast-analysis/rules/b5.ts +65 -0
- package/src/ast-analysis/rules/c.ts +157 -0
- package/src/ast-analysis/rules/index.ts +34 -0
- package/src/ast-analysis/rules/javascript.ts +3 -0
- package/src/ast-analysis/shared.ts +2 -0
- package/src/ast-analysis/visitor-utils.ts +5 -0
- package/src/ast-analysis/visitor.ts +82 -52
- package/src/ast-analysis/visitors/cfg-visitor.ts +198 -84
- package/src/ast-analysis/visitors/complexity-visitor.ts +44 -16
- package/src/ast-analysis/visitors/dataflow-visitor.ts +68 -29
- package/src/cli/commands/config.ts +184 -184
- package/src/cli/commands/roles.ts +6 -1
- package/src/db/better-sqlite3.ts +5 -4
- package/src/db/connection.ts +23 -5
- package/src/db/index.ts +1 -0
- package/src/db/migrations.ts +68 -0
- package/src/db/repository/build-stmts.ts +30 -0
- package/src/db/repository/dataflow.ts +16 -0
- package/src/db/repository/index.ts +1 -1
- package/src/db/repository/native-repository.ts +56 -40
- package/src/domain/analysis/fn-impact.ts +4 -0
- package/src/domain/analysis/module-map.ts +38 -6
- package/src/domain/analysis/roles.ts +23 -0
- package/src/domain/graph/builder/call-resolver.ts +112 -232
- package/src/domain/graph/builder/context.ts +1 -0
- package/src/domain/graph/builder/helpers.ts +190 -72
- package/src/domain/graph/builder/incremental.ts +249 -120
- package/src/domain/graph/builder/pipeline.ts +11 -5
- package/src/domain/graph/builder/stages/build-edges.ts +696 -296
- package/src/domain/graph/builder/stages/collect-files.ts +12 -6
- package/src/domain/graph/builder/stages/detect-changes.ts +3 -1
- package/src/domain/graph/builder/stages/native-orchestrator.ts +1102 -590
- package/src/domain/graph/resolver/points-to.ts +182 -59
- package/src/domain/graph/resolver/strategy.ts +265 -0
- package/src/domain/graph/watcher.ts +19 -9
- package/src/domain/parser.ts +12 -2
- package/src/domain/queries.ts +1 -1
- package/src/domain/wasm-worker-entry.ts +3 -0
- package/src/domain/wasm-worker-pool.ts +28 -4
- package/src/domain/wasm-worker-protocol.ts +4 -0
- package/src/extractors/dart.ts +48 -3
- package/src/extractors/groovy.ts +62 -2
- package/src/extractors/helpers.ts +5 -2
- package/src/extractors/java.ts +80 -1
- package/src/extractors/javascript.ts +566 -161
- package/src/extractors/kotlin.ts +57 -3
- package/src/extractors/objc.ts +25 -1
- package/src/extractors/scala.ts +63 -1
- package/src/extractors/swift.ts +46 -3
- package/src/features/audit.ts +43 -34
- package/src/features/boundaries.ts +17 -9
- package/src/features/cfg.ts +31 -22
- package/src/features/check.ts +21 -5
- package/src/features/communities.ts +28 -19
- package/src/features/dataflow.ts +755 -6
- package/src/features/manifesto.ts +76 -75
- package/src/features/sequence.ts +29 -23
- package/src/features/snapshot.ts +36 -25
- package/src/features/structure.ts +185 -55
- package/src/features/triage.ts +28 -15
- package/src/graph/algorithms/bfs.ts +13 -12
- package/src/graph/algorithms/tarjan.ts +5 -0
- package/src/graph/builders/dependency.ts +35 -23
- package/src/graph/classifiers/roles.ts +74 -7
- package/src/infrastructure/config.ts +32 -3
- package/src/infrastructure/registry.ts +44 -20
- package/src/infrastructure/update-check.ts +55 -33
- package/src/mcp/server.ts +2 -8
- package/src/mcp/tools/ast-query.ts +1 -1
- package/src/mcp/tools/audit.ts +1 -1
- package/src/mcp/tools/batch-query.ts +1 -1
- package/src/mcp/tools/branch-compare.ts +1 -1
- package/src/mcp/tools/brief.ts +1 -1
- package/src/mcp/tools/cfg.ts +1 -1
- package/src/mcp/tools/check.ts +1 -1
- package/src/mcp/tools/co-changes.ts +1 -1
- package/src/mcp/tools/code-owners.ts +1 -1
- package/src/mcp/tools/communities.ts +1 -1
- package/src/mcp/tools/complexity.ts +1 -1
- package/src/mcp/tools/context.ts +1 -1
- package/src/mcp/tools/dataflow.ts +1 -1
- package/src/mcp/tools/diff-impact.ts +1 -1
- package/src/mcp/tools/execution-flow.ts +1 -1
- package/src/mcp/tools/export-graph.ts +1 -1
- package/src/mcp/tools/file-deps.ts +1 -1
- package/src/mcp/tools/file-exports.ts +1 -1
- package/src/mcp/tools/find-cycles.ts +1 -1
- package/src/mcp/tools/fn-impact.ts +1 -1
- package/src/mcp/tools/impact-analysis.ts +1 -1
- package/src/mcp/tools/implementations.ts +1 -1
- package/src/mcp/tools/index.ts +2 -5
- package/src/mcp/tools/interfaces.ts +1 -1
- package/src/mcp/tools/list-functions.ts +1 -1
- package/src/mcp/tools/list-repos.ts +1 -1
- package/src/mcp/tools/module-map.ts +1 -1
- package/src/mcp/tools/node-roles.ts +1 -1
- package/src/mcp/tools/path.ts +1 -1
- package/src/mcp/tools/query.ts +1 -1
- package/src/mcp/tools/semantic-search.ts +1 -1
- package/src/mcp/tools/sequence.ts +1 -1
- package/src/mcp/tools/structure.ts +1 -1
- package/src/mcp/tools/symbol-children.ts +1 -1
- package/src/mcp/tools/triage.ts +1 -1
- package/src/mcp/tools/where.ts +1 -1
- package/src/mcp/types.ts +21 -0
- package/src/presentation/queries-cli/index.ts +1 -1
- package/src/presentation/queries-cli/overview.ts +35 -1
- package/src/presentation/queries-cli.ts +1 -0
- package/src/presentation/viewer.ts +98 -87
- package/src/shared/constants.ts +26 -0
- package/src/shared/normalize.ts +13 -22
- package/src/shared/paginate.ts +4 -18
- package/src/types.ts +86 -1
package/src/db/migrations.ts
CHANGED
|
@@ -263,6 +263,74 @@ export const MIGRATIONS: Migration[] = [
|
|
|
263
263
|
CREATE INDEX IF NOT EXISTS idx_edges_technique ON edges(technique);
|
|
264
264
|
`,
|
|
265
265
|
},
|
|
266
|
+
{
|
|
267
|
+
version: 18,
|
|
268
|
+
up: `
|
|
269
|
+
CREATE TABLE IF NOT EXISTS dataflow_vertices (
|
|
270
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
271
|
+
func_id INTEGER NOT NULL REFERENCES nodes(id),
|
|
272
|
+
kind TEXT NOT NULL,
|
|
273
|
+
name TEXT,
|
|
274
|
+
param_index INTEGER,
|
|
275
|
+
line INTEGER,
|
|
276
|
+
node_id INTEGER REFERENCES nodes(id)
|
|
277
|
+
);
|
|
278
|
+
CREATE INDEX IF NOT EXISTS idx_dfv_func ON dataflow_vertices(func_id);
|
|
279
|
+
CREATE INDEX IF NOT EXISTS idx_dfv_func_kind ON dataflow_vertices(func_id, kind);
|
|
280
|
+
CREATE INDEX IF NOT EXISTS idx_dfv_node ON dataflow_vertices(node_id);
|
|
281
|
+
|
|
282
|
+
ALTER TABLE dataflow ADD COLUMN source_vertex INTEGER REFERENCES dataflow_vertices(id);
|
|
283
|
+
ALTER TABLE dataflow ADD COLUMN target_vertex INTEGER REFERENCES dataflow_vertices(id);
|
|
284
|
+
ALTER TABLE dataflow ADD COLUMN scope TEXT;
|
|
285
|
+
ALTER TABLE dataflow ADD COLUMN call_edge_id INTEGER REFERENCES edges(id);
|
|
286
|
+
|
|
287
|
+
CREATE INDEX IF NOT EXISTS idx_dataflow_sv ON dataflow(source_vertex);
|
|
288
|
+
CREATE INDEX IF NOT EXISTS idx_dataflow_tv ON dataflow(target_vertex);
|
|
289
|
+
CREATE INDEX IF NOT EXISTS idx_dataflow_scope ON dataflow(scope);
|
|
290
|
+
|
|
291
|
+
CREATE TABLE IF NOT EXISTS dataflow_summary (
|
|
292
|
+
func_id INTEGER NOT NULL REFERENCES nodes(id),
|
|
293
|
+
param_index INTEGER NOT NULL,
|
|
294
|
+
flows_to_return INTEGER NOT NULL DEFAULT 0,
|
|
295
|
+
is_mutated INTEGER NOT NULL DEFAULT 0,
|
|
296
|
+
PRIMARY KEY(func_id, param_index)
|
|
297
|
+
);
|
|
298
|
+
CREATE INDEX IF NOT EXISTS idx_dfs_func ON dataflow_summary(func_id);
|
|
299
|
+
|
|
300
|
+
-- dataflow_fn exposes only vertex-linked (v18+) interprocedural flows.
|
|
301
|
+
-- The INNER JOINs intentionally exclude pre-v18 rows where source_vertex
|
|
302
|
+
-- and target_vertex are NULL — this is NOT a backward-compat replacement
|
|
303
|
+
-- for querying the dataflow table directly; legacy consumers must continue
|
|
304
|
+
-- to query dataflow directly to avoid silently dropping historical rows.
|
|
305
|
+
CREATE VIEW IF NOT EXISTS dataflow_fn AS
|
|
306
|
+
SELECT
|
|
307
|
+
sv.func_id AS source_id,
|
|
308
|
+
tv.func_id AS target_id,
|
|
309
|
+
d.kind,
|
|
310
|
+
d.param_index,
|
|
311
|
+
d.expression,
|
|
312
|
+
d.line,
|
|
313
|
+
d.confidence
|
|
314
|
+
FROM dataflow d
|
|
315
|
+
JOIN dataflow_vertices sv ON d.source_vertex = sv.id
|
|
316
|
+
JOIN dataflow_vertices tv ON d.target_vertex = tv.id
|
|
317
|
+
WHERE sv.func_id != tv.func_id;
|
|
318
|
+
`,
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
version: 19,
|
|
322
|
+
// P6 sentinel: forces a full rebuild so that databases built with the native
|
|
323
|
+
// fast path (which skipped vertex extraction before P6) backfill
|
|
324
|
+
// dataflow_vertices and dataflow_summary on the next `codegraph build`.
|
|
325
|
+
up: `SELECT 1`,
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
version: 20,
|
|
329
|
+
up: `
|
|
330
|
+
ALTER TABLE edges ADD COLUMN dynamic_kind TEXT;
|
|
331
|
+
CREATE INDEX IF NOT EXISTS idx_edges_dynamic_kind ON edges(dynamic_kind) WHERE dynamic_kind IS NOT NULL;
|
|
332
|
+
`,
|
|
333
|
+
},
|
|
266
334
|
];
|
|
267
335
|
|
|
268
336
|
interface PragmaColumnInfo {
|
|
@@ -5,6 +5,10 @@ interface PurgeStmts {
|
|
|
5
5
|
cfgEdges: SqliteStatement | null;
|
|
6
6
|
cfgBlocks: SqliteStatement | null;
|
|
7
7
|
dataflow: SqliteStatement | null;
|
|
8
|
+
dataflowByVertex: SqliteStatement | null;
|
|
9
|
+
dataflowByCallEdge: SqliteStatement | null;
|
|
10
|
+
dataflowSummary: SqliteStatement | null;
|
|
11
|
+
dataflowVertices: SqliteStatement | null;
|
|
8
12
|
complexity: SqliteStatement | null;
|
|
9
13
|
nodeMetrics: SqliteStatement | null;
|
|
10
14
|
astNodes: SqliteStatement | null;
|
|
@@ -44,6 +48,26 @@ function preparePurgeStmts(db: BetterSqlite3Database): PurgeStmts {
|
|
|
44
48
|
dataflow: tryPrepare(
|
|
45
49
|
'DELETE FROM dataflow WHERE source_id IN (SELECT id FROM nodes WHERE file = ?) OR target_id IN (SELECT id FROM nodes WHERE file = ?)',
|
|
46
50
|
),
|
|
51
|
+
dataflowByVertex: tryPrepare(
|
|
52
|
+
`DELETE FROM dataflow WHERE source_vertex IN (SELECT id FROM dataflow_vertices WHERE func_id IN (SELECT id FROM nodes WHERE file = ?))
|
|
53
|
+
OR target_vertex IN (SELECT id FROM dataflow_vertices WHERE func_id IN (SELECT id FROM nodes WHERE file = ?))`,
|
|
54
|
+
),
|
|
55
|
+
// Delete dataflow rows whose call_edge_id references a calls edge that
|
|
56
|
+
// touches the deleted file (source or target). These rows are not caught by
|
|
57
|
+
// the source_id/target_id or vertex-based deletions above when the dataflow
|
|
58
|
+
// row's own nodes live in other files. Must run before the edges delete to
|
|
59
|
+
// avoid SQLITE_CONSTRAINT_FOREIGNKEY: dataflow.call_edge_id REFERENCES edges(id).
|
|
60
|
+
dataflowByCallEdge: tryPrepare(
|
|
61
|
+
`DELETE FROM dataflow WHERE call_edge_id IN
|
|
62
|
+
(SELECT id FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = @f)
|
|
63
|
+
OR target_id IN (SELECT id FROM nodes WHERE file = @f))`,
|
|
64
|
+
),
|
|
65
|
+
dataflowSummary: tryPrepare(
|
|
66
|
+
'DELETE FROM dataflow_summary WHERE func_id IN (SELECT id FROM nodes WHERE file = ?)',
|
|
67
|
+
),
|
|
68
|
+
dataflowVertices: tryPrepare(
|
|
69
|
+
'DELETE FROM dataflow_vertices WHERE func_id IN (SELECT id FROM nodes WHERE file = ?)',
|
|
70
|
+
),
|
|
47
71
|
complexity: tryPrepare(
|
|
48
72
|
'DELETE FROM function_complexity WHERE node_id IN (SELECT id FROM nodes WHERE file = ?)',
|
|
49
73
|
),
|
|
@@ -80,6 +104,12 @@ function runPurge(stmts: PurgeStmts, file: string, opts: PurgeOpts = {}): void {
|
|
|
80
104
|
stmts.cfgEdges?.run(file);
|
|
81
105
|
stmts.cfgBlocks?.run(file);
|
|
82
106
|
stmts.dataflow?.run(file, file);
|
|
107
|
+
stmts.dataflowByVertex?.run(file, file);
|
|
108
|
+
// Clear dataflow rows keyed by call_edge_id before deleting edges so the FK
|
|
109
|
+
// (dataflow.call_edge_id REFERENCES edges(id)) does not block the edge purge.
|
|
110
|
+
stmts.dataflowByCallEdge?.run({ f: file });
|
|
111
|
+
stmts.dataflowSummary?.run(file);
|
|
112
|
+
stmts.dataflowVertices?.run(file);
|
|
83
113
|
stmts.complexity?.run(file);
|
|
84
114
|
stmts.nodeMetrics?.run(file);
|
|
85
115
|
stmts.astNodes?.run(file);
|
|
@@ -3,6 +3,7 @@ import { cachedStmt } from './cached-stmt.js';
|
|
|
3
3
|
|
|
4
4
|
// ─── Statement caches (one prepared statement per db instance) ────────────
|
|
5
5
|
const _hasDataflowTableStmt: StmtCache<{ c: number }> = new WeakMap();
|
|
6
|
+
const _hasDataflowVerticesStmt: StmtCache<{ c: number }> = new WeakMap();
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Check whether the dataflow table exists and has data.
|
|
@@ -17,3 +18,18 @@ export function hasDataflowTable(db: BetterSqlite3Database): boolean {
|
|
|
17
18
|
return false;
|
|
18
19
|
}
|
|
19
20
|
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Check whether the dataflow_vertices table exists and has data.
|
|
24
|
+
* Returns false on DBs built before migration v18.
|
|
25
|
+
*/
|
|
26
|
+
export function hasDataflowVertices(db: BetterSqlite3Database): boolean {
|
|
27
|
+
try {
|
|
28
|
+
return (
|
|
29
|
+
(cachedStmt(_hasDataflowVerticesStmt, db, 'SELECT COUNT(*) AS c FROM dataflow_vertices').get()
|
|
30
|
+
?.c ?? 0) > 0
|
|
31
|
+
);
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -7,7 +7,7 @@ export { cachedStmt } from './cached-stmt.js';
|
|
|
7
7
|
export { deleteCfgForNode, getCfgBlocks, getCfgEdges, hasCfgTables } from './cfg.js';
|
|
8
8
|
export { getCoChangeMeta, hasCoChanges, upsertCoChangeMeta } from './cochange.js';
|
|
9
9
|
export { getComplexityForNode } from './complexity.js';
|
|
10
|
-
export { hasDataflowTable } from './dataflow.js';
|
|
10
|
+
export { hasDataflowTable, hasDataflowVertices } from './dataflow.js';
|
|
11
11
|
export {
|
|
12
12
|
countCrossFileCallers,
|
|
13
13
|
findAllIncomingEdges,
|
|
@@ -163,6 +163,61 @@ function toComplexityMetrics(r: NativeComplexityMetrics): ComplexityMetrics {
|
|
|
163
163
|
};
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
// ── fnDeps conversion helpers ────────────────────────────────────────────
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Convert a native transitive-callers array (array of `{ depth, callers[] }`)
|
|
170
|
+
* into the JS `Record<number, FnDepsNode[]>` shape the Repository interface expects.
|
|
171
|
+
*/
|
|
172
|
+
function mapTransitiveCallers(groups: any[]): Record<number, FnDepsNode[]> {
|
|
173
|
+
const result: Record<number, FnDepsNode[]> = {};
|
|
174
|
+
for (const group of groups ?? []) {
|
|
175
|
+
result[group.depth] = (group.callers ?? []).map(
|
|
176
|
+
(c: any): FnDepsNode => ({
|
|
177
|
+
name: c.name,
|
|
178
|
+
kind: c.kind,
|
|
179
|
+
file: c.file,
|
|
180
|
+
line: c.line ?? null,
|
|
181
|
+
}),
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Convert a single raw native fnDeps entry into the typed `FnDepsEntry` shape.
|
|
189
|
+
* Handles napi-rs camelCase → Repository snake_case field aliasing.
|
|
190
|
+
*/
|
|
191
|
+
function mapFnDepsEntry(entry: any): FnDepsEntry {
|
|
192
|
+
return {
|
|
193
|
+
name: entry.name,
|
|
194
|
+
kind: entry.kind,
|
|
195
|
+
file: entry.file,
|
|
196
|
+
line: entry.line ?? null,
|
|
197
|
+
endLine: entry.endLine ?? entry.end_line ?? null,
|
|
198
|
+
role: entry.role ?? null,
|
|
199
|
+
fileHash: entry.fileHash ?? entry.file_hash ?? null,
|
|
200
|
+
callees: (entry.callees ?? []).map(
|
|
201
|
+
(c: any): FnDepsNode => ({
|
|
202
|
+
name: c.name,
|
|
203
|
+
kind: c.kind,
|
|
204
|
+
file: c.file,
|
|
205
|
+
line: c.line ?? null,
|
|
206
|
+
}),
|
|
207
|
+
),
|
|
208
|
+
callers: (entry.callers ?? []).map(
|
|
209
|
+
(c: any): FnDepsCallerNode => ({
|
|
210
|
+
name: c.name,
|
|
211
|
+
kind: c.kind,
|
|
212
|
+
file: c.file,
|
|
213
|
+
line: c.line ?? null,
|
|
214
|
+
viaHierarchy: c.viaHierarchy ?? c.via_hierarchy ?? undefined,
|
|
215
|
+
}),
|
|
216
|
+
),
|
|
217
|
+
transitiveCallers: mapTransitiveCallers(entry.transitiveCallers),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
166
221
|
// ── NativeRepository ────────────────────────────────────────────────────
|
|
167
222
|
|
|
168
223
|
export class NativeRepository extends Repository {
|
|
@@ -485,46 +540,7 @@ export class NativeRepository extends Repository {
|
|
|
485
540
|
// to JS format (transitiveCallers as Record<number, Array>)
|
|
486
541
|
return {
|
|
487
542
|
name: raw.name,
|
|
488
|
-
results: raw.results.map(
|
|
489
|
-
const transitiveCallers: Record<number, FnDepsNode[]> = {};
|
|
490
|
-
for (const group of entry.transitiveCallers ?? []) {
|
|
491
|
-
transitiveCallers[group.depth] = (group.callers ?? []).map(
|
|
492
|
-
(c: any): FnDepsNode => ({
|
|
493
|
-
name: c.name,
|
|
494
|
-
kind: c.kind,
|
|
495
|
-
file: c.file,
|
|
496
|
-
line: c.line ?? null,
|
|
497
|
-
}),
|
|
498
|
-
);
|
|
499
|
-
}
|
|
500
|
-
return {
|
|
501
|
-
name: entry.name,
|
|
502
|
-
kind: entry.kind,
|
|
503
|
-
file: entry.file,
|
|
504
|
-
line: entry.line ?? null,
|
|
505
|
-
endLine: entry.endLine ?? entry.end_line ?? null,
|
|
506
|
-
role: entry.role ?? null,
|
|
507
|
-
fileHash: entry.fileHash ?? entry.file_hash ?? null,
|
|
508
|
-
callees: (entry.callees ?? []).map(
|
|
509
|
-
(c: any): FnDepsNode => ({
|
|
510
|
-
name: c.name,
|
|
511
|
-
kind: c.kind,
|
|
512
|
-
file: c.file,
|
|
513
|
-
line: c.line ?? null,
|
|
514
|
-
}),
|
|
515
|
-
),
|
|
516
|
-
callers: (entry.callers ?? []).map(
|
|
517
|
-
(c: any): FnDepsCallerNode => ({
|
|
518
|
-
name: c.name,
|
|
519
|
-
kind: c.kind,
|
|
520
|
-
file: c.file,
|
|
521
|
-
line: c.line ?? null,
|
|
522
|
-
viaHierarchy: c.viaHierarchy ?? c.via_hierarchy ?? undefined,
|
|
523
|
-
}),
|
|
524
|
-
),
|
|
525
|
-
transitiveCallers,
|
|
526
|
-
};
|
|
527
|
-
}),
|
|
543
|
+
results: raw.results.map(mapFnDepsEntry),
|
|
528
544
|
};
|
|
529
545
|
}
|
|
530
546
|
}
|
|
@@ -294,10 +294,14 @@ export function fnImpactData(
|
|
|
294
294
|
maxDepth,
|
|
295
295
|
includeImplementors,
|
|
296
296
|
});
|
|
297
|
+
const direct = levels[1]?.length ?? 0;
|
|
298
|
+
const transitive = totalDependents - direct;
|
|
297
299
|
return {
|
|
298
300
|
...normalizeSymbol(node, repo, hc),
|
|
299
301
|
levels,
|
|
300
302
|
totalDependents,
|
|
303
|
+
direct,
|
|
304
|
+
transitive,
|
|
301
305
|
};
|
|
302
306
|
});
|
|
303
307
|
|
|
@@ -211,12 +211,20 @@ function computeQualityMetrics(
|
|
|
211
211
|
const totalCallEdges = (
|
|
212
212
|
db.prepare("SELECT COUNT(*) as c FROM edges WHERE kind = 'calls'").get() as { c: number }
|
|
213
213
|
).c;
|
|
214
|
+
// Exclude sink edges (confidence=0.0) from the confidence ratio: they flag
|
|
215
|
+
// unresolvable dynamic calls (eval/computed-key) and are not resolution
|
|
216
|
+
// attempts — including them in the denominator unfairly penalises the metric.
|
|
217
|
+
const resolvedCallEdges = (
|
|
218
|
+
db.prepare("SELECT COUNT(*) as c FROM edges WHERE kind = 'calls' AND confidence > 0").get() as {
|
|
219
|
+
c: number;
|
|
220
|
+
}
|
|
221
|
+
).c;
|
|
214
222
|
const highConfCallEdges = (
|
|
215
223
|
db
|
|
216
224
|
.prepare("SELECT COUNT(*) as c FROM edges WHERE kind = 'calls' AND confidence >= 0.7")
|
|
217
225
|
.get() as { c: number }
|
|
218
226
|
).c;
|
|
219
|
-
const callConfidence =
|
|
227
|
+
const callConfidence = resolvedCallEdges > 0 ? highConfCallEdges / resolvedCallEdges : 0;
|
|
220
228
|
|
|
221
229
|
const falsePositiveWarnings = buildFalsePositiveWarnings(queryFalsePositiveRows(db, fpThreshold));
|
|
222
230
|
|
|
@@ -239,7 +247,7 @@ function computeQualityMetrics(
|
|
|
239
247
|
callConfidence: {
|
|
240
248
|
ratio: callConfidence,
|
|
241
249
|
highConf: highConfCallEdges,
|
|
242
|
-
total:
|
|
250
|
+
total: resolvedCallEdges,
|
|
243
251
|
},
|
|
244
252
|
falsePositiveWarnings,
|
|
245
253
|
};
|
|
@@ -373,11 +381,29 @@ function queryFalsePositiveRows(
|
|
|
373
381
|
.all(fpThreshold) as FalsePositiveRow[];
|
|
374
382
|
}
|
|
375
383
|
|
|
384
|
+
/**
|
|
385
|
+
* Returns true when a high-caller-count row is a known structural false positive
|
|
386
|
+
* that should be silently excluded from warnings.
|
|
387
|
+
*
|
|
388
|
+
* Rust `::new()` methods (kind = method, local name = "new", file ends in ".rs")
|
|
389
|
+
* are conventional constructors — their high call counts are expected and carry
|
|
390
|
+
* no architectural signal. Any pattern-based exclusion should be added here
|
|
391
|
+
* rather than hardcoding specific symbol names.
|
|
392
|
+
*/
|
|
393
|
+
function isStructuralFalsePositive(r: FalsePositiveRow): boolean {
|
|
394
|
+
const localName = r.name.includes('.') ? r.name.split('.').pop()! : r.name;
|
|
395
|
+
// Rust ::new() constructors are always high-caller by design.
|
|
396
|
+
if (localName === 'new' && r.file.endsWith('.rs')) return true;
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
|
|
376
400
|
/** Filter false-positive rows by the configured name set and shape them for the report. */
|
|
377
401
|
function buildFalsePositiveWarnings(rows: FalsePositiveRow[]) {
|
|
378
402
|
return rows
|
|
379
|
-
.filter(
|
|
380
|
-
|
|
403
|
+
.filter(
|
|
404
|
+
(r) =>
|
|
405
|
+
!isStructuralFalsePositive(r) &&
|
|
406
|
+
FALSE_POSITIVE_NAMES.has(r.name.includes('.') ? r.name.split('.').pop()! : r.name),
|
|
381
407
|
)
|
|
382
408
|
.map((r) => ({ name: r.name, file: r.file, line: r.line, callerCount: r.caller_count }));
|
|
383
409
|
}
|
|
@@ -427,15 +453,21 @@ function buildStatsFromNative(
|
|
|
427
453
|
|
|
428
454
|
const callerCoverage =
|
|
429
455
|
s.quality.callableTotal > 0 ? s.quality.callableWithCallers / s.quality.callableTotal : 0;
|
|
456
|
+
// s.quality.callEdges is now the resolved (confidence>0) edge count — sink
|
|
457
|
+
// edges (confidence=0.0) are excluded so they don't dilute the ratio.
|
|
430
458
|
const callConfidence =
|
|
431
459
|
s.quality.callEdges > 0 ? s.quality.highConfCallEdges / s.quality.callEdges : 0;
|
|
432
460
|
|
|
433
|
-
// False-positive analysis still uses JS (needs FALSE_POSITIVE_NAMES set)
|
|
461
|
+
// False-positive analysis still uses JS (needs FALSE_POSITIVE_NAMES set).
|
|
462
|
+
// FP ratio uses the total calls count as denominator. When edgesByKind['calls']
|
|
463
|
+
// is undefined there are no call edges at all, so fpEdgeCount is 0 and the
|
|
464
|
+
// > 0 guard below returns 0 regardless — use 0 as the safe fallback.
|
|
465
|
+
const totalCallEdgesForFp = edgesByKind.calls ?? 0;
|
|
434
466
|
const fpThreshold = config.analysis?.falsePositiveCallers ?? FALSE_POSITIVE_CALLER_THRESHOLD;
|
|
435
467
|
const falsePositiveWarnings = buildFalsePositiveWarnings(queryFalsePositiveRows(db, fpThreshold));
|
|
436
468
|
let fpEdgeCount = 0;
|
|
437
469
|
for (const fp of falsePositiveWarnings) fpEdgeCount += fp.callerCount;
|
|
438
|
-
const falsePositiveRatio =
|
|
470
|
+
const falsePositiveRatio = totalCallEdgesForFp > 0 ? fpEdgeCount / totalCallEdgesForFp : 0;
|
|
439
471
|
const score = computeQualityScore(callerCoverage, callConfidence, falsePositiveRatio);
|
|
440
472
|
const testFilter = testFilterSQL('n.file', noTests);
|
|
441
473
|
const byTechnique = countCallEdgesByTechnique(db, testFilter);
|
|
@@ -6,6 +6,29 @@ import { normalizeSymbol } from '../../shared/normalize.js';
|
|
|
6
6
|
import { paginateResult } from '../../shared/paginate.js';
|
|
7
7
|
import type { NodeRow } from '../../types.js';
|
|
8
8
|
|
|
9
|
+
export interface DynamicCallCount {
|
|
10
|
+
dynamic_kind: string;
|
|
11
|
+
count: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Return a count of flagged dynamic call sink edges, grouped by kind. */
|
|
15
|
+
export function dynamicCallsData(customDbPath: string): DynamicCallCount[] {
|
|
16
|
+
const db = openReadonlyOrFail(customDbPath);
|
|
17
|
+
try {
|
|
18
|
+
return db
|
|
19
|
+
.prepare(
|
|
20
|
+
`SELECT dynamic_kind, COUNT(*) AS count
|
|
21
|
+
FROM edges
|
|
22
|
+
WHERE dynamic_kind IS NOT NULL
|
|
23
|
+
GROUP BY dynamic_kind
|
|
24
|
+
ORDER BY count DESC`,
|
|
25
|
+
)
|
|
26
|
+
.all() as DynamicCallCount[];
|
|
27
|
+
} finally {
|
|
28
|
+
db.close();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
9
32
|
export function rolesData(
|
|
10
33
|
customDbPath: string,
|
|
11
34
|
opts: {
|