@optave/codegraph 3.4.0 → 3.4.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/README.md +7 -7
- 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/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/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/connection.d.ts +17 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +91 -2
- 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 +7 -0
- package/dist/db/migrations.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 +2 -3
- 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 +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 +6 -0
- 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 +12 -2
- 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 +155 -59
- package/dist/domain/graph/builder/stages/build-structure.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 +6 -6
- 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 +85 -61
- 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.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 +11 -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 +58 -60
- 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 +2 -2
- package/dist/extractors/rust.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 +2 -3
- 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.d.ts.map +1 -1
- package/dist/features/snapshot.js +0 -1
- 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 +2 -8
- 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 +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -7
- package/src/ast-analysis/engine.ts +3 -9
- package/src/ast-analysis/shared.ts +0 -1
- 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/connection.ts +97 -13
- package/src/db/index.ts +2 -0
- package/src/db/migrations.ts +7 -0
- 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 +2 -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 +8 -0
- package/src/domain/graph/builder/stages/build-edges.ts +17 -4
- package/src/domain/graph/builder/stages/build-structure.ts +205 -76
- package/src/domain/graph/builder/stages/detect-changes.ts +11 -12
- package/src/domain/graph/builder/stages/finalize.ts +100 -81
- package/src/domain/graph/builder/stages/insert-nodes.ts +12 -8
- 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 +11 -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 +58 -61
- package/src/extractors/php.ts +2 -2
- package/src/extractors/python.ts +2 -2
- package/src/extractors/rust.ts +2 -2
- package/src/features/audit.ts +1 -2
- package/src/features/branch-compare.ts +3 -9
- 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 +1 -2
- 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 +2 -10
- 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 +4 -10
- package/src/vendor.d.ts +0 -39
|
@@ -50,18 +50,11 @@ function taAdd(a: Float64Array, i: number, v: number): void {
|
|
|
50
50
|
a[i] = taGet(a, i) + v;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
function taSub(a: Float64Array, i: number, v: number): void {
|
|
54
|
-
a[i] = taGet(a, i) - v;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
53
|
export function makeGraphAdapter(graph: CodeGraph, opts: GraphAdapterOptions = {}): GraphAdapter {
|
|
58
54
|
const linkWeight: (attrs: EdgeAttrs) => number =
|
|
59
|
-
opts.linkWeight ||
|
|
60
|
-
// biome-ignore lint/complexity/useLiteralKeys: index signature requires bracket access
|
|
61
|
-
((attrs) => (attrs && typeof attrs['weight'] === 'number' ? attrs['weight'] : 1));
|
|
55
|
+
opts.linkWeight || ((attrs) => (attrs && typeof attrs.weight === 'number' ? attrs.weight : 1));
|
|
62
56
|
const nodeSize: (attrs: NodeAttrs) => number =
|
|
63
|
-
|
|
64
|
-
opts.nodeSize || ((attrs) => (attrs && typeof attrs['size'] === 'number' ? attrs['size'] : 1));
|
|
57
|
+
opts.nodeSize || ((attrs) => (attrs && typeof attrs.size === 'number' ? attrs.size : 1));
|
|
65
58
|
const directed: boolean = !!opts.directed;
|
|
66
59
|
const baseNodeIds: string[] | undefined = opts.baseNodeIds;
|
|
67
60
|
|
|
@@ -58,7 +58,7 @@ function classifyDeadSubRole(node: ClassifiableNode): DeadSubRole {
|
|
|
58
58
|
|
|
59
59
|
// ── Helpers ────────────────────────────────────────────────────────
|
|
60
60
|
|
|
61
|
-
function median(sorted: number[]): number {
|
|
61
|
+
export function median(sorted: number[]): number {
|
|
62
62
|
if (sorted.length === 0) return 0;
|
|
63
63
|
const mid = Math.floor(sorted.length / 2);
|
|
64
64
|
return sorted.length % 2 === 0 ? (sorted[mid - 1]! + sorted[mid]!) / 2 : sorted[mid]!;
|
|
@@ -79,20 +79,29 @@ export interface RoleClassificationNode {
|
|
|
79
79
|
/**
|
|
80
80
|
* Classify nodes into architectural roles based on fan-in/fan-out metrics.
|
|
81
81
|
*/
|
|
82
|
-
export function classifyRoles(
|
|
82
|
+
export function classifyRoles(
|
|
83
|
+
nodes: RoleClassificationNode[],
|
|
84
|
+
medianOverrides?: { fanIn: number; fanOut: number },
|
|
85
|
+
): Map<string, Role> {
|
|
83
86
|
if (nodes.length === 0) return new Map();
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
let medFanIn: number;
|
|
89
|
+
let medFanOut: number;
|
|
90
|
+
if (medianOverrides) {
|
|
91
|
+
medFanIn = medianOverrides.fanIn;
|
|
92
|
+
medFanOut = medianOverrides.fanOut;
|
|
93
|
+
} else {
|
|
94
|
+
const nonZeroFanIn = nodes
|
|
95
|
+
.filter((n) => n.fanIn > 0)
|
|
96
|
+
.map((n) => n.fanIn)
|
|
97
|
+
.sort((a, b) => a - b);
|
|
98
|
+
const nonZeroFanOut = nodes
|
|
99
|
+
.filter((n) => n.fanOut > 0)
|
|
100
|
+
.map((n) => n.fanOut)
|
|
101
|
+
.sort((a, b) => a - b);
|
|
102
|
+
medFanIn = median(nonZeroFanIn);
|
|
103
|
+
medFanOut = median(nonZeroFanOut);
|
|
104
|
+
}
|
|
96
105
|
|
|
97
106
|
const result = new Map<string, Role>();
|
|
98
107
|
|
package/src/index.ts
CHANGED
|
@@ -53,6 +53,7 @@ export { sequenceData } from './features/sequence.js';
|
|
|
53
53
|
export { hotspotsData, moduleBoundariesData, structureData } from './features/structure.js';
|
|
54
54
|
export { triageData } from './features/triage.js';
|
|
55
55
|
export { loadConfig } from './infrastructure/config.js';
|
|
56
|
+
export type { ArrayCompatSet } from './shared/constants.js';
|
|
56
57
|
export { EXTENSIONS, IGNORE_DIRS } from './shared/constants.js';
|
|
57
58
|
export {
|
|
58
59
|
AnalysisError,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { toErrorMessage } from '../shared/errors.js';
|
|
4
5
|
import type { CodegraphConfig } from '../types.js';
|
|
5
6
|
import { debug, warn } from './logger.js';
|
|
6
7
|
|
|
@@ -170,11 +171,9 @@ export function loadConfig(cwd?: string): CodegraphConfig {
|
|
|
170
171
|
debug(`Loaded config from ${filePath}`);
|
|
171
172
|
const merged = mergeConfig(DEFAULTS as unknown as Record<string, unknown>, config);
|
|
172
173
|
if ('excludeTests' in config && !(config.query && 'excludeTests' in config.query)) {
|
|
173
|
-
(merged
|
|
174
|
-
config.excludeTests,
|
|
175
|
-
);
|
|
174
|
+
(merged.query as Record<string, unknown>).excludeTests = Boolean(config.excludeTests);
|
|
176
175
|
}
|
|
177
|
-
delete merged
|
|
176
|
+
delete merged.excludeTests;
|
|
178
177
|
const result = resolveSecrets(applyEnvOverrides(merged as unknown as CodegraphConfig));
|
|
179
178
|
_configCache.set(cwd, structuredClone(result));
|
|
180
179
|
return result;
|
|
@@ -227,7 +226,7 @@ export function resolveSecrets(config: CodegraphConfig): CodegraphConfig {
|
|
|
227
226
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
228
227
|
}).trim();
|
|
229
228
|
if (result) {
|
|
230
|
-
(config.llm as Record<string, unknown>)
|
|
229
|
+
(config.llm as Record<string, unknown>).apiKey = result;
|
|
231
230
|
}
|
|
232
231
|
} catch (err: unknown) {
|
|
233
232
|
warn(`apiKeyCommand failed: ${(err as Error).message}`);
|
|
@@ -310,8 +309,8 @@ function resolveWorkspaceEntry(pkgDir: string): string | null {
|
|
|
310
309
|
const candidate = path.resolve(pkgDir, idx);
|
|
311
310
|
if (fs.existsSync(candidate)) return candidate;
|
|
312
311
|
}
|
|
313
|
-
} catch {
|
|
314
|
-
|
|
312
|
+
} catch (e) {
|
|
313
|
+
debug(`resolveWorkspaceEntry: package.json probe failed for ${pkgDir}: ${toErrorMessage(e)}`);
|
|
315
314
|
}
|
|
316
315
|
return null;
|
|
317
316
|
}
|
|
@@ -344,8 +343,8 @@ export function detectWorkspaces(rootDir: string): Map<string, WorkspaceEntry> {
|
|
|
344
343
|
}
|
|
345
344
|
}
|
|
346
345
|
}
|
|
347
|
-
} catch {
|
|
348
|
-
|
|
346
|
+
} catch (e) {
|
|
347
|
+
debug(`detectWorkspaces: failed to parse pnpm-workspace.yaml: ${toErrorMessage(e)}`);
|
|
349
348
|
}
|
|
350
349
|
}
|
|
351
350
|
|
|
@@ -363,8 +362,8 @@ export function detectWorkspaces(rootDir: string): Map<string, WorkspaceEntry> {
|
|
|
363
362
|
// Yarn classic format: { packages: [...], nohoist: [...] }
|
|
364
363
|
patterns.push(...ws.packages);
|
|
365
364
|
}
|
|
366
|
-
} catch {
|
|
367
|
-
|
|
365
|
+
} catch (e) {
|
|
366
|
+
debug(`detectWorkspaces: failed to parse package.json workspaces: ${toErrorMessage(e)}`);
|
|
368
367
|
}
|
|
369
368
|
}
|
|
370
369
|
}
|
|
@@ -379,8 +378,8 @@ export function detectWorkspaces(rootDir: string): Map<string, WorkspaceEntry> {
|
|
|
379
378
|
if (Array.isArray(lerna.packages)) {
|
|
380
379
|
patterns.push(...lerna.packages);
|
|
381
380
|
}
|
|
382
|
-
} catch {
|
|
383
|
-
|
|
381
|
+
} catch (e) {
|
|
382
|
+
debug(`detectWorkspaces: failed to parse lerna.json: ${toErrorMessage(e)}`);
|
|
384
383
|
}
|
|
385
384
|
}
|
|
386
385
|
}
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
import { createRequire } from 'node:module';
|
|
10
10
|
import os from 'node:os';
|
|
11
|
-
import { EngineError } from '../shared/errors.js';
|
|
11
|
+
import { EngineError, toErrorMessage } from '../shared/errors.js';
|
|
12
12
|
import type { NativeAddon } from '../types.js';
|
|
13
|
+
import { debug } from './logger.js';
|
|
13
14
|
|
|
14
15
|
let _cached: NativeAddon | null | undefined; // undefined = not yet tried, null = failed, NativeAddon = module
|
|
15
16
|
let _loadError: Error | null = null;
|
|
@@ -26,7 +27,9 @@ function detectLibc(): 'gnu' | 'musl' {
|
|
|
26
27
|
if (files.some((f: string) => f.startsWith('ld-musl-') && f.endsWith('.so.1'))) {
|
|
27
28
|
return 'musl';
|
|
28
29
|
}
|
|
29
|
-
} catch {
|
|
30
|
+
} catch (e) {
|
|
31
|
+
debug(`detectLibc: failed to read /lib: ${toErrorMessage(e)}`);
|
|
32
|
+
}
|
|
30
33
|
return 'gnu';
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -92,7 +95,8 @@ export function getNativePackageVersion(): string | null {
|
|
|
92
95
|
try {
|
|
93
96
|
const pkgJson = _require(`${pkg}/package.json`) as { version?: string };
|
|
94
97
|
return pkgJson.version || null;
|
|
95
|
-
} catch {
|
|
98
|
+
} catch (e) {
|
|
99
|
+
debug(`getNativePackageVersion: failed to read package.json for ${pkg}: ${toErrorMessage(e)}`);
|
|
96
100
|
return null;
|
|
97
101
|
}
|
|
98
102
|
}
|
|
@@ -4,7 +4,7 @@ import path from 'node:path';
|
|
|
4
4
|
import { debug, warn } from './logger.js';
|
|
5
5
|
|
|
6
6
|
export const REGISTRY_PATH: string =
|
|
7
|
-
process.env
|
|
7
|
+
process.env.CODEGRAPH_REGISTRY_PATH || path.join(os.homedir(), '.codegraph', 'registry.json');
|
|
8
8
|
|
|
9
9
|
/** Default TTL: entries not accessed within 30 days are pruned. */
|
|
10
10
|
export const DEFAULT_TTL_DAYS = 30;
|
|
@@ -4,7 +4,7 @@ import os from 'node:os';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
|
|
6
6
|
const CACHE_PATH: string =
|
|
7
|
-
process.env
|
|
7
|
+
process.env.CODEGRAPH_UPDATE_CACHE_PATH ||
|
|
8
8
|
path.join(os.homedir(), '.codegraph', 'update-check.json');
|
|
9
9
|
|
|
10
10
|
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
@@ -120,8 +120,8 @@ export async function checkForUpdates(
|
|
|
120
120
|
options: CheckForUpdatesOptions = {},
|
|
121
121
|
): Promise<UpdateResult | null> {
|
|
122
122
|
// Suppress in non-interactive / CI contexts
|
|
123
|
-
if (process.env
|
|
124
|
-
if (process.env
|
|
123
|
+
if (process.env.CI) return null;
|
|
124
|
+
if (process.env.NO_UPDATE_CHECK) return null;
|
|
125
125
|
if (!process.stderr.isTTY) return null;
|
|
126
126
|
if (currentVersion.includes('-')) return null;
|
|
127
127
|
|
package/src/mcp/server.ts
CHANGED
|
@@ -24,14 +24,11 @@ import { TOOL_HANDLERS } from './tools/index.js';
|
|
|
24
24
|
* Because tests use vi.resetModules(), this module-level variable resets
|
|
25
25
|
* on each re-import — but the process-level flag on `process` persists.
|
|
26
26
|
*/
|
|
27
|
-
// biome-ignore lint/suspicious/noExplicitAny: MCP SDK server type is lazy-loaded
|
|
28
27
|
let _activeServer: any = null;
|
|
29
28
|
|
|
30
29
|
export interface McpToolContext {
|
|
31
30
|
dbPath: string | undefined;
|
|
32
|
-
// biome-ignore lint/suspicious/noExplicitAny: lazy-loaded queries module
|
|
33
31
|
getQueries(): Promise<any>;
|
|
34
|
-
// biome-ignore lint/suspicious/noExplicitAny: lazy-loaded better-sqlite3 constructor
|
|
35
32
|
getDatabase(): any;
|
|
36
33
|
findDbPath: typeof findDbPath;
|
|
37
34
|
allowedRepos: string[] | undefined;
|
|
@@ -140,7 +137,6 @@ export async function startMCPServer(
|
|
|
140
137
|
// and cached for subsequent calls.
|
|
141
138
|
const { getQueries, getDatabase } = createLazyLoaders();
|
|
142
139
|
|
|
143
|
-
// biome-ignore lint/suspicious/noExplicitAny: MCP SDK types are lazy-loaded and untyped
|
|
144
140
|
const server = new (Server as any)(
|
|
145
141
|
{ name: 'codegraph', version: PKG_VERSION },
|
|
146
142
|
{ capabilities: { tools: {} } },
|
|
@@ -150,7 +146,6 @@ export async function startMCPServer(
|
|
|
150
146
|
tools: buildToolList(multiRepo),
|
|
151
147
|
}));
|
|
152
148
|
|
|
153
|
-
// biome-ignore lint/suspicious/noExplicitAny: MCP SDK request type is dynamic
|
|
154
149
|
server.setRequestHandler(CallToolRequestSchema, async (request: any) => {
|
|
155
150
|
const { name, arguments: args } = request.params;
|
|
156
151
|
try {
|
|
@@ -185,7 +180,6 @@ export async function startMCPServer(
|
|
|
185
180
|
}
|
|
186
181
|
});
|
|
187
182
|
|
|
188
|
-
// biome-ignore lint/suspicious/noExplicitAny: MCP SDK types are lazy-loaded and untyped
|
|
189
183
|
const transport = new (StdioServerTransport as any)();
|
|
190
184
|
|
|
191
185
|
// Graceful shutdown — when the client disconnects (e.g. session clear),
|
|
@@ -197,10 +191,8 @@ export async function startMCPServer(
|
|
|
197
191
|
// Register handlers once per process to avoid listener accumulation.
|
|
198
192
|
// Use a process-level flag so it survives vi.resetModules() in tests.
|
|
199
193
|
const g = globalThis as Record<string, unknown>;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
// biome-ignore lint/complexity/useLiteralKeys: bracket notation required by TS noPropertyAccessFromIndexSignature
|
|
203
|
-
g['__codegraph_shutdown_installed'] = true;
|
|
194
|
+
if (!g.__codegraph_shutdown_installed) {
|
|
195
|
+
g.__codegraph_shutdown_installed = true;
|
|
204
196
|
|
|
205
197
|
const shutdown = async () => {
|
|
206
198
|
try {
|
package/src/mcp/tool-registry.ts
CHANGED
|
@@ -77,20 +77,27 @@ const BASE_TOOLS: ToolSchema[] = [
|
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
name: 'path',
|
|
80
|
-
description:
|
|
80
|
+
description:
|
|
81
|
+
'Find shortest path between two symbols (or files with file_mode) in the dependency graph',
|
|
81
82
|
inputSchema: {
|
|
82
83
|
type: 'object',
|
|
83
84
|
properties: {
|
|
84
|
-
from: { type: 'string', description: 'Source symbol name' },
|
|
85
|
-
to: { type: 'string', description: 'Target symbol name' },
|
|
85
|
+
from: { type: 'string', description: 'Source symbol name (or file path with file_mode)' },
|
|
86
|
+
to: { type: 'string', description: 'Target symbol name (or file path with file_mode)' },
|
|
86
87
|
depth: { type: 'number', description: 'Max traversal depth (default: 10)' },
|
|
87
88
|
edge_kinds: {
|
|
88
89
|
type: 'array',
|
|
89
90
|
items: { type: 'string', enum: EVERY_EDGE_KIND },
|
|
90
|
-
description:
|
|
91
|
+
description:
|
|
92
|
+
'Edge kinds to follow (default: ["calls"] for symbols, ["imports","imports-type"] for files)',
|
|
91
93
|
},
|
|
92
94
|
from_file: { type: 'string', description: 'Disambiguate source by file' },
|
|
93
95
|
to_file: { type: 'string', description: 'Disambiguate target by file' },
|
|
96
|
+
file_mode: {
|
|
97
|
+
type: 'boolean',
|
|
98
|
+
description: 'Treat from/to as file paths and find file-to-file shortest path',
|
|
99
|
+
default: false,
|
|
100
|
+
},
|
|
94
101
|
no_tests: { type: 'boolean', description: 'Exclude test files', default: false },
|
|
95
102
|
},
|
|
96
103
|
required: ['from', 'to'],
|
package/src/mcp/tools/audit.ts
CHANGED
|
@@ -19,7 +19,7 @@ export async function handler(args: AuditArgs, ctx: McpToolContext): Promise<unk
|
|
|
19
19
|
const { explainData } = await ctx.getQueries();
|
|
20
20
|
return explainData(args.target, ctx.dbPath, {
|
|
21
21
|
noTests: args.no_tests,
|
|
22
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
22
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.explain ?? 100, MCP_MAX_LIMIT),
|
|
23
23
|
offset: effectiveOffset(args),
|
|
24
24
|
});
|
|
25
25
|
}
|
package/src/mcp/tools/cfg.ts
CHANGED
|
@@ -19,7 +19,7 @@ export async function handler(args: CfgArgs, ctx: McpToolContext): Promise<unkno
|
|
|
19
19
|
file: args.file,
|
|
20
20
|
kind: args.kind,
|
|
21
21
|
noTests: args.no_tests,
|
|
22
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
22
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.query ?? 100, ctx.MCP_MAX_LIMIT),
|
|
23
23
|
offset: effectiveOffset(args),
|
|
24
24
|
});
|
|
25
25
|
if (args.format === 'dot') {
|
package/src/mcp/tools/check.ts
CHANGED
|
@@ -28,7 +28,7 @@ export async function handler(args: CheckArgs, ctx: McpToolContext): Promise<unk
|
|
|
28
28
|
file: args.file,
|
|
29
29
|
noTests: args.no_tests,
|
|
30
30
|
kind: args.kind,
|
|
31
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
31
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.manifesto ?? 100, MCP_MAX_LIMIT),
|
|
32
32
|
offset: effectiveOffset(args),
|
|
33
33
|
});
|
|
34
34
|
}
|
|
@@ -51,7 +51,7 @@ export async function handler(args: CheckArgs, ctx: McpToolContext): Promise<unk
|
|
|
51
51
|
file: args.file,
|
|
52
52
|
noTests: args.no_tests,
|
|
53
53
|
kind: args.kind,
|
|
54
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
54
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.manifesto ?? 100, MCP_MAX_LIMIT),
|
|
55
55
|
offset: effectiveOffset(args),
|
|
56
56
|
});
|
|
57
57
|
return { check: checkResult, manifesto: manifestoResult };
|
|
@@ -23,7 +23,7 @@ export async function handler(args: DataflowArgs, ctx: McpToolContext): Promise<
|
|
|
23
23
|
file: args.file,
|
|
24
24
|
kind: args.kind,
|
|
25
25
|
noTests: args.no_tests,
|
|
26
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
26
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.fn_impact ?? 100, ctx.MCP_MAX_LIMIT),
|
|
27
27
|
offset: effectiveOffset(args),
|
|
28
28
|
});
|
|
29
29
|
}
|
|
@@ -32,7 +32,7 @@ export async function handler(args: DataflowArgs, ctx: McpToolContext): Promise<
|
|
|
32
32
|
file: args.file,
|
|
33
33
|
kind: args.kind,
|
|
34
34
|
noTests: args.no_tests,
|
|
35
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
35
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.query ?? 100, ctx.MCP_MAX_LIMIT),
|
|
36
36
|
offset: effectiveOffset(args),
|
|
37
37
|
});
|
|
38
38
|
}
|
|
@@ -19,7 +19,7 @@ export async function handler(args: ExportGraphArgs, ctx: McpToolContext): Promi
|
|
|
19
19
|
const fileLevel = args.file_level !== false;
|
|
20
20
|
const exportLimit = args.limit
|
|
21
21
|
? Math.min(args.limit, MCP_MAX_LIMIT)
|
|
22
|
-
: (MCP_DEFAULTS
|
|
22
|
+
: (MCP_DEFAULTS.export_graph ?? 500);
|
|
23
23
|
|
|
24
24
|
let result: unknown;
|
|
25
25
|
try {
|
package/src/mcp/tools/index.ts
CHANGED
package/src/mcp/tools/path.ts
CHANGED
|
@@ -10,9 +10,19 @@ interface PathArgs {
|
|
|
10
10
|
from_file?: string;
|
|
11
11
|
to_file?: string;
|
|
12
12
|
no_tests?: boolean;
|
|
13
|
+
file_mode?: boolean;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export async function handler(args: PathArgs, ctx: McpToolContext): Promise<unknown> {
|
|
17
|
+
if (args.file_mode) {
|
|
18
|
+
const { filePathData } = await ctx.getQueries();
|
|
19
|
+
return filePathData(args.from, args.to, ctx.dbPath, {
|
|
20
|
+
maxDepth: args.depth ?? 10,
|
|
21
|
+
edgeKinds: args.edge_kinds,
|
|
22
|
+
reverse: false,
|
|
23
|
+
noTests: args.no_tests,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
16
26
|
const { pathData } = await ctx.getQueries();
|
|
17
27
|
return pathData(args.from, args.to, ctx.dbPath, {
|
|
18
28
|
maxDepth: args.depth ?? 10,
|
package/src/mcp/tools/query.ts
CHANGED
|
@@ -41,7 +41,7 @@ export async function handler(args: QueryArgs, ctx: McpToolContext): Promise<unk
|
|
|
41
41
|
file: args.file,
|
|
42
42
|
kind: args.kind,
|
|
43
43
|
noTests: args.no_tests,
|
|
44
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
44
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.query ?? 100, ctx.MCP_MAX_LIMIT),
|
|
45
45
|
offset: effectiveOffset(args),
|
|
46
46
|
});
|
|
47
47
|
}
|
|
@@ -14,7 +14,7 @@ interface SemanticSearchArgs {
|
|
|
14
14
|
export async function handler(args: SemanticSearchArgs, ctx: McpToolContext): Promise<unknown> {
|
|
15
15
|
const mode = args.mode || 'hybrid';
|
|
16
16
|
const searchOpts = {
|
|
17
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
17
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.semantic_search ?? 100, ctx.MCP_MAX_LIMIT),
|
|
18
18
|
offset: effectiveOffset(args),
|
|
19
19
|
minScore: args.min_score,
|
|
20
20
|
};
|
|
@@ -23,7 +23,7 @@ export async function handler(args: SequenceArgs, ctx: McpToolContext): Promise<
|
|
|
23
23
|
kind: args.kind,
|
|
24
24
|
dataflow: args.dataflow,
|
|
25
25
|
noTests: args.no_tests,
|
|
26
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
26
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.execution_flow ?? 100, ctx.MCP_MAX_LIMIT),
|
|
27
27
|
offset: effectiveOffset(args),
|
|
28
28
|
});
|
|
29
29
|
return args.format === 'json' ? seqResult : { text: sequenceToMermaid(seqResult), ...seqResult };
|
|
@@ -18,7 +18,7 @@ export async function handler(args: SymbolChildrenArgs, ctx: McpToolContext): Pr
|
|
|
18
18
|
file: args.file,
|
|
19
19
|
kind: args.kind,
|
|
20
20
|
noTests: args.no_tests,
|
|
21
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
21
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.context ?? 100, ctx.MCP_MAX_LIMIT),
|
|
22
22
|
offset: effectiveOffset(args),
|
|
23
23
|
});
|
|
24
24
|
}
|
package/src/mcp/tools/triage.ts
CHANGED
|
@@ -30,7 +30,7 @@ export async function handler(args: TriageArgs, ctx: McpToolContext): Promise<un
|
|
|
30
30
|
return hotspotsData(ctx.dbPath, {
|
|
31
31
|
metric,
|
|
32
32
|
level: args.level,
|
|
33
|
-
limit: Math.min(args.limit ?? MCP_DEFAULTS
|
|
33
|
+
limit: Math.min(args.limit ?? MCP_DEFAULTS.hotspots ?? 100, MCP_MAX_LIMIT),
|
|
34
34
|
offset: effectiveOffset(args),
|
|
35
35
|
noTests: args.no_tests,
|
|
36
36
|
});
|
|
@@ -20,7 +20,6 @@ export function audit(
|
|
|
20
20
|
customDbPath: string | undefined,
|
|
21
21
|
opts: AuditOpts = {},
|
|
22
22
|
): void {
|
|
23
|
-
// biome-ignore lint/suspicious/noExplicitAny: audit data shape is dynamic
|
|
24
23
|
const data: any = auditData(target, customDbPath, opts as any);
|
|
25
24
|
|
|
26
25
|
if (outputResult(data, null, opts)) return;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { diffImpactData } from '../domain/analysis/diff-impact.js';
|
|
2
|
+
|
|
3
|
+
export function diffImpactMermaid(
|
|
4
|
+
customDbPath: string,
|
|
5
|
+
opts: {
|
|
6
|
+
noTests?: boolean;
|
|
7
|
+
depth?: number;
|
|
8
|
+
staged?: boolean;
|
|
9
|
+
ref?: string;
|
|
10
|
+
includeImplementors?: boolean;
|
|
11
|
+
limit?: number;
|
|
12
|
+
offset?: number;
|
|
13
|
+
config?: any;
|
|
14
|
+
} = {},
|
|
15
|
+
): string {
|
|
16
|
+
const data: any = diffImpactData(customDbPath, opts);
|
|
17
|
+
if ('error' in data) return data.error as string;
|
|
18
|
+
if (data.changedFiles === 0 || data.affectedFunctions.length === 0) {
|
|
19
|
+
return 'flowchart TB\n none["No impacted functions detected"]';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const newFileSet = new Set(data.newFiles || []);
|
|
23
|
+
const lines = ['flowchart TB'];
|
|
24
|
+
|
|
25
|
+
// Assign stable Mermaid node IDs
|
|
26
|
+
let nodeCounter = 0;
|
|
27
|
+
const nodeIdMap = new Map<string, string>();
|
|
28
|
+
const nodeLabels = new Map<string, string>();
|
|
29
|
+
function nodeId(key: string, label?: string): string {
|
|
30
|
+
if (!nodeIdMap.has(key)) {
|
|
31
|
+
nodeIdMap.set(key, `n${nodeCounter++}`);
|
|
32
|
+
if (label) nodeLabels.set(key, label);
|
|
33
|
+
}
|
|
34
|
+
return nodeIdMap.get(key)!;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Register all nodes (changed functions + their callers)
|
|
38
|
+
for (const fn of data.affectedFunctions) {
|
|
39
|
+
nodeId(`${fn.file}::${fn.name}:${fn.line}`, fn.name);
|
|
40
|
+
for (const callers of Object.values(fn.levels || {})) {
|
|
41
|
+
for (const c of callers as Array<{ name: string; file: string; line: number }>) {
|
|
42
|
+
nodeId(`${c.file}::${c.name}:${c.line}`, c.name);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Collect all edges and determine blast radius
|
|
48
|
+
const allEdges = new Set<string>();
|
|
49
|
+
const edgeFromNodes = new Set<string>();
|
|
50
|
+
const edgeToNodes = new Set<string>();
|
|
51
|
+
const changedKeys = new Set<string>();
|
|
52
|
+
|
|
53
|
+
for (const fn of data.affectedFunctions) {
|
|
54
|
+
changedKeys.add(`${fn.file}::${fn.name}:${fn.line}`);
|
|
55
|
+
for (const edge of fn.edges || []) {
|
|
56
|
+
const edgeKey = `${edge.from}|${edge.to}`;
|
|
57
|
+
if (!allEdges.has(edgeKey)) {
|
|
58
|
+
allEdges.add(edgeKey);
|
|
59
|
+
edgeFromNodes.add(edge.from);
|
|
60
|
+
edgeToNodes.add(edge.to);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Blast radius: caller nodes that are never a source (leaf nodes of the impact tree)
|
|
66
|
+
const blastRadiusKeys = new Set<string>();
|
|
67
|
+
for (const key of edgeToNodes) {
|
|
68
|
+
if (!edgeFromNodes.has(key) && !changedKeys.has(key)) {
|
|
69
|
+
blastRadiusKeys.add(key);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Intermediate callers: not changed, not blast radius
|
|
74
|
+
const intermediateKeys = new Set<string>();
|
|
75
|
+
for (const key of edgeToNodes) {
|
|
76
|
+
if (!changedKeys.has(key) && !blastRadiusKeys.has(key)) {
|
|
77
|
+
intermediateKeys.add(key);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Group changed functions by file
|
|
82
|
+
const fileGroups = new Map<string, typeof data.affectedFunctions>();
|
|
83
|
+
for (const fn of data.affectedFunctions) {
|
|
84
|
+
if (!fileGroups.has(fn.file)) fileGroups.set(fn.file, []);
|
|
85
|
+
fileGroups.get(fn.file)!.push(fn);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Emit changed-file subgraphs
|
|
89
|
+
let sgCounter = 0;
|
|
90
|
+
for (const [file, fns] of fileGroups) {
|
|
91
|
+
const isNew = newFileSet.has(file);
|
|
92
|
+
const tag = isNew ? 'new' : 'modified';
|
|
93
|
+
const sgId = `sg${sgCounter++}`;
|
|
94
|
+
lines.push(` subgraph ${sgId}["${file} **(${tag})**"]`);
|
|
95
|
+
for (const fn of fns) {
|
|
96
|
+
const key = `${fn.file}::${fn.name}:${fn.line}`;
|
|
97
|
+
lines.push(` ${nodeIdMap.get(key)}["${fn.name}"]`);
|
|
98
|
+
}
|
|
99
|
+
lines.push(' end');
|
|
100
|
+
const style = isNew ? 'fill:#e8f5e9,stroke:#4caf50' : 'fill:#fff3e0,stroke:#ff9800';
|
|
101
|
+
lines.push(` style ${sgId} ${style}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Emit intermediate caller nodes (outside subgraphs)
|
|
105
|
+
for (const key of intermediateKeys) {
|
|
106
|
+
lines.push(` ${nodeIdMap.get(key)}["${nodeLabels.get(key)}"]`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Emit blast radius subgraph
|
|
110
|
+
if (blastRadiusKeys.size > 0) {
|
|
111
|
+
const sgId = `sg${sgCounter++}`;
|
|
112
|
+
lines.push(` subgraph ${sgId}["Callers **(blast radius)**"]`);
|
|
113
|
+
for (const key of blastRadiusKeys) {
|
|
114
|
+
lines.push(` ${nodeIdMap.get(key)}["${nodeLabels.get(key)}"]`);
|
|
115
|
+
}
|
|
116
|
+
lines.push(' end');
|
|
117
|
+
lines.push(` style ${sgId} fill:#f3e5f5,stroke:#9c27b0`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Emit edges (impact flows from changed fn toward callers)
|
|
121
|
+
for (const edgeKey of allEdges) {
|
|
122
|
+
const [from, to] = edgeKey.split('|') as [string, string];
|
|
123
|
+
lines.push(` ${nodeIdMap.get(from)} --> ${nodeIdMap.get(to)}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return lines.join('\n');
|
|
127
|
+
}
|
package/src/presentation/flow.ts
CHANGED
|
@@ -26,7 +26,6 @@ export function flow(
|
|
|
26
26
|
noTests: opts.noTests,
|
|
27
27
|
limit: opts.limit,
|
|
28
28
|
offset: opts.offset,
|
|
29
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic shape from listEntryPointsData
|
|
30
29
|
}) as any;
|
|
31
30
|
if (outputResult(data, 'entries', opts)) return;
|
|
32
31
|
if (data.count === 0) {
|
|
@@ -56,7 +55,6 @@ export function flow(
|
|
|
56
55
|
return;
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic shape from flowData
|
|
60
58
|
const data = flowData(name, dbPath, opts) as any;
|
|
61
59
|
if (outputResult(data, 'steps', opts)) return;
|
|
62
60
|
|
|
@@ -23,7 +23,6 @@ interface ManifestoViolationRow {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export function manifesto(customDbPath: string | undefined, opts: ManifestoOpts = {}): void {
|
|
26
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic shape from manifestoData
|
|
27
26
|
const data = manifestoData(customDbPath, opts as any) as any;
|
|
28
27
|
|
|
29
28
|
if (outputResult(data, 'violations', opts)) {
|