@optave/codegraph 3.4.0 → 3.5.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 +23 -22
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +3 -9
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/rules/javascript.d.ts.map +1 -1
- package/dist/ast-analysis/rules/javascript.js +1 -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 +0 -1
- package/dist/ast-analysis/shared.js.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/ast-store-visitor.js +103 -35
- package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/cfg-conditionals.d.ts +5 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.js +166 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-loops.d.ts +7 -0
- package/dist/ast-analysis/visitors/cfg-loops.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-loops.js +73 -0
- package/dist/ast-analysis/visitors/cfg-loops.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-shared.d.ts +56 -0
- package/dist/ast-analysis/visitors/cfg-shared.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-shared.js +107 -0
- package/dist/ast-analysis/visitors/cfg-shared.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.d.ts +4 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.js +100 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-visitor.d.ts +2 -2
- package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/cfg-visitor.js +11 -445
- 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.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
- package/dist/cli/commands/batch.d.ts.map +1 -1
- package/dist/cli/commands/batch.js +4 -3
- package/dist/cli/commands/batch.js.map +1 -1
- package/dist/cli/commands/branch-compare.js +1 -1
- package/dist/cli/commands/branch-compare.js.map +1 -1
- package/dist/cli/commands/build.js +1 -1
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/info.d.ts.map +1 -1
- package/dist/cli/commands/info.js +1 -2
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/cli/commands/path.d.ts.map +1 -1
- package/dist/cli/commands/path.js +7 -2
- package/dist/cli/commands/path.js.map +1 -1
- package/dist/cli/commands/plot.d.ts.map +1 -1
- package/dist/cli/commands/plot.js +2 -2
- package/dist/cli/commands/plot.js.map +1 -1
- package/dist/cli/commands/watch.js +1 -1
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/shared/open-graph.d.ts +2 -2
- package/dist/cli/shared/open-graph.d.ts.map +1 -1
- package/dist/cli/shared/open-graph.js.map +1 -1
- package/dist/cli/types.d.ts +1 -1
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli.js +2 -3
- package/dist/cli.js.map +1 -1
- package/dist/db/better-sqlite3.d.ts +3 -0
- package/dist/db/better-sqlite3.d.ts.map +1 -0
- package/dist/db/better-sqlite3.js +19 -0
- package/dist/db/better-sqlite3.js.map +1 -0
- package/dist/db/connection.d.ts +30 -2
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +167 -4
- package/dist/db/connection.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- 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 +9 -0
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/query-builder.d.ts +5 -5
- package/dist/db/query-builder.d.ts.map +1 -1
- package/dist/db/query-builder.js +20 -4
- package/dist/db/query-builder.js.map +1 -1
- package/dist/db/repository/index.d.ts +1 -0
- package/dist/db/repository/index.d.ts.map +1 -1
- package/dist/db/repository/index.js +1 -0
- package/dist/db/repository/index.js.map +1 -1
- package/dist/db/repository/native-repository.d.ts +58 -0
- package/dist/db/repository/native-repository.d.ts.map +1 -0
- package/dist/db/repository/native-repository.js +261 -0
- package/dist/db/repository/native-repository.js.map +1 -0
- package/dist/db/repository/nodes.d.ts +4 -4
- package/dist/db/repository/nodes.d.ts.map +1 -1
- package/dist/db/repository/nodes.js +6 -6
- package/dist/db/repository/nodes.js.map +1 -1
- package/dist/domain/analysis/brief.d.ts.map +1 -1
- package/dist/domain/analysis/brief.js +1 -3
- package/dist/domain/analysis/brief.js.map +1 -1
- package/dist/domain/analysis/context.d.ts.map +1 -1
- package/dist/domain/analysis/context.js +2 -4
- package/dist/domain/analysis/context.js.map +1 -1
- package/dist/domain/analysis/dependencies.d.ts +49 -0
- package/dist/domain/analysis/dependencies.d.ts.map +1 -1
- package/dist/domain/analysis/dependencies.js +145 -0
- package/dist/domain/analysis/dependencies.js.map +1 -1
- package/dist/domain/analysis/diff-impact.d.ts +76 -0
- package/dist/domain/analysis/diff-impact.d.ts.map +1 -0
- package/dist/domain/analysis/diff-impact.js +282 -0
- package/dist/domain/analysis/diff-impact.js.map +1 -0
- package/dist/domain/analysis/exports.d.ts.map +1 -1
- package/dist/domain/analysis/exports.js +0 -1
- package/dist/domain/analysis/exports.js.map +1 -1
- package/dist/domain/analysis/fn-impact.d.ts +66 -0
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -0
- package/dist/domain/analysis/fn-impact.js +189 -0
- package/dist/domain/analysis/fn-impact.js.map +1 -0
- package/dist/domain/analysis/impact.d.ts +8 -148
- package/dist/domain/analysis/impact.d.ts.map +1 -1
- package/dist/domain/analysis/impact.js +8 -568
- package/dist/domain/analysis/impact.js.map +1 -1
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +1 -3
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/graph/builder/context.d.ts +3 -3
- package/dist/domain/graph/builder/context.d.ts.map +1 -1
- package/dist/domain/graph/builder/context.js +1 -0
- package/dist/domain/graph/builder/context.js.map +1 -1
- package/dist/domain/graph/builder/helpers.d.ts +4 -5
- package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
- package/dist/domain/graph/builder/helpers.js +1 -2
- package/dist/domain/graph/builder/helpers.js.map +1 -1
- package/dist/domain/graph/builder/incremental.d.ts +2 -3
- package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
- 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 +34 -6
- 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 +113 -15
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-structure.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-structure.js +186 -62
- package/dist/domain/graph/builder/stages/build-structure.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 +71 -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 +42 -20
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +111 -64
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.js +104 -9
- package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js +58 -11
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/cycles.js +2 -2
- package/dist/domain/graph/cycles.js.map +1 -1
- package/dist/domain/graph/resolve.d.ts.map +1 -1
- package/dist/domain/graph/resolve.js +10 -8
- package/dist/domain/graph/resolve.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +1 -3
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +12 -12
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/queries.d.ts +3 -2
- package/dist/domain/queries.d.ts.map +1 -1
- package/dist/domain/queries.js +3 -2
- package/dist/domain/queries.js.map +1 -1
- package/dist/domain/search/generator.d.ts.map +1 -1
- package/dist/domain/search/generator.js.map +1 -1
- package/dist/extractors/csharp.js +2 -2
- package/dist/extractors/csharp.js.map +1 -1
- package/dist/extractors/go.js +2 -2
- package/dist/extractors/go.js.map +1 -1
- package/dist/extractors/helpers.d.ts +5 -0
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +5 -0
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/javascript.js +111 -98
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/php.js +2 -2
- package/dist/extractors/php.js.map +1 -1
- package/dist/extractors/python.js +2 -2
- package/dist/extractors/python.js.map +1 -1
- package/dist/extractors/rust.js +4 -3
- package/dist/extractors/rust.js.map +1 -1
- package/dist/features/ast.d.ts +14 -1
- package/dist/features/ast.d.ts.map +1 -1
- package/dist/features/ast.js +38 -1
- package/dist/features/ast.js.map +1 -1
- package/dist/features/audit.d.ts.map +1 -1
- package/dist/features/audit.js +1 -2
- package/dist/features/audit.js.map +1 -1
- package/dist/features/branch-compare.d.ts.map +1 -1
- package/dist/features/branch-compare.js +5 -4
- package/dist/features/branch-compare.js.map +1 -1
- package/dist/features/cfg.d.ts.map +1 -1
- package/dist/features/cfg.js +2 -4
- package/dist/features/cfg.js.map +1 -1
- package/dist/features/cochange.js +4 -4
- package/dist/features/cochange.js.map +1 -1
- package/dist/features/communities.js +4 -4
- package/dist/features/communities.js.map +1 -1
- package/dist/features/complexity-query.d.ts +37 -0
- package/dist/features/complexity-query.d.ts.map +1 -0
- package/dist/features/complexity-query.js +263 -0
- package/dist/features/complexity-query.js.map +1 -0
- package/dist/features/complexity.d.ts +2 -30
- package/dist/features/complexity.d.ts.map +1 -1
- package/dist/features/complexity.js +7 -261
- package/dist/features/complexity.js.map +1 -1
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +8 -24
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/export.d.ts +7 -8
- package/dist/features/export.d.ts.map +1 -1
- package/dist/features/export.js.map +1 -1
- package/dist/features/flow.d.ts.map +1 -1
- package/dist/features/flow.js.map +1 -1
- package/dist/features/graph-enrichment.d.ts.map +1 -1
- package/dist/features/graph-enrichment.js +1 -3
- package/dist/features/graph-enrichment.js.map +1 -1
- package/dist/features/manifesto.js +8 -8
- package/dist/features/manifesto.js.map +1 -1
- package/dist/features/snapshot.js +2 -2
- package/dist/features/snapshot.js.map +1 -1
- package/dist/features/structure-query.d.ts +76 -0
- package/dist/features/structure-query.d.ts.map +1 -0
- package/dist/features/structure-query.js +245 -0
- package/dist/features/structure-query.js.map +1 -0
- package/dist/features/structure.d.ts +12 -67
- package/dist/features/structure.d.ts.map +1 -1
- package/dist/features/structure.js +188 -244
- package/dist/features/structure.js.map +1 -1
- package/dist/features/triage.js +2 -2
- package/dist/features/triage.js.map +1 -1
- package/dist/graph/algorithms/leiden/adapter.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/adapter.js +2 -9
- package/dist/graph/algorithms/leiden/adapter.js.map +1 -1
- package/dist/graph/classifiers/roles.d.ts +5 -1
- package/dist/graph/classifiers/roles.d.ts.map +1 -1
- package/dist/graph/classifiers/roles.js +20 -12
- package/dist/graph/classifiers/roles.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +12 -11
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/infrastructure/native.d.ts.map +1 -1
- package/dist/infrastructure/native.js +7 -3
- package/dist/infrastructure/native.js.map +1 -1
- package/dist/infrastructure/registry.d.ts.map +1 -1
- package/dist/infrastructure/registry.js +1 -1
- package/dist/infrastructure/registry.js.map +1 -1
- package/dist/infrastructure/update-check.js +3 -3
- package/dist/infrastructure/update-check.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +4 -17
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-registry.d.ts.map +1 -1
- package/dist/mcp/tool-registry.js +9 -4
- package/dist/mcp/tool-registry.js.map +1 -1
- package/dist/mcp/tools/audit.js +1 -1
- package/dist/mcp/tools/audit.js.map +1 -1
- package/dist/mcp/tools/cfg.js +1 -1
- package/dist/mcp/tools/cfg.js.map +1 -1
- package/dist/mcp/tools/check.js +2 -2
- package/dist/mcp/tools/check.js.map +1 -1
- package/dist/mcp/tools/dataflow.js +2 -2
- package/dist/mcp/tools/dataflow.js.map +1 -1
- package/dist/mcp/tools/export-graph.js +1 -1
- package/dist/mcp/tools/export-graph.js.map +1 -1
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/path.d.ts +1 -0
- package/dist/mcp/tools/path.d.ts.map +1 -1
- package/dist/mcp/tools/path.js +9 -0
- package/dist/mcp/tools/path.js.map +1 -1
- package/dist/mcp/tools/query.js +1 -1
- package/dist/mcp/tools/query.js.map +1 -1
- package/dist/mcp/tools/semantic-search.js +1 -1
- package/dist/mcp/tools/semantic-search.js.map +1 -1
- package/dist/mcp/tools/sequence.js +1 -1
- package/dist/mcp/tools/sequence.js.map +1 -1
- package/dist/mcp/tools/symbol-children.js +1 -1
- package/dist/mcp/tools/symbol-children.js.map +1 -1
- package/dist/mcp/tools/triage.js +1 -1
- package/dist/mcp/tools/triage.js.map +1 -1
- package/dist/presentation/audit.d.ts.map +1 -1
- package/dist/presentation/audit.js +0 -1
- package/dist/presentation/audit.js.map +1 -1
- package/dist/presentation/diff-impact-mermaid.d.ts +11 -0
- package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -0
- package/dist/presentation/diff-impact-mermaid.js +105 -0
- package/dist/presentation/diff-impact-mermaid.js.map +1 -0
- package/dist/presentation/flow.d.ts.map +1 -1
- package/dist/presentation/flow.js +0 -2
- package/dist/presentation/flow.js.map +1 -1
- package/dist/presentation/manifesto.d.ts.map +1 -1
- package/dist/presentation/manifesto.js +0 -1
- package/dist/presentation/manifesto.js.map +1 -1
- package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
- package/dist/presentation/queries-cli/inspect.js.map +1 -1
- package/dist/presentation/queries-cli/path.d.ts.map +1 -1
- package/dist/presentation/queries-cli/path.js +45 -1
- package/dist/presentation/queries-cli/path.js.map +1 -1
- package/dist/presentation/result-formatter.d.ts.map +1 -1
- package/dist/presentation/result-formatter.js +1 -3
- package/dist/presentation/result-formatter.js.map +1 -1
- package/dist/presentation/sequence.d.ts.map +1 -1
- package/dist/presentation/sequence.js +0 -1
- package/dist/presentation/sequence.js.map +1 -1
- package/dist/presentation/structure.d.ts.map +1 -1
- package/dist/presentation/structure.js.map +1 -1
- package/dist/presentation/triage.d.ts.map +1 -1
- package/dist/presentation/triage.js +0 -1
- package/dist/presentation/triage.js.map +1 -1
- package/dist/shared/constants.d.ts +9 -3
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +6 -3
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/errors.d.ts +2 -0
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/errors.js +4 -0
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/version.d.ts +2 -0
- package/dist/shared/version.d.ts.map +1 -0
- package/dist/shared/version.js +5 -0
- package/dist/shared/version.js.map +1 -0
- package/dist/types.d.ts +230 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +62 -11
- package/src/ast-analysis/engine.ts +3 -9
- package/src/ast-analysis/rules/javascript.ts +1 -0
- package/src/ast-analysis/shared.ts +0 -1
- package/src/ast-analysis/visitors/ast-store-visitor.ts +102 -33
- package/src/ast-analysis/visitors/cfg-conditionals.ts +227 -0
- package/src/ast-analysis/visitors/cfg-loops.ts +136 -0
- package/src/ast-analysis/visitors/cfg-shared.ts +196 -0
- package/src/ast-analysis/visitors/cfg-try-catch.ts +142 -0
- package/src/ast-analysis/visitors/cfg-visitor.ts +34 -655
- package/src/ast-analysis/visitors/complexity-visitor.ts +0 -1
- package/src/ast-analysis/visitors/dataflow-visitor.ts +0 -1
- package/src/cli/commands/batch.ts +4 -3
- package/src/cli/commands/branch-compare.ts +1 -1
- package/src/cli/commands/build.ts +1 -1
- package/src/cli/commands/info.ts +1 -2
- package/src/cli/commands/path.ts +7 -2
- package/src/cli/commands/plot.ts +2 -2
- package/src/cli/commands/watch.ts +1 -1
- package/src/cli/index.ts +2 -2
- package/src/cli/shared/open-graph.ts +2 -2
- package/src/cli/types.ts +1 -1
- package/src/cli.ts +2 -3
- package/src/db/better-sqlite3.ts +20 -0
- package/src/db/connection.ts +191 -16
- package/src/db/index.ts +5 -1
- package/src/db/migrations.ts +9 -0
- package/src/db/query-builder.ts +30 -5
- package/src/db/repository/index.ts +1 -0
- package/src/db/repository/native-repository.ts +361 -0
- package/src/db/repository/nodes.ts +7 -3
- package/src/domain/analysis/brief.ts +0 -1
- package/src/domain/analysis/context.ts +2 -6
- package/src/domain/analysis/dependencies.ts +165 -0
- package/src/domain/analysis/diff-impact.ts +354 -0
- package/src/domain/analysis/exports.ts +0 -2
- package/src/domain/analysis/fn-impact.ts +241 -0
- package/src/domain/analysis/impact.ts +8 -718
- package/src/domain/analysis/module-map.ts +1 -5
- package/src/domain/graph/builder/context.ts +4 -2
- package/src/domain/graph/builder/helpers.ts +14 -11
- package/src/domain/graph/builder/incremental.ts +33 -28
- package/src/domain/graph/builder/pipeline.ts +37 -5
- package/src/domain/graph/builder/stages/build-edges.ts +131 -20
- package/src/domain/graph/builder/stages/build-structure.ts +245 -80
- package/src/domain/graph/builder/stages/collect-files.ts +84 -7
- package/src/domain/graph/builder/stages/detect-changes.ts +49 -32
- package/src/domain/graph/builder/stages/finalize.ts +132 -84
- package/src/domain/graph/builder/stages/insert-nodes.ts +141 -18
- package/src/domain/graph/builder/stages/resolve-imports.ts +75 -10
- package/src/domain/graph/cycles.ts +2 -2
- package/src/domain/graph/resolve.ts +14 -8
- package/src/domain/graph/watcher.ts +2 -4
- package/src/domain/parser.ts +12 -13
- package/src/domain/queries.ts +2 -2
- package/src/domain/search/generator.ts +3 -4
- package/src/extractors/csharp.ts +2 -2
- package/src/extractors/go.ts +2 -2
- package/src/extractors/helpers.ts +6 -0
- package/src/extractors/javascript.ts +112 -97
- package/src/extractors/php.ts +2 -2
- package/src/extractors/python.ts +2 -2
- package/src/extractors/rust.ts +4 -3
- package/src/features/ast.ts +66 -1
- package/src/features/audit.ts +1 -2
- package/src/features/branch-compare.ts +6 -10
- package/src/features/cfg.ts +2 -4
- package/src/features/cochange.ts +4 -4
- package/src/features/communities.ts +4 -4
- package/src/features/complexity-query.ts +370 -0
- package/src/features/complexity.ts +6 -365
- package/src/features/dataflow.ts +48 -70
- package/src/features/export.ts +12 -16
- package/src/features/flow.ts +0 -1
- package/src/features/graph-enrichment.ts +1 -3
- package/src/features/manifesto.ts +8 -8
- package/src/features/snapshot.ts +3 -3
- package/src/features/structure-query.ts +387 -0
- package/src/features/structure.ts +231 -376
- package/src/features/triage.ts +2 -2
- package/src/graph/algorithms/leiden/adapter.ts +2 -9
- package/src/graph/classifiers/roles.ts +22 -13
- package/src/index.ts +1 -0
- package/src/infrastructure/config.ts +12 -13
- package/src/infrastructure/native.ts +7 -3
- package/src/infrastructure/registry.ts +1 -1
- package/src/infrastructure/update-check.ts +3 -3
- package/src/mcp/server.ts +4 -20
- package/src/mcp/tool-registry.ts +11 -4
- package/src/mcp/tools/audit.ts +1 -1
- package/src/mcp/tools/cfg.ts +1 -1
- package/src/mcp/tools/check.ts +2 -2
- package/src/mcp/tools/dataflow.ts +2 -2
- package/src/mcp/tools/export-graph.ts +1 -1
- package/src/mcp/tools/index.ts +0 -1
- package/src/mcp/tools/path.ts +10 -0
- 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/symbol-children.ts +1 -1
- package/src/mcp/tools/triage.ts +1 -1
- package/src/presentation/audit.ts +0 -1
- package/src/presentation/diff-impact-mermaid.ts +127 -0
- package/src/presentation/flow.ts +0 -2
- package/src/presentation/manifesto.ts +0 -1
- package/src/presentation/queries-cli/inspect.ts +0 -1
- package/src/presentation/queries-cli/path.ts +71 -1
- package/src/presentation/result-formatter.ts +0 -1
- package/src/presentation/sequence.ts +0 -1
- package/src/presentation/structure.ts +0 -12
- package/src/presentation/triage.ts +0 -1
- package/src/shared/constants.ts +33 -19
- package/src/shared/errors.ts +5 -0
- package/src/shared/version.ts +10 -0
- package/src/types.ts +277 -10
- package/src/vendor.d.ts +0 -39
|
@@ -3,7 +3,7 @@ import { collectFile } from '../../db/query-builder.js';
|
|
|
3
3
|
import { EVERY_SYMBOL_KIND } from '../../domain/queries.js';
|
|
4
4
|
import { BATCH_COMMANDS, multiBatchData, splitTargets } from '../../features/batch.js';
|
|
5
5
|
import { batch } from '../../presentation/batch.js';
|
|
6
|
-
import { ConfigError } from '../../shared/errors.js';
|
|
6
|
+
import { ConfigError, toErrorMessage } from '../../shared/errors.js';
|
|
7
7
|
import type { CommandDefinition } from '../types.js';
|
|
8
8
|
|
|
9
9
|
interface MultiBatchItem {
|
|
@@ -58,8 +58,9 @@ export const command: CommandDefinition = {
|
|
|
58
58
|
targets = splitTargets(positionalTargets as unknown as string[]);
|
|
59
59
|
}
|
|
60
60
|
} catch (err: unknown) {
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
throw new ConfigError(`Failed to parse targets: ${toErrorMessage(err)}`, {
|
|
62
|
+
cause: err as Error,
|
|
63
|
+
});
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
if (!targets || targets.length === 0) {
|
|
@@ -13,7 +13,7 @@ export const command: CommandDefinition = {
|
|
|
13
13
|
async execute([base, target], opts, ctx) {
|
|
14
14
|
const { branchCompare } = await import('../../presentation/branch-compare.js');
|
|
15
15
|
await branchCompare(base!, target!, {
|
|
16
|
-
engine: ctx.program.opts()
|
|
16
|
+
engine: ctx.program.opts().engine,
|
|
17
17
|
depth: parseInt(opts.depth as string, 10),
|
|
18
18
|
noTests: ctx.resolveNoTests(opts),
|
|
19
19
|
json: opts.json,
|
|
@@ -15,7 +15,7 @@ export const command: CommandDefinition = {
|
|
|
15
15
|
],
|
|
16
16
|
async execute([dir], opts, ctx) {
|
|
17
17
|
const root = path.resolve(dir || '.');
|
|
18
|
-
const engine = ctx.program.opts()
|
|
18
|
+
const engine = ctx.program.opts().engine;
|
|
19
19
|
await buildGraph(root, {
|
|
20
20
|
incremental: opts.incremental as boolean,
|
|
21
21
|
ast: opts.ast as boolean,
|
package/src/cli/commands/info.ts
CHANGED
|
@@ -9,7 +9,7 @@ export const command: CommandDefinition = {
|
|
|
9
9
|
);
|
|
10
10
|
const { getActiveEngine } = await import('../../domain/parser.js');
|
|
11
11
|
|
|
12
|
-
const engine = ctx.program.opts()
|
|
12
|
+
const engine = ctx.program.opts().engine;
|
|
13
13
|
const { name: activeName, version: activeVersion } = getActiveEngine({ engine });
|
|
14
14
|
const nativeAvailable = isNativeAvailable();
|
|
15
15
|
|
|
@@ -43,7 +43,6 @@ export const command: CommandDefinition = {
|
|
|
43
43
|
const dbPath = findDbPath();
|
|
44
44
|
const fs = await import('node:fs');
|
|
45
45
|
if (fs.existsSync(dbPath)) {
|
|
46
|
-
// @ts-expect-error -- better-sqlite3 default export typing
|
|
47
46
|
const db = new Database(dbPath, { readonly: true });
|
|
48
47
|
const buildEngine = getBuildMeta(db, 'engine');
|
|
49
48
|
const buildVersion = getBuildMeta(db, 'codegraph_version');
|
package/src/cli/commands/path.ts
CHANGED
|
@@ -4,11 +4,15 @@ import type { CommandDefinition } from '../types.js';
|
|
|
4
4
|
|
|
5
5
|
export const command: CommandDefinition = {
|
|
6
6
|
name: 'path <from> <to>',
|
|
7
|
-
description: 'Find shortest path between two symbols',
|
|
7
|
+
description: 'Find shortest path between two symbols (or files with --file)',
|
|
8
8
|
options: [
|
|
9
9
|
['-d, --db <path>', 'Path to graph.db'],
|
|
10
|
+
['-f, --file', 'Treat <from> and <to> as file paths instead of symbol names'],
|
|
10
11
|
['--reverse', 'Follow edges backward'],
|
|
11
|
-
[
|
|
12
|
+
[
|
|
13
|
+
'--kinds <kinds>',
|
|
14
|
+
'Comma-separated edge kinds to follow (default: calls; file mode: imports,imports-type)',
|
|
15
|
+
],
|
|
12
16
|
['--from-file <path>', 'Disambiguate source symbol by file'],
|
|
13
17
|
['--to-file <path>', 'Disambiguate target symbol by file'],
|
|
14
18
|
['--depth <n>', 'Max traversal depth', '10'],
|
|
@@ -32,6 +36,7 @@ export const command: CommandDefinition = {
|
|
|
32
36
|
kind: opts.kind,
|
|
33
37
|
noTests: ctx.resolveNoTests(opts),
|
|
34
38
|
json: opts.json,
|
|
39
|
+
file: opts.file,
|
|
35
40
|
});
|
|
36
41
|
},
|
|
37
42
|
};
|
package/src/cli/commands/plot.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { toErrorMessage } from '../../shared/errors.js';
|
|
3
4
|
import { openGraph } from '../shared/open-graph.js';
|
|
4
5
|
import type { CommandDefinition } from '../types.js';
|
|
5
6
|
|
|
@@ -51,8 +52,7 @@ export const command: CommandDefinition = {
|
|
|
51
52
|
try {
|
|
52
53
|
plotCfg = JSON.parse(fs.readFileSync(opts.config as string, 'utf-8')) as PlotConfig;
|
|
53
54
|
} catch (e: unknown) {
|
|
54
|
-
|
|
55
|
-
console.error(`Failed to load config: ${message}`);
|
|
55
|
+
console.error(`Failed to load config: ${toErrorMessage(e)}`);
|
|
56
56
|
process.exitCode = 1;
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
@@ -7,7 +7,7 @@ export const command: CommandDefinition = {
|
|
|
7
7
|
description: 'Watch project for file changes and incrementally update the graph',
|
|
8
8
|
async execute([dir], _opts, ctx) {
|
|
9
9
|
const root = path.resolve(dir || '.');
|
|
10
|
-
const engine = ctx.program.opts()
|
|
10
|
+
const engine = ctx.program.opts().engine;
|
|
11
11
|
await watchProject(root, { engine });
|
|
12
12
|
},
|
|
13
13
|
};
|
package/src/cli/index.ts
CHANGED
|
@@ -27,12 +27,12 @@ program
|
|
|
27
27
|
.option('--engine <engine>', 'Parser engine: native, wasm, or auto (default: auto)', 'auto')
|
|
28
28
|
.hook('preAction', (thisCommand) => {
|
|
29
29
|
const opts = thisCommand.opts();
|
|
30
|
-
if (opts
|
|
30
|
+
if (opts.verbose) setVerbose(true);
|
|
31
31
|
})
|
|
32
32
|
.hook('postAction', async (_thisCommand, actionCommand) => {
|
|
33
33
|
const name = actionCommand.name();
|
|
34
34
|
if (name === 'mcp' || name === 'watch') return;
|
|
35
|
-
if (actionCommand.opts()
|
|
35
|
+
if (actionCommand.opts().json) return;
|
|
36
36
|
try {
|
|
37
37
|
const result = await checkForUpdates(pkg.version);
|
|
38
38
|
if (result) printUpdateNotification(result.current, result.latest);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type Database from 'better-sqlite3';
|
|
2
1
|
import { openReadonlyOrFail } from '../../db/index.js';
|
|
2
|
+
import type { BetterSqlite3Database } from '../../types.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Open the graph database in readonly mode with a clean close() handle.
|
|
6
6
|
*/
|
|
7
7
|
export function openGraph(opts: { db?: string } = {}): {
|
|
8
|
-
db:
|
|
8
|
+
db: BetterSqlite3Database;
|
|
9
9
|
close: () => void;
|
|
10
10
|
} {
|
|
11
11
|
const db = openReadonlyOrFail(opts.db);
|
package/src/cli/types.ts
CHANGED
|
@@ -27,7 +27,7 @@ export interface CommandDefinition {
|
|
|
27
27
|
description: string;
|
|
28
28
|
queryOpts?: boolean;
|
|
29
29
|
options?: Array<[string, string, ...unknown[]]>;
|
|
30
|
-
validate?(args: string[], opts: CommandOpts, ctx: CliContext): string |
|
|
30
|
+
validate?(args: string[], opts: CommandOpts, ctx: CliContext): string | undefined;
|
|
31
31
|
execute?(args: string[], opts: CommandOpts, ctx: CliContext): void | Promise<void>;
|
|
32
32
|
subcommands?: CommandDefinition[];
|
|
33
33
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { run } from './cli/index.js';
|
|
4
|
-
import { CodegraphError } from './shared/errors.js';
|
|
4
|
+
import { CodegraphError, toErrorMessage } from './shared/errors.js';
|
|
5
5
|
|
|
6
6
|
run().catch((err: unknown) => {
|
|
7
7
|
if (err instanceof CodegraphError) {
|
|
8
8
|
console.error(`codegraph [${err.code}]: ${err.message}`);
|
|
9
9
|
if (err.file) console.error(` file: ${err.file}`);
|
|
10
10
|
} else {
|
|
11
|
-
|
|
12
|
-
console.error(`codegraph: fatal error — ${message}`);
|
|
11
|
+
console.error(`codegraph: fatal error — ${toErrorMessage(err)}`);
|
|
13
12
|
}
|
|
14
13
|
process.exit(1);
|
|
15
14
|
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy-loaded better-sqlite3 constructor.
|
|
3
|
+
*
|
|
4
|
+
* Centralises the `createRequire` + cache pattern so every call site that
|
|
5
|
+
* needs a JS-side SQLite handle can `import { getDatabase } from '…/db/better-sqlite3.js'`
|
|
6
|
+
* instead of duplicating the boilerplate. The native engine path (NativeDatabase /
|
|
7
|
+
* rusqlite) never touches this module.
|
|
8
|
+
*/
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
|
+
|
|
11
|
+
const _require = createRequire(import.meta.url);
|
|
12
|
+
let _Database: any;
|
|
13
|
+
|
|
14
|
+
/** Return the `better-sqlite3` Database constructor, loading it on first call. */
|
|
15
|
+
export function getDatabase(): new (...args: any[]) => any {
|
|
16
|
+
if (!_Database) {
|
|
17
|
+
_Database = _require('better-sqlite3');
|
|
18
|
+
}
|
|
19
|
+
return _Database;
|
|
20
|
+
}
|
package/src/db/connection.ts
CHANGED
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { debug, warn } from '../infrastructure/logger.js';
|
|
6
|
+
import { getNative, isNativeAvailable } from '../infrastructure/native.js';
|
|
6
7
|
import { DbError } from '../shared/errors.js';
|
|
7
|
-
import type { BetterSqlite3Database } from '../types.js';
|
|
8
|
+
import type { BetterSqlite3Database, NativeDatabase } from '../types.js';
|
|
9
|
+
import { getDatabase } from './better-sqlite3.js';
|
|
8
10
|
import { Repository } from './repository/base.js';
|
|
11
|
+
import { NativeRepository } from './repository/native-repository.js';
|
|
9
12
|
import { SqliteRepository } from './repository/sqlite-repository.js';
|
|
10
13
|
|
|
14
|
+
/** Lazy-loaded package version (read once from package.json). */
|
|
15
|
+
let _packageVersion: string | undefined;
|
|
16
|
+
function getPackageVersion(): string {
|
|
17
|
+
if (_packageVersion !== undefined) return _packageVersion;
|
|
18
|
+
try {
|
|
19
|
+
const connDir = path.dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const pkgPath = path.join(connDir, '..', '..', 'package.json');
|
|
21
|
+
_packageVersion = (JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { version: string })
|
|
22
|
+
.version;
|
|
23
|
+
} catch {
|
|
24
|
+
_packageVersion = '';
|
|
25
|
+
}
|
|
26
|
+
return _packageVersion;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Warn once per process when DB version mismatches the running codegraph version. */
|
|
30
|
+
let _versionWarned = false;
|
|
31
|
+
|
|
11
32
|
/** DB instance with optional advisory lock path. */
|
|
12
33
|
export type LockedDatabase = BetterSqlite3Database & { __lockPath?: string };
|
|
13
34
|
|
|
@@ -60,6 +81,11 @@ export function _resetRepoRootCache(): void {
|
|
|
60
81
|
_cachedRepoRootCwd = undefined;
|
|
61
82
|
}
|
|
62
83
|
|
|
84
|
+
/** Reset the version warning flag (for testing). */
|
|
85
|
+
export function _resetVersionWarning(): void {
|
|
86
|
+
_versionWarned = false;
|
|
87
|
+
}
|
|
88
|
+
|
|
63
89
|
function isProcessAlive(pid: number): boolean {
|
|
64
90
|
try {
|
|
65
91
|
process.kill(pid, 0);
|
|
@@ -119,16 +145,13 @@ function isSameDirectory(a: string, b: string): boolean {
|
|
|
119
145
|
}
|
|
120
146
|
|
|
121
147
|
export function openDb(dbPath: string): LockedDatabase {
|
|
148
|
+
// Flush any deferred DB close from a previous build (avoids WAL contention)
|
|
149
|
+
flushDeferredClose();
|
|
122
150
|
const dir = path.dirname(dbPath);
|
|
123
151
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
124
152
|
acquireAdvisoryLock(dbPath);
|
|
125
|
-
|
|
126
|
-
const db = new (
|
|
127
|
-
Database as unknown as new (
|
|
128
|
-
path: string,
|
|
129
|
-
opts?: Record<string, unknown>,
|
|
130
|
-
) => LockedDatabase
|
|
131
|
-
)(dbPath);
|
|
153
|
+
const Database = getDatabase();
|
|
154
|
+
const db = new Database(dbPath) as unknown as LockedDatabase;
|
|
132
155
|
db.pragma('journal_mode = WAL');
|
|
133
156
|
db.pragma('busy_timeout = 5000');
|
|
134
157
|
db.__lockPath = `${dbPath}.lock`;
|
|
@@ -140,6 +163,89 @@ export function closeDb(db: LockedDatabase): void {
|
|
|
140
163
|
if (db.__lockPath) releaseAdvisoryLock(db.__lockPath);
|
|
141
164
|
}
|
|
142
165
|
|
|
166
|
+
/** Pending deferred-close DB handles (not yet closed). */
|
|
167
|
+
const _deferredDbs: LockedDatabase[] = [];
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Synchronously close any DB handles queued by `closeDbDeferred()`.
|
|
171
|
+
* Call before deleting DB files or in test teardown to avoid EBUSY on Windows.
|
|
172
|
+
*/
|
|
173
|
+
export function flushDeferredClose(): void {
|
|
174
|
+
while (_deferredDbs.length > 0) {
|
|
175
|
+
const db = _deferredDbs.pop()!;
|
|
176
|
+
try {
|
|
177
|
+
db.close();
|
|
178
|
+
} catch {
|
|
179
|
+
/* ignore — handle may already be closed */
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Schedule DB close on the next event loop tick. Useful for incremental
|
|
186
|
+
* builds where the WAL checkpoint in db.close() is expensive (~250ms on
|
|
187
|
+
* Windows) and doesn't need to block the caller.
|
|
188
|
+
*
|
|
189
|
+
* The advisory lock is released immediately so subsequent opens succeed.
|
|
190
|
+
* The actual handle close (+ WAL checkpoint) happens asynchronously.
|
|
191
|
+
* Call `flushDeferredClose()` before deleting the DB file.
|
|
192
|
+
*/
|
|
193
|
+
export function closeDbDeferred(db: LockedDatabase): void {
|
|
194
|
+
// Release the advisory lock immediately so the next open can proceed
|
|
195
|
+
if (db.__lockPath) {
|
|
196
|
+
releaseAdvisoryLock(db.__lockPath);
|
|
197
|
+
db.__lockPath = undefined;
|
|
198
|
+
}
|
|
199
|
+
_deferredDbs.push(db);
|
|
200
|
+
// Defer the expensive WAL checkpoint to after the caller returns
|
|
201
|
+
setImmediate(() => {
|
|
202
|
+
const idx = _deferredDbs.indexOf(db);
|
|
203
|
+
if (idx !== -1) {
|
|
204
|
+
_deferredDbs.splice(idx, 1);
|
|
205
|
+
try {
|
|
206
|
+
db.close();
|
|
207
|
+
} catch {
|
|
208
|
+
/* ignore — handle may already be closed by flush */
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ── Paired close helpers (Phase 6.16) ──────────────────────────────────
|
|
215
|
+
// When both a NativeDatabase and better-sqlite3 handle are open on the same
|
|
216
|
+
// DB file, these helpers ensure NativeDatabase is closed first (fast, ~1ms)
|
|
217
|
+
// before the better-sqlite3 close (which forces a WAL checkpoint, ~250ms).
|
|
218
|
+
|
|
219
|
+
/** A better-sqlite3 handle optionally paired with a NativeDatabase. */
|
|
220
|
+
export interface LockedDatabasePair {
|
|
221
|
+
db: LockedDatabase;
|
|
222
|
+
nativeDb?: NativeDatabase;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Close both handles: NativeDatabase first (fast), then better-sqlite3 (releases lock). */
|
|
226
|
+
export function closeDbPair(pair: LockedDatabasePair): void {
|
|
227
|
+
if (pair.nativeDb) {
|
|
228
|
+
try {
|
|
229
|
+
pair.nativeDb.close();
|
|
230
|
+
} catch {
|
|
231
|
+
/* ignore */
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
closeDb(pair.db);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** Close NativeDatabase immediately, defer better-sqlite3 WAL checkpoint. */
|
|
238
|
+
export function closeDbPairDeferred(pair: LockedDatabasePair): void {
|
|
239
|
+
if (pair.nativeDb) {
|
|
240
|
+
try {
|
|
241
|
+
pair.nativeDb.close();
|
|
242
|
+
} catch {
|
|
243
|
+
/* ignore */
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
closeDbDeferred(pair.db);
|
|
247
|
+
}
|
|
248
|
+
|
|
143
249
|
export function findDbPath(customPath?: string): string {
|
|
144
250
|
if (customPath) return path.resolve(customPath);
|
|
145
251
|
const rawCeiling = findRepoRoot();
|
|
@@ -190,19 +296,38 @@ export function openReadonlyOrFail(customPath?: string): BetterSqlite3Database {
|
|
|
190
296
|
{ file: dbPath },
|
|
191
297
|
);
|
|
192
298
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
299
|
+
const Database = getDatabase();
|
|
300
|
+
const db = new Database(dbPath, { readonly: true }) as unknown as BetterSqlite3Database;
|
|
301
|
+
|
|
302
|
+
// Warn once per process if the DB was built with a different codegraph version
|
|
303
|
+
if (!_versionWarned) {
|
|
304
|
+
try {
|
|
305
|
+
const row = db
|
|
306
|
+
.prepare<{ value: string }>('SELECT value FROM build_meta WHERE key = ?')
|
|
307
|
+
.get('codegraph_version');
|
|
308
|
+
const buildVersion = row?.value;
|
|
309
|
+
const currentVersion = getPackageVersion();
|
|
310
|
+
if (buildVersion && currentVersion && buildVersion !== currentVersion) {
|
|
311
|
+
warn(
|
|
312
|
+
`DB was built with codegraph v${buildVersion}, running v${currentVersion}. Consider: codegraph build --no-incremental`,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
} catch {
|
|
316
|
+
// build_meta table may not exist in older DBs — silently ignore
|
|
317
|
+
}
|
|
318
|
+
_versionWarned = true;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return db;
|
|
199
322
|
}
|
|
200
323
|
|
|
201
324
|
/**
|
|
202
325
|
* Open a Repository from either an injected instance or a DB path.
|
|
203
326
|
*
|
|
204
327
|
* When `opts.repo` is a Repository instance, returns it directly (no DB opened).
|
|
205
|
-
*
|
|
328
|
+
* When the native engine is available, opens a NativeDatabase (rusqlite) and
|
|
329
|
+
* wraps it in NativeRepository. Otherwise falls back to better-sqlite3 via
|
|
330
|
+
* SqliteRepository.
|
|
206
331
|
*/
|
|
207
332
|
export function openRepo(
|
|
208
333
|
customDbPath?: string,
|
|
@@ -216,6 +341,56 @@ export function openRepo(
|
|
|
216
341
|
}
|
|
217
342
|
return { repo: opts.repo, close() {} };
|
|
218
343
|
}
|
|
344
|
+
|
|
345
|
+
// Try native rusqlite path first (Phase 6.14)
|
|
346
|
+
if (isNativeAvailable()) {
|
|
347
|
+
try {
|
|
348
|
+
const dbPath = findDbPath(customDbPath);
|
|
349
|
+
if (!fs.existsSync(dbPath)) {
|
|
350
|
+
throw new DbError(
|
|
351
|
+
`No codegraph database found at ${dbPath}.\nRun "codegraph build" first to analyze your codebase.`,
|
|
352
|
+
{ file: dbPath },
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
const native = getNative();
|
|
356
|
+
const ndb = native.NativeDatabase.openReadonly(dbPath);
|
|
357
|
+
try {
|
|
358
|
+
// Version check (same logic as openReadonlyOrFail)
|
|
359
|
+
if (!_versionWarned) {
|
|
360
|
+
try {
|
|
361
|
+
const buildVersion = ndb.getBuildMeta('codegraph_version');
|
|
362
|
+
const currentVersion = getPackageVersion();
|
|
363
|
+
if (buildVersion && currentVersion && buildVersion !== currentVersion) {
|
|
364
|
+
warn(
|
|
365
|
+
`DB was built with codegraph v${buildVersion}, running v${currentVersion}. Consider: codegraph build --no-incremental`,
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
} catch {
|
|
369
|
+
// build_meta table may not exist in older DBs
|
|
370
|
+
}
|
|
371
|
+
_versionWarned = true;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return {
|
|
375
|
+
repo: new NativeRepository(ndb),
|
|
376
|
+
close() {
|
|
377
|
+
ndb.close();
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
} catch (innerErr) {
|
|
381
|
+
ndb.close();
|
|
382
|
+
throw innerErr;
|
|
383
|
+
}
|
|
384
|
+
} catch (e) {
|
|
385
|
+
// Re-throw user-visible errors (e.g. DB not found) — only silently
|
|
386
|
+
// fall back for native-engine failures (e.g. incompatible native binary).
|
|
387
|
+
if (e instanceof DbError) throw e;
|
|
388
|
+
debug(
|
|
389
|
+
`openRepo: native path failed, falling back to better-sqlite3: ${(e as Error).message}`,
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
219
394
|
const db = openReadonlyOrFail(customDbPath);
|
|
220
395
|
return {
|
|
221
396
|
repo: new SqliteRepository(db),
|
package/src/db/index.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// Barrel re-export — keeps all existing `import { ... } from '…/db/index.js'` working.
|
|
2
2
|
|
|
3
|
-
export type { LockedDatabase } from './connection.js';
|
|
3
|
+
export type { LockedDatabase, LockedDatabasePair } from './connection.js';
|
|
4
4
|
export {
|
|
5
5
|
closeDb,
|
|
6
|
+
closeDbDeferred,
|
|
7
|
+
closeDbPair,
|
|
8
|
+
closeDbPairDeferred,
|
|
6
9
|
findDbPath,
|
|
7
10
|
findRepoRoot,
|
|
11
|
+
flushDeferredClose,
|
|
8
12
|
openDb,
|
|
9
13
|
openReadonlyOrFail,
|
|
10
14
|
openRepo,
|
package/src/db/migrations.ts
CHANGED
|
@@ -8,6 +8,8 @@ interface Migration {
|
|
|
8
8
|
up: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
// IMPORTANT: Migration DDL is mirrored in crates/codegraph-core/src/native_db.rs.
|
|
12
|
+
// Any changes here MUST be reflected there (and vice-versa).
|
|
11
13
|
export const MIGRATIONS: Migration[] = [
|
|
12
14
|
{
|
|
13
15
|
version: 1,
|
|
@@ -247,6 +249,13 @@ export const MIGRATIONS: Migration[] = [
|
|
|
247
249
|
CREATE INDEX IF NOT EXISTS idx_nodes_scope ON nodes(scope);
|
|
248
250
|
`,
|
|
249
251
|
},
|
|
252
|
+
{
|
|
253
|
+
version: 16,
|
|
254
|
+
up: `
|
|
255
|
+
CREATE INDEX IF NOT EXISTS idx_edges_kind_target ON edges(kind, target_id);
|
|
256
|
+
CREATE INDEX IF NOT EXISTS idx_edges_kind_source ON edges(kind, source_id);
|
|
257
|
+
`,
|
|
258
|
+
},
|
|
250
259
|
];
|
|
251
260
|
|
|
252
261
|
interface PragmaColumnInfo {
|
package/src/db/query-builder.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DbError } from '../shared/errors.js';
|
|
2
2
|
import { DEAD_ROLE_PREFIX, EVERY_EDGE_KIND } from '../shared/kinds.js';
|
|
3
|
-
import type { BetterSqlite3Database } from '../types.js';
|
|
3
|
+
import type { BetterSqlite3Database, NativeDatabase } from '../types.js';
|
|
4
4
|
|
|
5
5
|
// ─── Validation Helpers ─────────────────────────────────────────────
|
|
6
6
|
|
|
@@ -66,6 +66,17 @@ function validateEdgeKind(edgeKind: string): void {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/** Runtime-validate that every param is string, number, or null before sending to nativeDb. */
|
|
70
|
+
function validateNativeParams(params: (string | number)[]): Array<string | number | null> {
|
|
71
|
+
for (let i = 0; i < params.length; i++) {
|
|
72
|
+
const p = params[i];
|
|
73
|
+
if (p !== null && typeof p !== 'string' && typeof p !== 'number') {
|
|
74
|
+
throw new DbError(`NodeQuery param[${i}] has unsupported type: ${typeof p}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return params as Array<string | number | null>;
|
|
78
|
+
}
|
|
79
|
+
|
|
69
80
|
// ─── LIKE Escaping ──────────────────────────────────────────────────
|
|
70
81
|
|
|
71
82
|
/** Escape LIKE wildcards in a literal string segment. */
|
|
@@ -314,15 +325,29 @@ export class NodeQuery {
|
|
|
314
325
|
return { sql, params };
|
|
315
326
|
}
|
|
316
327
|
|
|
317
|
-
/** Execute and return all rows. */
|
|
318
|
-
all<TRow = Record<string, unknown>>(
|
|
328
|
+
/** Execute and return all rows. When `nativeDb` is provided, dispatches through rusqlite. */
|
|
329
|
+
all<TRow = Record<string, unknown>>(
|
|
330
|
+
db: BetterSqlite3Database,
|
|
331
|
+
nativeDb?: NativeDatabase,
|
|
332
|
+
): TRow[] {
|
|
319
333
|
const { sql, params } = this.build();
|
|
334
|
+
if (nativeDb) {
|
|
335
|
+
return nativeDb.queryAll(sql, validateNativeParams(params)) as TRow[];
|
|
336
|
+
}
|
|
320
337
|
return db.prepare<TRow>(sql).all(...params) as TRow[];
|
|
321
338
|
}
|
|
322
339
|
|
|
323
|
-
/** Execute and return first row. */
|
|
324
|
-
get<TRow = Record<string, unknown>>(
|
|
340
|
+
/** Execute and return first row. When `nativeDb` is provided, dispatches through rusqlite. */
|
|
341
|
+
get<TRow = Record<string, unknown>>(
|
|
342
|
+
db: BetterSqlite3Database,
|
|
343
|
+
nativeDb?: NativeDatabase,
|
|
344
|
+
): TRow | undefined {
|
|
325
345
|
const { sql, params } = this.build();
|
|
346
|
+
if (nativeDb) {
|
|
347
|
+
return (nativeDb.queryGet(sql, validateNativeParams(params)) ?? undefined) as
|
|
348
|
+
| TRow
|
|
349
|
+
| undefined;
|
|
350
|
+
}
|
|
326
351
|
return db.prepare<TRow>(sql).get(...params) as TRow | undefined;
|
|
327
352
|
}
|
|
328
353
|
|
|
@@ -28,6 +28,7 @@ export {
|
|
|
28
28
|
export { getEmbeddingCount, getEmbeddingMeta, hasEmbeddings } from './embeddings.js';
|
|
29
29
|
export { getCallableNodes, getCallEdges, getFileNodesAll, getImportEdges } from './graph-read.js';
|
|
30
30
|
export { InMemoryRepository } from './in-memory-repository.js';
|
|
31
|
+
export { NativeRepository } from './native-repository.js';
|
|
31
32
|
export {
|
|
32
33
|
bulkNodeIdsByFile,
|
|
33
34
|
countEdges,
|