@monoes/monograph 1.2.0 → 1.2.2
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/.monomind/loops/mastermind-review-1782162423447.json +16 -0
- package/__tests__/mcp-tools/cypher.test.ts +10 -6
- package/__tests__/mcp-tools/detect-changes.test.ts +14 -11
- package/__tests__/pipeline/phases/wildcard-synthesis.test.ts +4 -4
- package/__tests__/search/embed-batch-config.test.ts +7 -7
- package/__tests__/search/hybrid-query.test.ts +3 -1
- package/__tests__/web/api.test.ts +1 -1
- package/dist/src/analysis/churn-cache.d.ts.map +1 -1
- package/dist/src/analysis/churn-cache.js +19 -6
- package/dist/src/analysis/churn-cache.js.map +1 -1
- package/dist/src/analysis/churn-trend.d.ts.map +1 -1
- package/dist/src/analysis/churn-trend.js +50 -6
- package/dist/src/analysis/churn-trend.js.map +1 -1
- package/dist/src/analysis/cluster-quality.d.ts +3 -0
- package/dist/src/analysis/cluster-quality.d.ts.map +1 -1
- package/dist/src/analysis/cluster-quality.js +18 -12
- package/dist/src/analysis/cluster-quality.js.map +1 -1
- package/dist/src/analysis/coverage-gaps.d.ts +3 -0
- package/dist/src/analysis/coverage-gaps.d.ts.map +1 -1
- package/dist/src/analysis/coverage-gaps.js +40 -1
- package/dist/src/analysis/coverage-gaps.js.map +1 -1
- package/dist/src/analysis/dep-classification.d.ts +2 -0
- package/dist/src/analysis/dep-classification.d.ts.map +1 -1
- package/dist/src/analysis/dep-classification.js +30 -0
- package/dist/src/analysis/dep-classification.js.map +1 -1
- package/dist/src/analysis/dependency-health.d.ts +4 -0
- package/dist/src/analysis/dependency-health.d.ts.map +1 -1
- package/dist/src/analysis/dependency-health.js +28 -0
- package/dist/src/analysis/dependency-health.js.map +1 -1
- package/dist/src/analysis/duplicate-exports.d.ts +9 -5
- package/dist/src/analysis/duplicate-exports.d.ts.map +1 -1
- package/dist/src/analysis/duplicate-exports.js +26 -2
- package/dist/src/analysis/duplicate-exports.js.map +1 -1
- package/dist/src/analysis/feature-flags.d.ts.map +1 -1
- package/dist/src/analysis/feature-flags.js +36 -17
- package/dist/src/analysis/feature-flags.js.map +1 -1
- package/dist/src/analysis/node-similarity.d.ts +19 -0
- package/dist/src/analysis/node-similarity.d.ts.map +1 -1
- package/dist/src/analysis/node-similarity.js +34 -3
- package/dist/src/analysis/node-similarity.js.map +1 -1
- package/dist/src/analysis/private-type-leaks.d.ts +4 -0
- package/dist/src/analysis/private-type-leaks.d.ts.map +1 -1
- package/dist/src/analysis/private-type-leaks.js +43 -2
- package/dist/src/analysis/private-type-leaks.js.map +1 -1
- package/dist/src/analysis/project-state.d.ts +2 -0
- package/dist/src/analysis/project-state.d.ts.map +1 -1
- package/dist/src/analysis/project-state.js +18 -7
- package/dist/src/analysis/project-state.js.map +1 -1
- package/dist/src/analysis/suppressions.d.ts.map +1 -1
- package/dist/src/analysis/suppressions.js +3 -1
- package/dist/src/analysis/suppressions.js.map +1 -1
- package/dist/src/analysis/trace.d.ts +5 -3
- package/dist/src/analysis/trace.d.ts.map +1 -1
- package/dist/src/analysis/trace.js +59 -53
- package/dist/src/analysis/trace.js.map +1 -1
- package/dist/src/analysis/unused-class-members.d.ts.map +1 -1
- package/dist/src/analysis/unused-class-members.js +7 -1
- package/dist/src/analysis/unused-class-members.js.map +1 -1
- package/dist/src/analysis/worker-pool.d.ts +3 -0
- package/dist/src/analysis/worker-pool.d.ts.map +1 -1
- package/dist/src/analysis/worker-pool.js +30 -8
- package/dist/src/analysis/worker-pool.js.map +1 -1
- package/dist/src/cli/augment.d.ts.map +1 -1
- package/dist/src/cli/augment.js +10 -3
- package/dist/src/cli/augment.js.map +1 -1
- package/dist/src/cli/skill-gen.js +3 -0
- package/dist/src/cli/skill-gen.js.map +1 -1
- package/dist/src/export/sarif.js +5 -5
- package/dist/src/export/sarif.js.map +1 -1
- package/dist/src/graph/analyzer.d.ts.map +1 -1
- package/dist/src/graph/analyzer.js +17 -2
- package/dist/src/graph/analyzer.js.map +1 -1
- package/dist/src/graph/author-analytics.d.ts +2 -0
- package/dist/src/graph/author-analytics.d.ts.map +1 -1
- package/dist/src/graph/author-analytics.js +39 -5
- package/dist/src/graph/author-analytics.js.map +1 -1
- package/dist/src/graph/baseline.d.ts +5 -0
- package/dist/src/graph/baseline.d.ts.map +1 -1
- package/dist/src/graph/baseline.js +65 -18
- package/dist/src/graph/baseline.js.map +1 -1
- package/dist/src/graph/clone-detector.d.ts.map +1 -1
- package/dist/src/graph/clone-detector.js +19 -33
- package/dist/src/graph/clone-detector.js.map +1 -1
- package/dist/src/graph/clone-families.d.ts +2 -0
- package/dist/src/graph/clone-families.d.ts.map +1 -1
- package/dist/src/graph/clone-families.js +38 -10
- package/dist/src/graph/clone-families.js.map +1 -1
- package/dist/src/graph/codeowners-extended.d.ts +17 -0
- package/dist/src/graph/codeowners-extended.d.ts.map +1 -1
- package/dist/src/graph/codeowners-extended.js +42 -0
- package/dist/src/graph/codeowners-extended.js.map +1 -1
- package/dist/src/graph/codeowners-gitlab.d.ts +21 -0
- package/dist/src/graph/codeowners-gitlab.d.ts.map +1 -1
- package/dist/src/graph/codeowners-gitlab.js +37 -0
- package/dist/src/graph/codeowners-gitlab.js.map +1 -1
- package/dist/src/graph/codeowners.d.ts +10 -0
- package/dist/src/graph/codeowners.d.ts.map +1 -1
- package/dist/src/graph/codeowners.js +24 -2
- package/dist/src/graph/codeowners.js.map +1 -1
- package/dist/src/graph/complexity.d.ts +10 -0
- package/dist/src/graph/complexity.d.ts.map +1 -1
- package/dist/src/graph/complexity.js +93 -43
- package/dist/src/graph/complexity.js.map +1 -1
- package/dist/src/graph/cross-reference-findings.d.ts.map +1 -1
- package/dist/src/graph/cross-reference-findings.js +19 -2
- package/dist/src/graph/cross-reference-findings.js.map +1 -1
- package/dist/src/graph/cross-reference.d.ts +4 -0
- package/dist/src/graph/cross-reference.d.ts.map +1 -1
- package/dist/src/graph/cross-reference.js +23 -0
- package/dist/src/graph/cross-reference.js.map +1 -1
- package/dist/src/graph/cycle-detection.d.ts +2 -0
- package/dist/src/graph/cycle-detection.d.ts.map +1 -1
- package/dist/src/graph/cycle-detection.js +26 -3
- package/dist/src/graph/cycle-detection.js.map +1 -1
- package/dist/src/graph/cycles.d.ts +11 -3
- package/dist/src/graph/cycles.d.ts.map +1 -1
- package/dist/src/graph/cycles.js +121 -83
- package/dist/src/graph/cycles.js.map +1 -1
- package/dist/src/graph/dead-code.d.ts +23 -0
- package/dist/src/graph/dead-code.d.ts.map +1 -1
- package/dist/src/graph/dead-code.js +53 -13
- package/dist/src/graph/dead-code.js.map +1 -1
- package/dist/src/graph/dependency-closure.d.ts.map +1 -1
- package/dist/src/graph/dependency-closure.js +20 -4
- package/dist/src/graph/dependency-closure.js.map +1 -1
- package/dist/src/graph/dfs.d.ts +14 -0
- package/dist/src/graph/dfs.d.ts.map +1 -1
- package/dist/src/graph/dfs.js +61 -0
- package/dist/src/graph/dfs.js.map +1 -1
- package/dist/src/graph/duplication-stats.d.ts.map +1 -1
- package/dist/src/graph/duplication-stats.js +19 -3
- package/dist/src/graph/duplication-stats.js.map +1 -1
- package/dist/src/graph/edge-filter.d.ts +2 -0
- package/dist/src/graph/edge-filter.d.ts.map +1 -1
- package/dist/src/graph/edge-filter.js +26 -12
- package/dist/src/graph/edge-filter.js.map +1 -1
- package/dist/src/graph/health-score.d.ts +8 -0
- package/dist/src/graph/health-score.d.ts.map +1 -1
- package/dist/src/graph/health-score.js +48 -17
- package/dist/src/graph/health-score.js.map +1 -1
- package/dist/src/graph/hotspots.d.ts +7 -0
- package/dist/src/graph/hotspots.d.ts.map +1 -1
- package/dist/src/graph/hotspots.js +50 -5
- package/dist/src/graph/hotspots.js.map +1 -1
- package/dist/src/graph/import-chain.d.ts +17 -1
- package/dist/src/graph/import-chain.d.ts.map +1 -1
- package/dist/src/graph/import-chain.js +68 -19
- package/dist/src/graph/import-chain.js.map +1 -1
- package/dist/src/graph/loader.d.ts.map +1 -1
- package/dist/src/graph/loader.js +9 -10
- package/dist/src/graph/loader.js.map +1 -1
- package/dist/src/graph/maintainability.d.ts +8 -0
- package/dist/src/graph/maintainability.d.ts.map +1 -1
- package/dist/src/graph/maintainability.js +65 -10
- package/dist/src/graph/maintainability.js.map +1 -1
- package/dist/src/graph/mirrored-dirs.d.ts +4 -0
- package/dist/src/graph/mirrored-dirs.d.ts.map +1 -1
- package/dist/src/graph/mirrored-dirs.js +48 -13
- package/dist/src/graph/mirrored-dirs.js.map +1 -1
- package/dist/src/graph/narrowing.d.ts +15 -0
- package/dist/src/graph/narrowing.d.ts.map +1 -1
- package/dist/src/graph/narrowing.js +33 -0
- package/dist/src/graph/narrowing.js.map +1 -1
- package/dist/src/graph/node-search.d.ts +3 -0
- package/dist/src/graph/node-search.d.ts.map +1 -1
- package/dist/src/graph/node-search.js +37 -4
- package/dist/src/graph/node-search.js.map +1 -1
- package/dist/src/graph/normalize-id.d.ts +4 -0
- package/dist/src/graph/normalize-id.d.ts.map +1 -1
- package/dist/src/graph/normalize-id.js +25 -2
- package/dist/src/graph/normalize-id.js.map +1 -1
- package/dist/src/graph/pagerank.d.ts +7 -0
- package/dist/src/graph/pagerank.d.ts.map +1 -1
- package/dist/src/graph/pagerank.js +49 -2
- package/dist/src/graph/pagerank.js.map +1 -1
- package/dist/src/graph/prune.d.ts +31 -0
- package/dist/src/graph/prune.d.ts.map +1 -1
- package/dist/src/graph/prune.js +65 -0
- package/dist/src/graph/prune.js.map +1 -1
- package/dist/src/graph/regex-search.d.ts +10 -2
- package/dist/src/graph/regex-search.d.ts.map +1 -1
- package/dist/src/graph/regex-search.js +33 -4
- package/dist/src/graph/regex-search.js.map +1 -1
- package/dist/src/graph/regression.d.ts +5 -0
- package/dist/src/graph/regression.d.ts.map +1 -1
- package/dist/src/graph/regression.js +45 -23
- package/dist/src/graph/regression.js.map +1 -1
- package/dist/src/graph/ripple-impact.d.ts +27 -0
- package/dist/src/graph/ripple-impact.d.ts.map +1 -1
- package/dist/src/graph/ripple-impact.js +55 -7
- package/dist/src/graph/ripple-impact.js.map +1 -1
- package/dist/src/graph/risk-profile.d.ts +7 -0
- package/dist/src/graph/risk-profile.d.ts.map +1 -1
- package/dist/src/graph/risk-profile.js +82 -48
- package/dist/src/graph/risk-profile.js.map +1 -1
- package/dist/src/graph/shingle-filter.d.ts.map +1 -1
- package/dist/src/graph/shingle-filter.js +25 -26
- package/dist/src/graph/shingle-filter.js.map +1 -1
- package/dist/src/graph/statistics.d.ts +19 -0
- package/dist/src/graph/statistics.d.ts.map +1 -1
- package/dist/src/graph/statistics.js +53 -40
- package/dist/src/graph/statistics.js.map +1 -1
- package/dist/src/graph/stats.d.ts +2 -0
- package/dist/src/graph/stats.d.ts.map +1 -1
- package/dist/src/graph/stats.js +54 -8
- package/dist/src/graph/stats.js.map +1 -1
- package/dist/src/graph/subgraph.d.ts +5 -0
- package/dist/src/graph/subgraph.d.ts.map +1 -1
- package/dist/src/graph/subgraph.js +73 -9
- package/dist/src/graph/subgraph.js.map +1 -1
- package/dist/src/graph/topo-sort.d.ts +15 -0
- package/dist/src/graph/topo-sort.d.ts.map +1 -1
- package/dist/src/graph/topo-sort.js +83 -10
- package/dist/src/graph/topo-sort.js.map +1 -1
- package/dist/src/graph/wcc.d.ts +29 -0
- package/dist/src/graph/wcc.d.ts.map +1 -1
- package/dist/src/graph/wcc.js +122 -39
- package/dist/src/graph/wcc.js.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp-tools/api-impact.d.ts.map +1 -1
- package/dist/src/mcp-tools/api-impact.js +13 -6
- package/dist/src/mcp-tools/api-impact.js.map +1 -1
- package/dist/src/mcp-tools/context.d.ts.map +1 -1
- package/dist/src/mcp-tools/context.js +19 -29
- package/dist/src/mcp-tools/context.js.map +1 -1
- package/dist/src/mcp-tools/cypher.d.ts +11 -0
- package/dist/src/mcp-tools/cypher.d.ts.map +1 -1
- package/dist/src/mcp-tools/cypher.js +13 -1
- package/dist/src/mcp-tools/cypher.js.map +1 -1
- package/dist/src/mcp-tools/detect-changes.d.ts.map +1 -1
- package/dist/src/mcp-tools/detect-changes.js +35 -20
- package/dist/src/mcp-tools/detect-changes.js.map +1 -1
- package/dist/src/mcp-tools/explain.d.ts.map +1 -1
- package/dist/src/mcp-tools/explain.js +4 -1
- package/dist/src/mcp-tools/explain.js.map +1 -1
- package/dist/src/mcp-tools/graph-query.d.ts +2 -0
- package/dist/src/mcp-tools/graph-query.d.ts.map +1 -1
- package/dist/src/mcp-tools/graph-query.js +20 -3
- package/dist/src/mcp-tools/graph-query.js.map +1 -1
- package/dist/src/mcp-tools/group-list.d.ts +1 -0
- package/dist/src/mcp-tools/group-list.d.ts.map +1 -1
- package/dist/src/mcp-tools/group-list.js +7 -9
- package/dist/src/mcp-tools/group-list.js.map +1 -1
- package/dist/src/mcp-tools/impact.d.ts.map +1 -1
- package/dist/src/mcp-tools/impact.js +20 -59
- package/dist/src/mcp-tools/impact.js.map +1 -1
- package/dist/src/mcp-tools/neighbors.d.ts.map +1 -1
- package/dist/src/mcp-tools/neighbors.js +24 -33
- package/dist/src/mcp-tools/neighbors.js.map +1 -1
- package/dist/src/mcp-tools/query.d.ts +2 -0
- package/dist/src/mcp-tools/query.d.ts.map +1 -1
- package/dist/src/mcp-tools/query.js +1 -0
- package/dist/src/mcp-tools/query.js.map +1 -1
- package/dist/src/mcp-tools/rename.d.ts.map +1 -1
- package/dist/src/mcp-tools/rename.js +12 -7
- package/dist/src/mcp-tools/rename.js.map +1 -1
- package/dist/src/mcp-tools/route-map.d.ts.map +1 -1
- package/dist/src/mcp-tools/route-map.js +19 -23
- package/dist/src/mcp-tools/route-map.js.map +1 -1
- package/dist/src/mcp-tools/shape-check.d.ts.map +1 -1
- package/dist/src/mcp-tools/shape-check.js +17 -13
- package/dist/src/mcp-tools/shape-check.js.map +1 -1
- package/dist/src/parsers/loader.js +6 -5
- package/dist/src/parsers/loader.js.map +1 -1
- package/dist/src/pipeline/cluster-only.d.ts.map +1 -1
- package/dist/src/pipeline/cluster-only.js +8 -4
- package/dist/src/pipeline/cluster-only.js.map +1 -1
- package/dist/src/pipeline/orchestrator.d.ts +2 -0
- package/dist/src/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/src/pipeline/orchestrator.js +19 -0
- package/dist/src/pipeline/orchestrator.js.map +1 -1
- package/dist/src/pipeline/phases/boundary.d.ts +2 -0
- package/dist/src/pipeline/phases/boundary.d.ts.map +1 -1
- package/dist/src/pipeline/phases/boundary.js +31 -2
- package/dist/src/pipeline/phases/boundary.js.map +1 -1
- package/dist/src/pipeline/phases/communities.d.ts +14 -0
- package/dist/src/pipeline/phases/communities.d.ts.map +1 -1
- package/dist/src/pipeline/phases/communities.js +58 -5
- package/dist/src/pipeline/phases/communities.js.map +1 -1
- package/dist/src/pipeline/phases/contextual-proximity.d.ts.map +1 -1
- package/dist/src/pipeline/phases/contextual-proximity.js +21 -14
- package/dist/src/pipeline/phases/contextual-proximity.js.map +1 -1
- package/dist/src/pipeline/phases/cross-file.d.ts.map +1 -1
- package/dist/src/pipeline/phases/cross-file.js +35 -14
- package/dist/src/pipeline/phases/cross-file.js.map +1 -1
- package/dist/src/pipeline/phases/field-access.d.ts.map +1 -1
- package/dist/src/pipeline/phases/field-access.js +9 -4
- package/dist/src/pipeline/phases/field-access.js.map +1 -1
- package/dist/src/pipeline/phases/god-nodes.d.ts +4 -0
- package/dist/src/pipeline/phases/god-nodes.d.ts.map +1 -1
- package/dist/src/pipeline/phases/god-nodes.js +43 -9
- package/dist/src/pipeline/phases/god-nodes.js.map +1 -1
- package/dist/src/pipeline/phases/import-resolver.d.ts +11 -0
- package/dist/src/pipeline/phases/import-resolver.d.ts.map +1 -1
- package/dist/src/pipeline/phases/import-resolver.js +34 -7
- package/dist/src/pipeline/phases/import-resolver.js.map +1 -1
- package/dist/src/pipeline/phases/leiden.d.ts.map +1 -1
- package/dist/src/pipeline/phases/leiden.js +27 -19
- package/dist/src/pipeline/phases/leiden.js.map +1 -1
- package/dist/src/pipeline/phases/markdown.d.ts.map +1 -1
- package/dist/src/pipeline/phases/markdown.js +10 -5
- package/dist/src/pipeline/phases/markdown.js.map +1 -1
- package/dist/src/pipeline/phases/pdf-parse.d.ts.map +1 -1
- package/dist/src/pipeline/phases/pdf-parse.js +18 -3
- package/dist/src/pipeline/phases/pdf-parse.js.map +1 -1
- package/dist/src/pipeline/phases/processes.d.ts.map +1 -1
- package/dist/src/pipeline/phases/processes.js +26 -9
- package/dist/src/pipeline/phases/processes.js.map +1 -1
- package/dist/src/pipeline/phases/re-export-propagation.d.ts.map +1 -1
- package/dist/src/pipeline/phases/re-export-propagation.js +33 -14
- package/dist/src/pipeline/phases/re-export-propagation.js.map +1 -1
- package/dist/src/pipeline/phases/reachability.d.ts.map +1 -1
- package/dist/src/pipeline/phases/reachability.js +42 -26
- package/dist/src/pipeline/phases/reachability.js.map +1 -1
- package/dist/src/pipeline/phases/routes.d.ts.map +1 -1
- package/dist/src/pipeline/phases/routes.js +30 -21
- package/dist/src/pipeline/phases/routes.js.map +1 -1
- package/dist/src/pipeline/phases/scope-resolution.d.ts.map +1 -1
- package/dist/src/pipeline/phases/scope-resolution.js +93 -63
- package/dist/src/pipeline/phases/scope-resolution.js.map +1 -1
- package/dist/src/pipeline/runner.d.ts +4 -0
- package/dist/src/pipeline/runner.d.ts.map +1 -1
- package/dist/src/pipeline/runner.js +30 -11
- package/dist/src/pipeline/runner.js.map +1 -1
- package/dist/src/query/cypher-parser.d.ts +20 -0
- package/dist/src/query/cypher-parser.d.ts.map +1 -1
- package/dist/src/query/cypher-parser.js +73 -0
- package/dist/src/query/cypher-parser.js.map +1 -1
- package/dist/src/search/embed-batch.d.ts.map +1 -1
- package/dist/src/search/embed-batch.js +4 -1
- package/dist/src/search/embed-batch.js.map +1 -1
- package/dist/src/search/hybrid-query.d.ts +4 -0
- package/dist/src/search/hybrid-query.d.ts.map +1 -1
- package/dist/src/search/hybrid-query.js +5 -1
- package/dist/src/search/hybrid-query.js.map +1 -1
- package/dist/src/staleness/git-staleness.js +3 -3
- package/dist/src/staleness/git-staleness.js.map +1 -1
- package/dist/src/storage/db.d.ts.map +1 -1
- package/dist/src/storage/db.js +12 -0
- package/dist/src/storage/db.js.map +1 -1
- package/dist/src/storage/edge-store.d.ts +2 -0
- package/dist/src/storage/edge-store.d.ts.map +1 -1
- package/dist/src/storage/edge-store.js +26 -1
- package/dist/src/storage/edge-store.js.map +1 -1
- package/dist/src/storage/embedding-store.d.ts +16 -0
- package/dist/src/storage/embedding-store.d.ts.map +1 -1
- package/dist/src/storage/embedding-store.js +26 -2
- package/dist/src/storage/embedding-store.js.map +1 -1
- package/dist/src/storage/file-cache.d.ts +5 -0
- package/dist/src/storage/file-cache.d.ts.map +1 -1
- package/dist/src/storage/file-cache.js +35 -9
- package/dist/src/storage/file-cache.js.map +1 -1
- package/dist/src/storage/fts-store.d.ts +4 -0
- package/dist/src/storage/fts-store.d.ts.map +1 -1
- package/dist/src/storage/fts-store.js +8 -3
- package/dist/src/storage/fts-store.js.map +1 -1
- package/dist/src/storage/node-store.d.ts +2 -0
- package/dist/src/storage/node-store.d.ts.map +1 -1
- package/dist/src/storage/node-store.js +28 -1
- package/dist/src/storage/node-store.js.map +1 -1
- package/dist/src/wiki/wiki-generator.d.ts.map +1 -1
- package/dist/src/wiki/wiki-generator.js +5 -1
- package/dist/src/wiki/wiki-generator.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/__tests__/pipeline/runner.parallel.test.ts +2 -2
- package/src/analysis/churn-cache.ts +18 -7
- package/src/analysis/churn-trend.ts +35 -6
- package/src/analysis/cluster-quality.ts +20 -11
- package/src/analysis/coverage-gaps.ts +44 -1
- package/src/analysis/dep-classification.ts +34 -0
- package/src/analysis/dependency-health.ts +25 -0
- package/src/analysis/duplicate-exports.ts +40 -4
- package/src/analysis/feature-flags.ts +37 -17
- package/src/analysis/node-similarity.ts +45 -4
- package/src/analysis/private-type-leaks.ts +49 -2
- package/src/analysis/project-state.ts +19 -9
- package/src/analysis/suppressions.ts +4 -1
- package/src/analysis/trace.ts +73 -54
- package/src/analysis/unused-class-members.ts +8 -1
- package/src/analysis/worker-pool.ts +40 -8
- package/src/cli/augment.ts +10 -3
- package/src/cli/skill-gen.ts +3 -0
- package/src/export/sarif.ts +5 -5
- package/src/graph/analyzer.ts +26 -2
- package/src/graph/author-analytics.ts +45 -5
- package/src/graph/baseline.ts +78 -24
- package/src/graph/clone-detector.ts +22 -36
- package/src/graph/clone-families.ts +34 -10
- package/src/graph/codeowners-extended.ts +54 -0
- package/src/graph/codeowners-gitlab.ts +46 -0
- package/src/graph/codeowners.ts +33 -2
- package/src/graph/complexity.ts +102 -47
- package/src/graph/cross-reference-findings.ts +23 -2
- package/src/graph/cross-reference.ts +26 -0
- package/src/graph/cycle-detection.ts +22 -3
- package/src/graph/cycles.ts +155 -96
- package/src/graph/dead-code.ts +76 -17
- package/src/graph/dependency-closure.ts +24 -7
- package/src/graph/dfs.ts +78 -0
- package/src/graph/duplication-stats.ts +17 -6
- package/src/graph/edge-filter.ts +26 -12
- package/src/graph/health-score.ts +47 -17
- package/src/graph/hotspots.ts +57 -8
- package/src/graph/import-chain.ts +89 -19
- package/src/graph/loader.ts +10 -7
- package/src/graph/maintainability.ts +72 -22
- package/src/graph/mirrored-dirs.ts +45 -14
- package/src/graph/narrowing.ts +44 -0
- package/src/graph/node-search.ts +50 -4
- package/src/graph/normalize-id.ts +26 -2
- package/src/graph/pagerank.ts +70 -2
- package/src/graph/prune.ts +76 -0
- package/src/graph/regex-search.ts +38 -4
- package/src/graph/regression.ts +48 -23
- package/src/graph/ripple-impact.ts +71 -11
- package/src/graph/risk-profile.ts +98 -53
- package/src/graph/shingle-filter.ts +33 -27
- package/src/graph/statistics.ts +73 -45
- package/src/graph/stats.ts +50 -16
- package/src/graph/subgraph.ts +97 -25
- package/src/graph/topo-sort.ts +101 -16
- package/src/graph/wcc.ts +146 -37
- package/src/index.ts +1 -1
- package/src/mcp-tools/api-impact.ts +13 -6
- package/src/mcp-tools/context.ts +31 -40
- package/src/mcp-tools/cypher.ts +14 -1
- package/src/mcp-tools/detect-changes.ts +38 -23
- package/src/mcp-tools/explain.ts +4 -1
- package/src/mcp-tools/graph-query.ts +24 -3
- package/src/mcp-tools/group-list.ts +9 -11
- package/src/mcp-tools/impact.ts +26 -66
- package/src/mcp-tools/neighbors.ts +34 -39
- package/src/mcp-tools/query.ts +3 -0
- package/src/mcp-tools/rename.ts +9 -8
- package/src/mcp-tools/route-map.ts +21 -23
- package/src/mcp-tools/shape-check.ts +18 -14
- package/src/parsers/loader.ts +5 -5
- package/src/pipeline/cluster-only.ts +8 -4
- package/src/pipeline/orchestrator.ts +22 -0
- package/src/pipeline/phases/boundary.ts +40 -2
- package/src/pipeline/phases/communities.ts +66 -5
- package/src/pipeline/phases/contextual-proximity.ts +15 -14
- package/src/pipeline/phases/cross-file.ts +35 -14
- package/src/pipeline/phases/field-access.ts +11 -4
- package/src/pipeline/phases/god-nodes.ts +47 -10
- package/src/pipeline/phases/import-resolver.ts +37 -5
- package/src/pipeline/phases/leiden.ts +25 -18
- package/src/pipeline/phases/markdown.ts +12 -7
- package/src/pipeline/phases/pdf-parse.ts +19 -2
- package/src/pipeline/phases/processes.ts +27 -15
- package/src/pipeline/phases/re-export-propagation.ts +40 -18
- package/src/pipeline/phases/reachability.ts +39 -24
- package/src/pipeline/phases/routes.ts +32 -21
- package/src/pipeline/phases/scope-resolution.ts +110 -71
- package/src/pipeline/runner.ts +28 -11
- package/src/query/cypher-parser.ts +83 -0
- package/src/search/embed-batch.ts +4 -1
- package/src/search/hybrid-query.ts +11 -1
- package/src/staleness/git-staleness.ts +3 -3
- package/src/storage/db.ts +11 -0
- package/src/storage/edge-store.ts +34 -1
- package/src/storage/embedding-store.ts +38 -6
- package/src/storage/file-cache.ts +35 -21
- package/src/storage/fts-store.ts +12 -3
- package/src/storage/node-store.ts +39 -1
- package/src/wiki/wiki-generator.ts +5 -1
- package/src/coverage/runtime.ts +0 -249
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import { bidirectional } from 'graphology-shortest-path';
|
|
2
2
|
import betweennessCentrality from 'graphology-metrics/centrality/betweenness.js';
|
|
3
3
|
import { loadGraphFromDb } from './loader.js';
|
|
4
|
-
|
|
4
|
+
// ── TTL graph cache ───────────────────────────────────────────────────────────
|
|
5
|
+
// Avoids loading the full graph from the DB multiple times in the same request
|
|
6
|
+
// window (e.g. when getShortestPath and getBetweennessCentrality are called
|
|
7
|
+
// back-to-back on the same DB instance).
|
|
8
|
+
const GRAPH_CACHE_TTL_MS = 30_000;
|
|
9
|
+
const graphCache = new WeakMap();
|
|
10
|
+
function getOrLoadGraph(db) {
|
|
11
|
+
const cached = graphCache.get(db);
|
|
12
|
+
if (cached && Date.now() < cached.expiresAt)
|
|
13
|
+
return cached.graph;
|
|
5
14
|
const graph = loadGraphFromDb(db);
|
|
15
|
+
graphCache.set(db, { graph, expiresAt: Date.now() + GRAPH_CACHE_TTL_MS });
|
|
16
|
+
return graph;
|
|
17
|
+
}
|
|
18
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
19
|
+
export function getShortestPath(db, sourceId, targetId, maxDepth = 6) {
|
|
20
|
+
const graph = getOrLoadGraph(db);
|
|
6
21
|
if (!graph.hasNode(sourceId) || !graph.hasNode(targetId))
|
|
7
22
|
return null;
|
|
8
23
|
try {
|
|
@@ -24,7 +39,7 @@ export function getShortestPath(db, sourceId, targetId, maxDepth = 6) {
|
|
|
24
39
|
* structural bridges — refactoring them has wide blast radius.
|
|
25
40
|
*/
|
|
26
41
|
export function getBetweennessCentrality(db) {
|
|
27
|
-
const graph =
|
|
42
|
+
const graph = getOrLoadGraph(db);
|
|
28
43
|
if (graph.order === 0)
|
|
29
44
|
return new Map();
|
|
30
45
|
const scores = betweennessCentrality(graph, { normalized: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../../src/graph/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,qBAAqB,MAAM,8CAA8C,CAAC;AAGjF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,UAAU,eAAe,CAC7B,EAAe,EACf,QAAgB,EAChB,QAAgB,EAChB,QAAQ,GAAG,CAAC;IAEZ,MAAM,KAAK,GAAG,
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../../src/graph/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,qBAAqB,MAAM,8CAA8C,CAAC;AAGjF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,iFAAiF;AACjF,+EAA+E;AAC/E,4EAA4E;AAC5E,yCAAyC;AAEzC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAOlC,MAAM,UAAU,GAAG,IAAI,OAAO,EAAuB,CAAC;AAEtD,SAAS,cAAc,CAAC,EAAe;IACrC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IACjE,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IAClC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,kBAAkB,EAAE,CAAC,CAAC;IAC1E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,gFAAgF;AAEhF,MAAM,UAAU,eAAe,CAC7B,EAAe,EACf,QAAgB,EAChB,QAAgB,EAChB,QAAQ,GAAG,CAAC;IAEZ,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IACtE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,EAAe;IACtD,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,MAAc;IACzD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IACrD,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;KACnD,CAAC;AACJ,CAAC"}
|
|
@@ -15,4 +15,6 @@ export interface AuthorAnalyticsReport {
|
|
|
15
15
|
unownedFiles: number;
|
|
16
16
|
}
|
|
17
17
|
export declare function computeAuthorAnalytics(repoPath: string, db: MonographDb): AuthorAnalyticsReport;
|
|
18
|
+
/** Format AuthorAnalyticsReport as structured text for LLM navigation. */
|
|
19
|
+
export declare function formatAuthorAnalytics(report: AuthorAnalyticsReport): string;
|
|
18
20
|
//# sourceMappingURL=author-analytics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"author-analytics.d.ts","sourceRoot":"","sources":["../../../src/graph/author-analytics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAgBD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,qBAAqB,
|
|
1
|
+
{"version":3,"file":"author-analytics.d.ts","sourceRoot":"","sources":["../../../src/graph/author-analytics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAgBD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,qBAAqB,CAmJ/F;AAED,0EAA0E;AAC1E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CA+B3E"}
|
|
@@ -53,16 +53,22 @@ export function computeAuthorAnalytics(repoPath, db) {
|
|
|
53
53
|
if (commitCount.size === 0)
|
|
54
54
|
return EMPTY_REPORT;
|
|
55
55
|
// ── File ownership ─────────────────────────────────────────────────────────
|
|
56
|
-
// Get File nodes with degree > 2
|
|
56
|
+
// Get File nodes with degree > 2 — use JOIN+GROUP BY instead of correlated subquery
|
|
57
57
|
const fileRows = db.prepare(`
|
|
58
58
|
SELECT n.id, n.name, n.file_path
|
|
59
59
|
FROM nodes n
|
|
60
|
+
JOIN (
|
|
61
|
+
SELECT id, COUNT(*) AS deg
|
|
62
|
+
FROM (
|
|
63
|
+
SELECT source_id AS id FROM edges
|
|
64
|
+
UNION ALL
|
|
65
|
+
SELECT target_id AS id FROM edges
|
|
66
|
+
)
|
|
67
|
+
GROUP BY id
|
|
68
|
+
HAVING COUNT(*) > 2
|
|
69
|
+
) deg_tbl ON deg_tbl.id = n.id
|
|
60
70
|
WHERE n.label = 'File'
|
|
61
71
|
AND n.file_path IS NOT NULL
|
|
62
|
-
AND (
|
|
63
|
-
SELECT COUNT(*) FROM edges e
|
|
64
|
-
WHERE e.source_id = n.id OR e.target_id = n.id
|
|
65
|
-
) > 2
|
|
66
72
|
LIMIT 200
|
|
67
73
|
`).all();
|
|
68
74
|
// Map: file path → winning author email (majority owner) or null
|
|
@@ -148,4 +154,32 @@ export function computeAuthorAnalytics(repoPath, db) {
|
|
|
148
154
|
const topOwners = authors.filter(a => !a.isBot).slice(0, 5);
|
|
149
155
|
return { authors, topOwners, botAuthors, unownedFiles };
|
|
150
156
|
}
|
|
157
|
+
/** Format AuthorAnalyticsReport as structured text for LLM navigation. */
|
|
158
|
+
export function formatAuthorAnalytics(report) {
|
|
159
|
+
if (report.authors.length === 0) {
|
|
160
|
+
return 'Author analytics: no commit history found.';
|
|
161
|
+
}
|
|
162
|
+
const lines = [
|
|
163
|
+
`Author analytics: ${report.authors.length} contributor(s), ${report.unownedFiles} unowned file(s).`,
|
|
164
|
+
'',
|
|
165
|
+
];
|
|
166
|
+
if (report.topOwners.length > 0) {
|
|
167
|
+
lines.push('Top file owners (non-bot):');
|
|
168
|
+
for (const a of report.topOwners) {
|
|
169
|
+
const trend = a.churnTrend === 'accelerating' ? ' [↑ accelerating]'
|
|
170
|
+
: a.churnTrend === 'declining' ? ' [↓ declining]' : '';
|
|
171
|
+
lines.push(` ${a.author} files:${a.filesOwned} commits:${a.commitCount} recent30d:${a.recentCommits}${trend}`);
|
|
172
|
+
}
|
|
173
|
+
lines.push('');
|
|
174
|
+
}
|
|
175
|
+
if (report.botAuthors.length > 0) {
|
|
176
|
+
lines.push(`Bot/automation authors (${report.botAuthors.length}): ${report.botAuthors.join(', ')}`);
|
|
177
|
+
lines.push('');
|
|
178
|
+
}
|
|
179
|
+
if (report.unownedFiles > 0) {
|
|
180
|
+
lines.push(`Unowned files: ${report.unownedFiles} file(s) have no majority author (> 50% commits).`);
|
|
181
|
+
lines.push('Consider adding CODEOWNERS entries for these files.');
|
|
182
|
+
}
|
|
183
|
+
return lines.join('\n').trimEnd();
|
|
184
|
+
}
|
|
151
185
|
//# sourceMappingURL=author-analytics.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"author-analytics.js","sourceRoot":"","sources":["../../../src/graph/author-analytics.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"author-analytics.js","sourceRoot":"","sources":["../../../src/graph/author-analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ export interface BaselineFinding {
|
|
|
6
6
|
nodeId: string;
|
|
7
7
|
nodeName: string;
|
|
8
8
|
filePath: string | null;
|
|
9
|
+
startLine: number | null;
|
|
9
10
|
savedAt: string;
|
|
10
11
|
/** 16-hex SHA-256 fingerprint for stable deduplication across runs */
|
|
11
12
|
fingerprint?: string;
|
|
@@ -77,4 +78,8 @@ export interface BaselineVitals {
|
|
|
77
78
|
* Each baseline must carry BaselineVitals fields (nodeCount, edgeCount, …).
|
|
78
79
|
*/
|
|
79
80
|
export declare function computeTrend(before: BaselineData & BaselineVitals, after: BaselineData & BaselineVitals): TrendReport;
|
|
81
|
+
/** Format a list of ComparedFindings as structured text with file:line hints. */
|
|
82
|
+
export declare function formatComparedFindings(findings: ComparedFinding[], showAll?: boolean): string;
|
|
83
|
+
/** Format a TrendReport as structured text for LLM consumption. */
|
|
84
|
+
export declare function formatTrendReport(report: TrendReport): string;
|
|
80
85
|
//# sourceMappingURL=baseline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../../src/graph/baseline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAS3C,MAAM,WAAW,eAAe;IAC9B,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,oBAAoB,GAAG,eAAe,GAAG,gBAAgB,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;IACpH,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,eAAe,EAAE,EAC3B,WAAW,EAAE,MAAM,GAClB,IAAI,CAQN;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAOtE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,eAAe,EAAE,EAClC,QAAQ,EAAE,YAAY,GAAG,IAAI,GAC5B,eAAe,EAAE,CAmBnB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,GAClB,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../../src/graph/baseline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAS3C,MAAM,WAAW,eAAe;IAC9B,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,oBAAoB,GAAG,eAAe,GAAG,gBAAgB,GAAG,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,OAAO,CAAC;IACpH,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,eAAe,EAAE,EAC3B,WAAW,EAAE,MAAM,GAClB,IAAI,CAQN;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAOtE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,eAAe,EAAE,eAAe,EAAE,EAClC,QAAQ,EAAE,YAAY,GAAG,IAAI,GAC5B,eAAe,EAAE,CAmBnB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,GAClB,eAAe,EAAE,CAuJnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7E;AAID,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,CAAC;AAElE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,gBAAgB,EAAE,cAAc,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAuCD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,YAAY,GAAG,cAAc,EACrC,KAAK,EAAE,YAAY,GAAG,cAAc,GACnC,WAAW,CAiCb;AAED,iFAAiF;AACjF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE,OAAO,UAAQ,GAAG,MAAM,CAkC3F;AAED,mEAAmE;AACnE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAU7D"}
|
|
@@ -63,7 +63,7 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
63
63
|
const findings = [];
|
|
64
64
|
// Isolated nodes (no incoming or outgoing edges)
|
|
65
65
|
const isolated = db.prepare(`
|
|
66
|
-
SELECT n.id, n.name, n.file_path, n.label
|
|
66
|
+
SELECT n.id, n.name, n.file_path, n.start_line, n.label
|
|
67
67
|
FROM nodes n
|
|
68
68
|
WHERE NOT EXISTS (SELECT 1 FROM edges e WHERE e.source_id = n.id OR e.target_id = n.id)
|
|
69
69
|
AND n.label IN ('Function', 'Class', 'Method', 'Interface', 'Variable', 'Module', 'File')
|
|
@@ -76,13 +76,14 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
76
76
|
nodeId: n.id,
|
|
77
77
|
nodeName: n.name,
|
|
78
78
|
filePath: n.file_path,
|
|
79
|
+
startLine: n.start_line ?? null,
|
|
79
80
|
savedAt: new Date().toISOString(),
|
|
80
81
|
fingerprint: fingerprintFinding('isolated_node', n.file_path ?? '', n.id),
|
|
81
82
|
});
|
|
82
83
|
}
|
|
83
84
|
// God nodes (degree > 50)
|
|
84
85
|
const gods = db.prepare(`
|
|
85
|
-
SELECT n.id, n.name, n.file_path,
|
|
86
|
+
SELECT n.id, n.name, n.file_path, n.start_line,
|
|
86
87
|
COUNT(DISTINCT e1.id) + COUNT(DISTINCT e2.id) as degree
|
|
87
88
|
FROM nodes n
|
|
88
89
|
LEFT JOIN edges e1 ON e1.source_id = n.id
|
|
@@ -99,6 +100,7 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
99
100
|
nodeId: n.id,
|
|
100
101
|
nodeName: n.name,
|
|
101
102
|
filePath: n.file_path,
|
|
103
|
+
startLine: n.start_line ?? null,
|
|
102
104
|
savedAt: new Date().toISOString(),
|
|
103
105
|
fingerprint: fingerprintFinding('god_node', n.file_path ?? '', n.id),
|
|
104
106
|
});
|
|
@@ -106,7 +108,7 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
106
108
|
// Surprise edges: non-EXTRACTED confidence (cross-community low-confidence edges)
|
|
107
109
|
const surprises = db.prepare(`
|
|
108
110
|
SELECT DISTINCT e.id as edge_id, e.source_id, e.target_id, e.confidence,
|
|
109
|
-
n.name as src_name, n.file_path as src_file
|
|
111
|
+
n.name as src_name, n.file_path as src_file, n.start_line as src_line
|
|
110
112
|
FROM edges e
|
|
111
113
|
JOIN nodes n ON n.id = e.source_id
|
|
112
114
|
WHERE e.confidence != 'EXTRACTED'
|
|
@@ -119,27 +121,25 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
119
121
|
nodeId: e.source_id,
|
|
120
122
|
nodeName: e.src_name,
|
|
121
123
|
filePath: e.src_file,
|
|
124
|
+
startLine: e.src_line ?? null,
|
|
122
125
|
savedAt: new Date().toISOString(),
|
|
123
126
|
fingerprint: fingerprintFinding('surprise', e.source_id, e.target_id),
|
|
124
127
|
});
|
|
125
128
|
}
|
|
126
129
|
// Bridge nodes: nodes whose edges span more than one community_id
|
|
130
|
+
// Use JOIN+GROUP BY instead of correlated subqueries to avoid N*2 subquery executions
|
|
127
131
|
const bridges = db.prepare(`
|
|
128
|
-
SELECT n.id, n.name, n.file_path
|
|
132
|
+
SELECT n.id, n.name, n.file_path, n.start_line,
|
|
133
|
+
COUNT(DISTINCT CASE WHEN e_out.source_id = n.id AND n_tgt.community_id != n.community_id THEN n_tgt.community_id END) +
|
|
134
|
+
COUNT(DISTINCT CASE WHEN e_in.target_id = n.id AND n_src.community_id != n.community_id THEN n_src.community_id END) AS cross_communities
|
|
129
135
|
FROM nodes n
|
|
136
|
+
LEFT JOIN edges e_out ON e_out.source_id = n.id
|
|
137
|
+
LEFT JOIN nodes n_tgt ON n_tgt.id = e_out.target_id AND n_tgt.community_id IS NOT NULL
|
|
138
|
+
LEFT JOIN edges e_in ON e_in.target_id = n.id
|
|
139
|
+
LEFT JOIN nodes n_src ON n_src.id = e_in.source_id AND n_src.community_id IS NOT NULL
|
|
130
140
|
WHERE n.community_id IS NOT NULL
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
FROM edges e_out
|
|
134
|
-
JOIN nodes n_tgt ON n_tgt.id = e_out.target_id
|
|
135
|
-
WHERE e_out.source_id = n.id AND n_tgt.community_id != n.community_id
|
|
136
|
-
) +
|
|
137
|
-
(
|
|
138
|
-
SELECT COUNT(DISTINCT n_src.community_id)
|
|
139
|
-
FROM edges e_in
|
|
140
|
-
JOIN nodes n_src ON n_src.id = e_in.source_id
|
|
141
|
-
WHERE e_in.target_id = n.id AND n_src.community_id != n.community_id
|
|
142
|
-
) >= 2
|
|
141
|
+
GROUP BY n.id
|
|
142
|
+
HAVING cross_communities >= 2
|
|
143
143
|
LIMIT 100
|
|
144
144
|
`).all();
|
|
145
145
|
for (const n of bridges) {
|
|
@@ -149,13 +149,14 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
149
149
|
nodeId: n.id,
|
|
150
150
|
nodeName: n.name,
|
|
151
151
|
filePath: n.file_path,
|
|
152
|
+
startLine: n.start_line ?? null,
|
|
152
153
|
savedAt: new Date().toISOString(),
|
|
153
154
|
fingerprint: fingerprintFinding('bridge_node', n.file_path ?? '', n.id),
|
|
154
155
|
});
|
|
155
156
|
}
|
|
156
157
|
// Unreachable exports: exported nodes with no incoming edges
|
|
157
158
|
const unreachableExports = db.prepare(`
|
|
158
|
-
SELECT n.id, n.name, n.file_path
|
|
159
|
+
SELECT n.id, n.name, n.file_path, n.start_line
|
|
159
160
|
FROM nodes n
|
|
160
161
|
WHERE n.is_exported = 1
|
|
161
162
|
AND n.label IN ('Function', 'Class', 'Method', 'Interface', 'Variable')
|
|
@@ -169,6 +170,7 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
169
170
|
nodeId: n.id,
|
|
170
171
|
nodeName: n.name,
|
|
171
172
|
filePath: n.file_path,
|
|
173
|
+
startLine: n.start_line ?? null,
|
|
172
174
|
savedAt: new Date().toISOString(),
|
|
173
175
|
fingerprint: fingerprintFinding('unreachable_export', n.file_path ?? '', n.id),
|
|
174
176
|
});
|
|
@@ -176,7 +178,7 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
176
178
|
// Ambiguous edges: edges with AMBIGUOUS confidence
|
|
177
179
|
const ambiguousEdges = db.prepare(`
|
|
178
180
|
SELECT DISTINCT e.id as edge_id, e.source_id, e.target_id,
|
|
179
|
-
n.name as src_name, n.file_path as src_file
|
|
181
|
+
n.name as src_name, n.file_path as src_file, n.start_line as src_line
|
|
180
182
|
FROM edges e
|
|
181
183
|
JOIN nodes n ON n.id = e.source_id
|
|
182
184
|
WHERE e.confidence = 'AMBIGUOUS'
|
|
@@ -189,6 +191,7 @@ export function extractFindingsFromDb(db, projectPath) {
|
|
|
189
191
|
nodeId: e.source_id,
|
|
190
192
|
nodeName: e.src_name,
|
|
191
193
|
filePath: e.src_file,
|
|
194
|
+
startLine: e.src_line ?? null,
|
|
192
195
|
savedAt: new Date().toISOString(),
|
|
193
196
|
fingerprint: fingerprintFinding('ambiguous_edge', e.source_id, e.target_id),
|
|
194
197
|
});
|
|
@@ -269,4 +272,48 @@ export function computeTrend(before, after) {
|
|
|
269
272
|
}
|
|
270
273
|
return { metrics, overallDirection };
|
|
271
274
|
}
|
|
275
|
+
/** Format a list of ComparedFindings as structured text with file:line hints. */
|
|
276
|
+
export function formatComparedFindings(findings, showAll = false) {
|
|
277
|
+
if (findings.length === 0)
|
|
278
|
+
return 'Baseline comparison: no findings.';
|
|
279
|
+
const newFindings = findings.filter(f => f.introduced);
|
|
280
|
+
const existing = findings.filter(f => !f.introduced);
|
|
281
|
+
const lines = [
|
|
282
|
+
`Baseline comparison: ${findings.length} total finding(s) — ${newFindings.length} new, ${existing.length} known.`,
|
|
283
|
+
'',
|
|
284
|
+
];
|
|
285
|
+
if (newFindings.length > 0) {
|
|
286
|
+
lines.push(`New findings (${newFindings.length}):`);
|
|
287
|
+
for (const f of newFindings) {
|
|
288
|
+
const ref = f.filePath
|
|
289
|
+
? f.startLine != null ? `${f.filePath}:${f.startLine}` : f.filePath
|
|
290
|
+
: f.nodeId;
|
|
291
|
+
lines.push(` [${f.type}] ${f.nodeName} ${ref}`);
|
|
292
|
+
}
|
|
293
|
+
lines.push('');
|
|
294
|
+
}
|
|
295
|
+
if (showAll && existing.length > 0) {
|
|
296
|
+
lines.push(`Known findings (${existing.length}):`);
|
|
297
|
+
for (const f of existing) {
|
|
298
|
+
const ref = f.filePath
|
|
299
|
+
? f.startLine != null ? `${f.filePath}:${f.startLine}` : f.filePath
|
|
300
|
+
: f.nodeId;
|
|
301
|
+
lines.push(` [${f.type}] ${f.nodeName} ${ref}`);
|
|
302
|
+
}
|
|
303
|
+
lines.push('');
|
|
304
|
+
}
|
|
305
|
+
return lines.join('\n').trimEnd();
|
|
306
|
+
}
|
|
307
|
+
/** Format a TrendReport as structured text for LLM consumption. */
|
|
308
|
+
export function formatTrendReport(report) {
|
|
309
|
+
const lines = [
|
|
310
|
+
`Graph trend: ${report.overallDirection}`,
|
|
311
|
+
'',
|
|
312
|
+
];
|
|
313
|
+
for (const m of report.metrics) {
|
|
314
|
+
const deltaStr = m.delta > 0 ? `+${m.delta}` : `${m.delta}`;
|
|
315
|
+
lines.push(` ${m.symbol} ${m.metric}: ${m.previous} → ${m.current} (${deltaStr}) [${m.direction}]`);
|
|
316
|
+
}
|
|
317
|
+
return lines.join('\n');
|
|
318
|
+
}
|
|
272
319
|
//# sourceMappingURL=baseline.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../../src/graph/baseline.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,SAAS,kBAAkB,CAAC,IAAY,EAAE,GAAG,KAAe;IAC1D,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC7F,CAAC;
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../../src/graph/baseline.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,SAAS,kBAAkB,CAAC,IAAY,EAAE,GAAG,KAAe;IAC1D,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC7F,CAAC;AA0BD;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,YAAoB,EACpB,QAA2B,EAC3B,WAAmB;IAEnB,MAAM,IAAI,GAAiB;QACzB,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACjC,WAAW;QACX,QAAQ;KACT,CAAC;IACF,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,YAAoB;IAC/C,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAiB,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,eAAkC,EAClC,QAA6B;IAE7B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,8CAA8C;QAC9C,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,6DAA6D;IAC7D,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAClC,QAAQ,CAAC,QAAQ;SACd,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;SAC1B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAqB,CAAC,CACrC,CAAC;IACF,iEAAiE;IACjE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QAC7B,IAAI,CAAC,CAAC,WAAW,IAAI,oBAAoB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACnD,OAAO,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;QACxE,CAAC;QACD,OAAO,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,EAAqB,EACrB,WAAmB;IAEnB,MAAM,QAAQ,GAAsB,EAAE,CAAC;IAEvC,iDAAiD;IACjD,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;GAM3B,CAAC,CAAC,GAAG,EAAwG,CAAC;IAE/G,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC;YACZ,GAAG,EAAE,YAAY,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE;YAChD,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,CAAC,CAAC,EAAE;YACZ,QAAQ,EAAE,CAAC,CAAC,IAAI;YAChB,QAAQ,EAAE,CAAC,CAAC,SAAS;YACrB,SAAS,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;YAC/B,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,WAAW,EAAE,kBAAkB,CAAC,eAAe,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;SAC1E,CAAC,CAAC;IACL,CAAC;IAED,0BAA0B;IAC1B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;GAUvB,CAAC,CAAC,GAAG,EAAyG,CAAC;IAEhH,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC;YACZ,GAAG,EAAE,YAAY,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE;YAChD,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,CAAC,CAAC,EAAE;YACZ,QAAQ,EAAE,CAAC,CAAC,IAAI;YAChB,QAAQ,EAAE,CAAC,CAAC,SAAS;YACrB,SAAS,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;YAC/B,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,WAAW,EAAE,kBAAkB,CAAC,UAAU,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;SACrE,CAAC,CAAC;IACL,CAAC;IAED,kFAAkF;IAClF,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;GAO5B,CAAC,CAAC,GAAG,EAAyJ,CAAC;IAEhK,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC;YACZ,GAAG,EAAE,YAAY,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,EAAE;YAC7C,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,CAAC,CAAC,SAAS;YACnB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,SAAS,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;YAC7B,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,WAAW,EAAE,kBAAkB,CAAC,UAAU,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC;SACtE,CAAC,CAAC;IACL,CAAC;IAED,kEAAkE;IAClE,sFAAsF;IACtF,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;;;;;;;GAa1B,CAAC,CAAC,GAAG,EAAyF,CAAC;IAEhG,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC;YACZ,GAAG,EAAE,eAAe,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE;YACnD,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,CAAC,CAAC,EAAE;YACZ,QAAQ,EAAE,CAAC,CAAC,IAAI;YAChB,QAAQ,EAAE,CAAC,CAAC,SAAS;YACrB,SAAS,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;YAC/B,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,WAAW,EAAE,kBAAkB,CAAC,aAAa,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;SACxE,CAAC,CAAC;IACL,CAAC;IAED,6DAA6D;IAC7D,MAAM,kBAAkB,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;GAOrC,CAAC,CAAC,GAAG,EAAyF,CAAC;IAEhG,KAAK,MAAM,CAAC,IAAI,kBAAkB,EAAE,CAAC;QACnC,QAAQ,CAAC,IAAI,CAAC;YACZ,GAAG,EAAE,sBAAsB,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE;YAC1D,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,CAAC,CAAC,EAAE;YACZ,QAAQ,EAAE,CAAC,CAAC,IAAI;YAChB,QAAQ,EAAE,CAAC,CAAC,SAAS;YACrB,SAAS,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;YAC/B,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,WAAW,EAAE,kBAAkB,CAAC,oBAAoB,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;SAC/E,CAAC,CAAC;IACL,CAAC;IAED,mDAAmD;IACnD,MAAM,cAAc,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;;GAOjC,CAAC,CAAC,GAAG,EAAqI,CAAC;IAE5I,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,QAAQ,CAAC,IAAI,CAAC;YACZ,GAAG,EAAE,kBAAkB,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,EAAE;YACnD,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE,CAAC,CAAC,SAAS;YACnB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,SAAS,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI;YAC7B,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,WAAW,EAAE,kBAAkB,CAAC,gBAAgB,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC;SAC5E,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkB,EAAE,IAAa;IACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;IAClE,OAAO,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAkCD;;;;GAIG;AACH,MAAM,uBAAuB,GAA4B;IACvD,SAAS,EAAE,IAAI;IACf,SAAS,EAAE,KAAK,EAAS,iDAAiD;IAC1E,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,KAAK;IACnB,aAAa,EAAE,KAAK;IACpB,YAAY,EAAE,KAAK;IACnB,oBAAoB,EAAE,KAAK;CAC5B,CAAC;AAEF,SAAS,cAAc,CACrB,MAAc,EACd,KAAa;IAEb,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAE7D,+DAA+D;IAC/D,IAAI,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAExE,MAAM,cAAc,GAAG,uBAAuB,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IAE/D,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,cAAc;YACnB,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE;YACzC,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAC9C,CAAC;IACD,YAAY;IACZ,OAAO,cAAc;QACnB,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE;QACzC,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAqC,EACrC,KAAoC;IAEpC,MAAM,UAAU,GAAgC;QAC9C,WAAW;QACX,WAAW;QACX,gBAAgB;QAChB,cAAc;QACd,eAAe;QACf,cAAc;QACd,sBAAsB;KACvB,CAAC;IAEF,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,GAAG,IAAI,CAAC;QAC1B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,gEAAgE;IAChE,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACzD,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;IAE/C,IAAI,gBAAgB,GAAmB,QAAQ,CAAC;IAChD,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QAC5E,gBAAgB,GAAG,WAAW,CAAC;IACjC,CAAC;SAAM,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACnF,gBAAgB,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AACvC,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,sBAAsB,CAAC,QAA2B,EAAE,OAAO,GAAG,KAAK;IACjF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,mCAAmC,CAAC;IAEtE,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAErD,MAAM,KAAK,GAAa;QACtB,wBAAwB,QAAQ,CAAC,MAAM,uBAAuB,WAAW,CAAC,MAAM,SAAS,QAAQ,CAAC,MAAM,SAAS;QACjH,EAAE;KACH,CAAC;IAEF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,iBAAiB,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC;QACpD,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ;gBACpB,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ;gBACnE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,mBAAmB,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ;gBACpB,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ;gBACnE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACb,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AACpC,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,MAAM,KAAK,GAAa;QACtB,gBAAgB,MAAM,CAAC,gBAAgB,EAAE;QACzC,EAAE;KACH,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,OAAO,KAAK,QAAQ,OAAO,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;IACxG,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone-detector.d.ts","sourceRoot":"","sources":["../../../src/graph/clone-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"clone-detector.d.ts","sourceRoot":"","sources":["../../../src/graph/clone-detector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAIpD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,GAAG,SAAS,GAAG,YAAY,CAAC;IAC9C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAwCD,wBAAgB,YAAY,CAC1B,EAAE,EAAE,WAAW,EACf,aAAa,SAAM,EACnB,SAAS,SAAI,GACZ,oBAAoB,CAsGtB"}
|
|
@@ -11,38 +11,28 @@ function tokenizePath(filePath) {
|
|
|
11
11
|
function baseName(filePath) {
|
|
12
12
|
return filePath.replace(/^.*[\\/]/, '');
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Compute both Jaccard similarity and shared token count in a single pass.
|
|
16
|
+
* Avoids building the countA Map twice (previously done separately in
|
|
17
|
+
* jaccardSimilarity and sharedTokenCount).
|
|
18
|
+
*/
|
|
19
|
+
function computeSimilarityAndShared(a, b) {
|
|
16
20
|
const countA = new Map();
|
|
17
|
-
const countB = new Map();
|
|
18
21
|
for (const t of a)
|
|
19
22
|
countA.set(t, (countA.get(t) ?? 0) + 1);
|
|
20
|
-
for (const t of b)
|
|
21
|
-
countB.set(t, (countB.get(t) ?? 0) + 1);
|
|
22
23
|
let intersection = 0;
|
|
23
|
-
for (const [token, ca] of countA) {
|
|
24
|
-
const cb = countB.get(token) ?? 0;
|
|
25
|
-
intersection += Math.min(ca, cb);
|
|
26
|
-
}
|
|
27
|
-
const union = a.length + b.length - intersection;
|
|
28
|
-
return union === 0 ? 1 : intersection / union;
|
|
29
|
-
}
|
|
30
|
-
/** Count tokens shared between two multisets. */
|
|
31
|
-
function sharedTokenCount(a, b) {
|
|
32
|
-
const countA = new Map();
|
|
33
|
-
for (const t of a)
|
|
34
|
-
countA.set(t, (countA.get(t) ?? 0) + 1);
|
|
35
|
-
let shared = 0;
|
|
36
24
|
const seen = new Map();
|
|
37
25
|
for (const t of b) {
|
|
38
26
|
const limit = countA.get(t) ?? 0;
|
|
39
27
|
const used = seen.get(t) ?? 0;
|
|
40
28
|
if (used < limit) {
|
|
41
|
-
|
|
29
|
+
intersection++;
|
|
42
30
|
seen.set(t, used + 1);
|
|
43
31
|
}
|
|
44
32
|
}
|
|
45
|
-
|
|
33
|
+
const union = a.length + b.length - intersection;
|
|
34
|
+
const similarity = union === 0 ? 1 : intersection / union;
|
|
35
|
+
return { similarity, shared: intersection };
|
|
46
36
|
}
|
|
47
37
|
export function detectClones(db, minSimilarity = 0.8, minTokens = 2) {
|
|
48
38
|
// Query all File nodes with file_path
|
|
@@ -52,29 +42,25 @@ export function detectClones(db, minSimilarity = 0.8, minTokens = 2) {
|
|
|
52
42
|
const totalFiles = rows.length;
|
|
53
43
|
const pairs = [];
|
|
54
44
|
const involvedFiles = new Set();
|
|
55
|
-
// Pre-compute tokens for each file
|
|
45
|
+
// Pre-compute path tokens and name tokens for each file
|
|
56
46
|
const tokenMap = new Map();
|
|
57
47
|
for (const row of rows) {
|
|
58
|
-
|
|
48
|
+
const pathTokens = tokenizePath(row.file_path);
|
|
49
|
+
const nameTokens = tokenizePath(baseName(row.file_path));
|
|
50
|
+
tokenMap.set(row.file_path, { pathTokens, nameTokens });
|
|
59
51
|
}
|
|
60
52
|
// Compare all pairs
|
|
61
53
|
for (let i = 0; i < rows.length; i++) {
|
|
62
54
|
for (let j = i + 1; j < rows.length; j++) {
|
|
63
55
|
const pathA = rows[i].file_path;
|
|
64
56
|
const pathB = rows[j].file_path;
|
|
65
|
-
const
|
|
66
|
-
const
|
|
67
|
-
const sim =
|
|
68
|
-
const shared = sharedTokenCount(tokensA, tokensB);
|
|
57
|
+
const entryA = tokenMap.get(pathA);
|
|
58
|
+
const entryB = tokenMap.get(pathB);
|
|
59
|
+
const { similarity: sim, shared } = computeSimilarityAndShared(entryA.pathTokens, entryB.pathTokens);
|
|
69
60
|
if (sim < minSimilarity || shared < minTokens) {
|
|
70
61
|
// Also check near-duplicate file names (same name, different dir)
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
const nameTokensA = tokenizePath(nameA);
|
|
74
|
-
const nameTokensB = tokenizePath(nameB);
|
|
75
|
-
const nameSim = jaccardSimilarity(nameTokensA, nameTokensB);
|
|
76
|
-
const nameShared = sharedTokenCount(nameTokensA, nameTokensB);
|
|
77
|
-
if (nameSim >= minSimilarity && nameShared >= Math.min(minTokens, nameTokensA.length)) {
|
|
62
|
+
const { similarity: nameSim, shared: nameShared } = computeSimilarityAndShared(entryA.nameTokens, entryB.nameTokens);
|
|
63
|
+
if (nameSim >= minSimilarity && nameShared >= Math.min(minTokens, entryA.nameTokens.length)) {
|
|
78
64
|
// Same-name files in different directories → structural similarity
|
|
79
65
|
const pair = {
|
|
80
66
|
fileA: pathA,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone-detector.js","sourceRoot":"","sources":["../../../src/graph/clone-detector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAgBrC,+DAA+D;AAC/D,SAAS,YAAY,CAAC,QAAgB;IACpC,OAAO,QAAQ;SACZ,WAAW,EAAE;SACb,KAAK,CAAC,YAAY,CAAC;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,iEAAiE;AACjE,SAAS,QAAQ,CAAC,QAAgB;IAChC,OAAO,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"clone-detector.js","sourceRoot":"","sources":["../../../src/graph/clone-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,8 @@ export interface CloneFamily {
|
|
|
24
24
|
suggestions: RefactoringSuggestion[];
|
|
25
25
|
}
|
|
26
26
|
export declare function groupIntoFamilies(groups: CloneGroup[]): CloneFamily[];
|
|
27
|
+
/** Format clone families as structured text for LLM consumption. */
|
|
28
|
+
export declare function formatCloneFamilies(families: CloneFamily[]): string;
|
|
27
29
|
export declare function cloneFamilySummary(families: CloneFamily[]): {
|
|
28
30
|
totalFamilies: number;
|
|
29
31
|
totalDuplicatedLines: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clone-families.d.ts","sourceRoot":"","sources":["../../../src/graph/clone-families.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAEvF,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,eAAe,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,qBAAqB,EAAE,CAAC;CACtC;
|
|
1
|
+
{"version":3,"file":"clone-families.d.ts","sourceRoot":"","sources":["../../../src/graph/clone-families.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAEvF,eAAO,MAAM,iCAAiC,KAAK,CAAC;AAEpD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,eAAe,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,qBAAqB,EAAE,CAAC;CACtC;AA+CD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,EAAE,CAsBrE;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAUnE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG;IAC3D,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;CACzC,CAcA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export const MODULE_EXTRACTION_THRESHOLD_LINES = 50;
|
|
2
2
|
function fileSetKey(files) {
|
|
3
|
-
|
|
3
|
+
// Avoid spread allocation: sort a copy directly
|
|
4
|
+
return files.slice().sort().join('|');
|
|
4
5
|
}
|
|
5
6
|
function generateSuggestions(family) {
|
|
6
7
|
const suggestions = [];
|
|
@@ -15,10 +16,14 @@ function generateSuggestions(family) {
|
|
|
15
16
|
}
|
|
16
17
|
else {
|
|
17
18
|
// Check if all files are in the same directory → MergeDirectories
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// Use Set directly to avoid spread+map intermediate array
|
|
20
|
+
const dirSet = new Set();
|
|
21
|
+
for (const f of family.files) {
|
|
22
|
+
const slash = f.replace(/\\/g, '/');
|
|
23
|
+
const lastSlash = slash.lastIndexOf('/');
|
|
24
|
+
dirSet.add(lastSlash >= 0 ? slash.slice(0, lastSlash) : '.');
|
|
25
|
+
}
|
|
26
|
+
const dirs = [...dirSet];
|
|
22
27
|
if (dirs.length > 1 && family.files.length >= 3) {
|
|
23
28
|
suggestions.push({
|
|
24
29
|
kind: 'MergeDirectories',
|
|
@@ -48,24 +53,47 @@ export function groupIntoFamilies(groups) {
|
|
|
48
53
|
}
|
|
49
54
|
familyMap.get(key).groups.push(group);
|
|
50
55
|
}
|
|
51
|
-
|
|
56
|
+
// Build output array without intermediate spread + map allocation
|
|
57
|
+
const result = [];
|
|
58
|
+
for (const { files, groups } of familyMap.values()) {
|
|
52
59
|
const fileList = [...files].sort();
|
|
53
|
-
|
|
60
|
+
let totalDuplicatedLines = 0;
|
|
61
|
+
for (const g of groups)
|
|
62
|
+
totalDuplicatedLines += g.duplicatedLines;
|
|
54
63
|
const base = { files: fileList, groups, totalDuplicatedLines };
|
|
55
|
-
|
|
56
|
-
}
|
|
64
|
+
result.push({ ...base, suggestions: generateSuggestions(base) });
|
|
65
|
+
}
|
|
66
|
+
return result.sort((a, b) => b.totalDuplicatedLines - a.totalDuplicatedLines);
|
|
67
|
+
}
|
|
68
|
+
/** Format clone families as structured text for LLM consumption. */
|
|
69
|
+
export function formatCloneFamilies(families) {
|
|
70
|
+
if (families.length === 0)
|
|
71
|
+
return 'No clone families detected.';
|
|
72
|
+
const lines = [`Clone Families (${families.length} total):`];
|
|
73
|
+
for (const f of families.slice(0, 20)) {
|
|
74
|
+
lines.push(`\n ${f.totalDuplicatedLines} duplicated lines across ${f.files.length} files:`);
|
|
75
|
+
for (const file of f.files)
|
|
76
|
+
lines.push(` ${file}`);
|
|
77
|
+
for (const s of f.suggestions)
|
|
78
|
+
lines.push(` -> [${s.kind}] ${s.description}`);
|
|
79
|
+
}
|
|
80
|
+
if (families.length > 20)
|
|
81
|
+
lines.push(`\n ... and ${families.length - 20} more families`);
|
|
82
|
+
return lines.join('\n');
|
|
57
83
|
}
|
|
58
84
|
export function cloneFamilySummary(families) {
|
|
59
85
|
const byKind = {
|
|
60
86
|
ExtractFunction: 0, ExtractModule: 0, MergeDirectories: 0,
|
|
61
87
|
};
|
|
88
|
+
let totalDuplicatedLines = 0;
|
|
62
89
|
for (const f of families) {
|
|
90
|
+
totalDuplicatedLines += f.totalDuplicatedLines;
|
|
63
91
|
for (const s of f.suggestions)
|
|
64
92
|
byKind[s.kind]++;
|
|
65
93
|
}
|
|
66
94
|
return {
|
|
67
95
|
totalFamilies: families.length,
|
|
68
|
-
totalDuplicatedLines
|
|
96
|
+
totalDuplicatedLines,
|
|
69
97
|
byKind,
|
|
70
98
|
};
|
|
71
99
|
}
|