@monoes/monograph 1.5.6 → 1.5.7
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 +25 -9
- package/dist/src/mcp-tools/impact.d.ts.map +1 -1
- package/dist/src/mcp-tools/impact.js +1 -10
- package/dist/src/mcp-tools/impact.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -9
- package/.monomind/data/ranked-context.json +0 -5
- package/.monomind/loops/mastermind-review-1782162423447.json +0 -16
- package/.monomind/sessions/session-1777578175215.json +0 -15
- package/.monomind/sessions/session-1777823684507.json +0 -15
- package/.monomind/sessions/session-1777928944749.json +0 -15
- package/.monomind/sessions/session-1778052902210.json +0 -15
- package/.monomind/sessions/session-1778056744636.json +0 -15
- package/.monomind/sessions/session-1778061077599.json +0 -15
- package/.monomind/sessions/session-1778102154764.json +0 -15
- package/__tests__/analysis/shape-extractor.test.ts +0 -124
- package/__tests__/analysis/surprise-scorer.test.ts +0 -154
- package/__tests__/cache/extraction-cache.test.ts +0 -45
- package/__tests__/cli/ai-context.test.ts +0 -175
- package/__tests__/cli/augment.test.ts +0 -128
- package/__tests__/cli/doctor.test.ts +0 -125
- package/__tests__/cli/eval-server.test.ts +0 -89
- package/__tests__/cli/setup.test.ts +0 -178
- package/__tests__/cli/skill-gen.test.ts +0 -280
- package/__tests__/export/formats.test.ts +0 -82
- package/__tests__/fixtures/sample.c +0 -25
- package/__tests__/fixtures/sample.cpp +0 -32
- package/__tests__/fixtures/sample.dart +0 -34
- package/__tests__/fixtures/sample.kt +0 -30
- package/__tests__/fixtures/sample.php +0 -30
- package/__tests__/fixtures/sample.py +0 -11
- package/__tests__/fixtures/sample.rb +0 -26
- package/__tests__/fixtures/sample.swift +0 -42
- package/__tests__/fixtures/sample.ts +0 -17
- package/__tests__/fixtures/sample.vue +0 -40
- package/__tests__/groups/group-search.test.ts +0 -221
- package/__tests__/groups/group-sync.test.ts +0 -336
- package/__tests__/integration/build-atomicity.test.ts +0 -61
- package/__tests__/integration/call-attribution.test.ts +0 -116
- package/__tests__/integration/full-pipeline.test.ts +0 -64
- package/__tests__/integration/graph-report-freshness.test.ts +0 -53
- package/__tests__/integration/incremental-build.test.ts +0 -103
- package/__tests__/mcp-resources/resources.test.ts +0 -256
- package/__tests__/mcp-tools/api-impact.test.ts +0 -188
- package/__tests__/mcp-tools/context.test.ts +0 -130
- package/__tests__/mcp-tools/cypher.test.ts +0 -258
- package/__tests__/mcp-tools/detect-changes.test.ts +0 -114
- package/__tests__/mcp-tools/impact.test.ts +0 -133
- package/__tests__/mcp-tools/rename.test.ts +0 -117
- package/__tests__/mcp-tools/route-map.test.ts +0 -237
- package/__tests__/mcp-tools/shape-check.test.ts +0 -202
- package/__tests__/mcp-tools/tool-map.test.ts +0 -135
- package/__tests__/parsers/c.test.ts +0 -28
- package/__tests__/parsers/cpp.test.ts +0 -28
- package/__tests__/parsers/csharp.test.ts +0 -62
- package/__tests__/parsers/dart.test.ts +0 -28
- package/__tests__/parsers/kotlin.test.ts +0 -28
- package/__tests__/parsers/loader.test.ts +0 -14
- package/__tests__/parsers/php.test.ts +0 -28
- package/__tests__/parsers/python.test.ts +0 -32
- package/__tests__/parsers/ruby.test.ts +0 -33
- package/__tests__/parsers/swift.test.ts +0 -28
- package/__tests__/parsers/typescript.test.ts +0 -45
- package/__tests__/parsers/vue.test.ts +0 -28
- package/__tests__/pipeline/analysis.test.ts +0 -58
- package/__tests__/pipeline/phases/corpus-check.test.ts +0 -26
- package/__tests__/pipeline/phases/evidence.test.ts +0 -41
- package/__tests__/pipeline/phases/field-access.test.ts +0 -22
- package/__tests__/pipeline/phases/leiden.test.ts +0 -72
- package/__tests__/pipeline/phases/markdown.test.ts +0 -84
- package/__tests__/pipeline/phases/middleware-extractor.test.ts +0 -131
- package/__tests__/pipeline/phases/orm.test.ts +0 -379
- package/__tests__/pipeline/phases/processes.test.ts +0 -191
- package/__tests__/pipeline/phases/routes.test.ts +0 -195
- package/__tests__/pipeline/phases/scope-resolution.test.ts +0 -133
- package/__tests__/pipeline/phases/tools.test.ts +0 -161
- package/__tests__/pipeline/phases/variables.test.ts +0 -30
- package/__tests__/pipeline/phases/wildcard-synthesis.test.ts +0 -207
- package/__tests__/pipeline/phases.test.ts +0 -41
- package/__tests__/pipeline/runner.test.ts +0 -28
- package/__tests__/registry/repo-registry.test.ts +0 -127
- package/__tests__/reporting/graph-report.suggest.test.ts +0 -36
- package/__tests__/reporting/graph-report.test.ts +0 -165
- package/__tests__/search/ast-chunker.test.ts +0 -63
- package/__tests__/search/rrf.test.ts +0 -95
- package/__tests__/security/safe-fetch.test.ts +0 -41
- package/__tests__/security/sensitive-files.test.ts +0 -32
- package/__tests__/setup.ts +0 -1
- package/__tests__/skills/platform-skills.test.ts +0 -63
- package/__tests__/staleness/git-staleness.test.ts +0 -107
- package/__tests__/storage/db.test.ts +0 -37
- package/__tests__/storage/evidence-roundtrip.test.ts +0 -89
- package/__tests__/storage/stores.test.ts +0 -165
- package/__tests__/types.test.ts +0 -13
- package/__tests__/validation/extraction-validator.test.ts +0 -48
- package/__tests__/watch/watcher.test.ts +0 -31
- package/__tests__/web/analyze-api.test.ts +0 -66
- package/__tests__/web/api.test.ts +0 -210
- package/__tests__/web/mcp-http.test.ts +0 -67
- package/__tests__/web/react-ui.test.ts +0 -43
- package/__tests__/wiki/gist-publisher.test.ts +0 -66
- package/__tests__/wiki/providers.test.ts +0 -69
- package/__tests__/wiki/wiki-generator.test.ts +0 -260
- package/src/__tests__/analysis/benchmark.test.ts +0 -59
- package/src/__tests__/analysis/cluster-quality.test.ts +0 -106
- package/src/__tests__/analysis/corpus-health.test.ts +0 -33
- package/src/__tests__/analysis/dependency-health.test.ts +0 -105
- package/src/__tests__/analysis/file-classifier.test.ts +0 -50
- package/src/__tests__/analysis/node-similarity.test.ts +0 -81
- package/src/__tests__/cache/augment-cache.test.ts +0 -55
- package/src/__tests__/cli/check-update.test.ts +0 -42
- package/src/__tests__/cli/hooks-install.test.ts +0 -56
- package/src/__tests__/cli/hooks-marker.test.ts +0 -138
- package/src/__tests__/cli/hooks-status.test.ts +0 -42
- package/src/__tests__/export/adjacency-matrix.test.ts +0 -116
- package/src/__tests__/export/csv.test.ts +0 -39
- package/src/__tests__/export/dot.test.ts +0 -86
- package/src/__tests__/export/gexf.test.ts +0 -78
- package/src/__tests__/export/graphml.test.ts +0 -57
- package/src/__tests__/export/mermaid.test.ts +0 -89
- package/src/__tests__/graph/betweenness.test.ts +0 -89
- package/src/__tests__/graph/cycles.test.ts +0 -131
- package/src/__tests__/graph/dead-code.test.ts +0 -174
- package/src/__tests__/graph/dfs.test.ts +0 -62
- package/src/__tests__/graph/diff-summary.test.ts +0 -83
- package/src/__tests__/graph/edge-filter.test.ts +0 -129
- package/src/__tests__/graph/import-chain.test.ts +0 -111
- package/src/__tests__/graph/merge.test.ts +0 -151
- package/src/__tests__/graph/node-search.test.ts +0 -167
- package/src/__tests__/graph/normalize-id.test.ts +0 -102
- package/src/__tests__/graph/pagerank.test.ts +0 -96
- package/src/__tests__/graph/prune.test.ts +0 -110
- package/src/__tests__/graph/regex-search.test.ts +0 -166
- package/src/__tests__/graph/ripple-impact.test.ts +0 -73
- package/src/__tests__/graph/scc.test.ts +0 -85
- package/src/__tests__/graph/statistics.test.ts +0 -219
- package/src/__tests__/graph/subgraph.test.ts +0 -127
- package/src/__tests__/graph/topo-sort.test.ts +0 -110
- package/src/__tests__/graph/wcc.test.ts +0 -101
- package/src/__tests__/groups/grpc-extractor.test.ts +0 -47
- package/src/__tests__/groups/service-boundary.test.ts +0 -86
- package/src/__tests__/groups/topic-extractor.test.ts +0 -43
- package/src/__tests__/ingest/git-clone.test.ts +0 -128
- package/src/__tests__/ingest/query-memory.test.ts +0 -123
- package/src/__tests__/ingest/transcribe.test.ts +0 -58
- package/src/__tests__/ingest/url-ingest.test.ts +0 -48
- package/src/__tests__/mcp-resources/repo-context-resource.test.ts +0 -37
- package/src/__tests__/mcp-resources/repos-resource.test.ts +0 -71
- package/src/__tests__/mcp-resources/wiki-resource.test.ts +0 -52
- package/src/__tests__/mcp-tools/explain.test.ts +0 -46
- package/src/__tests__/mcp-tools/graph-query.test.ts +0 -45
- package/src/__tests__/mcp-tools/group-sync.test.ts +0 -8
- package/src/__tests__/mcp-tools/impact-filtering.test.ts +0 -48
- package/src/__tests__/mcp-tools/impact.risk.test.ts +0 -24
- package/src/__tests__/mcp-tools/list-repos.test.ts +0 -24
- package/src/__tests__/mcp-tools/neighbors.test.ts +0 -48
- package/src/__tests__/mcp-tools/query.test.ts +0 -42
- package/src/__tests__/parsers/language-parsers.test.ts +0 -52
- package/src/__tests__/parsers/named-bindings.test.ts +0 -73
- package/src/__tests__/pipeline/cluster-only.test.ts +0 -33
- package/src/__tests__/pipeline/phases/bridge-adapters/electron-ipc.test.ts +0 -87
- package/src/__tests__/pipeline/phases/bridge-adapters/tauri.test.ts +0 -116
- package/src/__tests__/pipeline/phases/bridge-adapters/wails.test.ts +0 -81
- package/src/__tests__/pipeline/phases/bridge-resolver.test.ts +0 -110
- package/src/__tests__/pipeline/phases/communities.cohesion.test.ts +0 -43
- package/src/__tests__/pipeline/phases/community-split.test.ts +0 -30
- package/src/__tests__/pipeline/phases/framework-detect.test.ts +0 -65
- package/src/__tests__/pipeline/phases/import-resolver.test.ts +0 -64
- package/src/__tests__/pipeline/phases/parse-arrow.test.ts +0 -33
- package/src/__tests__/pipeline/phases/parse-csharp.test.ts +0 -33
- package/src/__tests__/pipeline/phases/scan.monographignore.test.ts +0 -53
- package/src/__tests__/pipeline/phases/scan.negation.test.ts +0 -40
- package/src/__tests__/pipeline/phases/scope-resolution.go.test.ts +0 -34
- package/src/__tests__/pipeline/phases/scope-resolution.java.test.ts +0 -30
- package/src/__tests__/pipeline/phases/scope-resolution.rust.test.ts +0 -31
- package/src/__tests__/pipeline/phases/suggest-questions.test.ts +0 -46
- package/src/__tests__/pipeline/phases/surprises-scoring.test.ts +0 -46
- package/src/__tests__/pipeline/phases/variables-phase.test.ts +0 -78
- package/src/__tests__/pipeline/phases/wildcard-phase.test.ts +0 -99
- package/src/__tests__/pipeline/runner.parallel.test.ts +0 -78
- package/src/__tests__/reporting/graph-report-confidence.test.ts +0 -43
- package/src/__tests__/reporting/graph-report-gaps.test.ts +0 -41
- package/src/__tests__/scope-resolution/call-sites.test.ts +0 -89
- package/src/__tests__/scope-resolution/evidence-weights.test.ts +0 -49
- package/src/__tests__/search/diacritic.test.ts +0 -23
- package/src/__tests__/security/safe-fetch.test.ts +0 -125
- package/src/__tests__/skills/platform-skills.extra.test.ts +0 -36
- package/src/__tests__/web/api.clusters.test.ts +0 -65
- package/src/__tests__/web/api.file.test.ts +0 -44
- package/src/__tests__/web/api.grep.test.ts +0 -47
- package/src/__tests__/web/api.info.test.ts +0 -18
- package/src/__tests__/web/api.jobs.test.ts +0 -47
- package/src/__tests__/web/api.progress.test.ts +0 -25
- package/src/__tests__/web/api.stream.test.ts +0 -35
- package/src/__tests__/wiki/providers-reasoning.test.ts +0 -46
- package/src/__tests__/wiki/wiki-review-mode.test.ts +0 -22
- package/src/analysis/benchmark.ts +0 -132
- package/src/analysis/changed-files.ts +0 -73
- package/src/analysis/changed-workspaces.ts +0 -94
- package/src/analysis/churn-cache.ts +0 -179
- package/src/analysis/churn-trend.ts +0 -57
- package/src/analysis/churn.ts +0 -263
- package/src/analysis/cluster-quality.ts +0 -142
- package/src/analysis/combined.ts +0 -41
- package/src/analysis/corpus-health.ts +0 -41
- package/src/analysis/coverage-gaps.ts +0 -246
- package/src/analysis/dep-classification.ts +0 -167
- package/src/analysis/dependency-health.ts +0 -146
- package/src/analysis/duplicate-exports.ts +0 -110
- package/src/analysis/fallow-suppression.ts +0 -98
- package/src/analysis/feature-flags-config.ts +0 -47
- package/src/analysis/feature-flags.ts +0 -223
- package/src/analysis/file-classifier.ts +0 -87
- package/src/analysis/git-changed-files.ts +0 -62
- package/src/analysis/health-baseline.ts +0 -80
- package/src/analysis/issue-filters.ts +0 -56
- package/src/analysis/list.ts +0 -74
- package/src/analysis/node-similarity.ts +0 -115
- package/src/analysis/private-type-leaks.ts +0 -119
- package/src/analysis/progress.ts +0 -43
- package/src/analysis/project-state.ts +0 -95
- package/src/analysis/regression-config.ts +0 -36
- package/src/analysis/rule-overrides.ts +0 -81
- package/src/analysis/scripts.ts +0 -95
- package/src/analysis/shape-extractor.ts +0 -202
- package/src/analysis/since-duration.ts +0 -42
- package/src/analysis/suppression-context.ts +0 -95
- package/src/analysis/suppressions.ts +0 -80
- package/src/analysis/surprise-scorer.ts +0 -74
- package/src/analysis/targets.ts +0 -237
- package/src/analysis/unused-class-members.ts +0 -79
- package/src/analysis/workspace-filter.ts +0 -89
- package/src/analyze/boundary-analysis.ts +0 -129
- package/src/analyze/predicates/file.ts +0 -86
- package/src/analyze/predicates/import.ts +0 -90
- package/src/analyze/predicates/lifecycle.ts +0 -55
- package/src/analyze/unused-deps.ts +0 -70
- package/src/analyze/unused-exports.ts +0 -145
- package/src/analyze/unused-files.ts +0 -46
- package/src/api/production-override.ts +0 -63
- package/src/api/programmatic.ts +0 -118
- package/src/audit.ts +0 -234
- package/src/cache/augment-cache.ts +0 -63
- package/src/cache/extraction-cache.ts +0 -141
- package/src/check/filtering.ts +0 -78
- package/src/check/index.ts +0 -99
- package/src/check/output.ts +0 -79
- package/src/check/rules.ts +0 -61
- package/src/ci-template.ts +0 -84
- package/src/claude-cli.ts +0 -59
- package/src/cli/ai-context.ts +0 -193
- package/src/cli/augment.ts +0 -114
- package/src/cli/check-update.ts +0 -40
- package/src/cli/doctor.ts +0 -182
- package/src/cli/eval-server.ts +0 -126
- package/src/cli/hooks-install.ts +0 -202
- package/src/cli/setup.ts +0 -197
- package/src/cli/skill-gen.ts +0 -347
- package/src/commands/flags.ts +0 -72
- package/src/config/boundary-config.ts +0 -183
- package/src/config/cli-schema.ts +0 -81
- package/src/config/config-parsing.ts +0 -102
- package/src/config/duplicates-config.ts +0 -62
- package/src/config/external-plugin.ts +0 -77
- package/src/config/health-config.ts +0 -42
- package/src/config/ignore-exports-used-in-file.ts +0 -46
- package/src/config/migration-types.ts +0 -73
- package/src/config/output-format.ts +0 -24
- package/src/config/plugins/builtin.ts +0 -411
- package/src/config/plugins/registry.ts +0 -77
- package/src/config/plugins/types.ts +0 -14
- package/src/config/resolution.ts +0 -102
- package/src/config/rules.ts +0 -70
- package/src/config/schema-gen.ts +0 -115
- package/src/config/types.ts +0 -149
- package/src/config/used-class-members.ts +0 -53
- package/src/config/validate.ts +0 -108
- package/src/config/workspace.ts +0 -137
- package/src/coverage/cloud-client.ts +0 -111
- package/src/coverage/upload-inventory.ts +0 -84
- package/src/coverage/upload-source-maps.ts +0 -97
- package/src/discover/entry-points.ts +0 -51
- package/src/discover/infrastructure-entries.ts +0 -175
- package/src/duplicates/detect/concatenation.ts +0 -37
- package/src/duplicates/detect/extraction.ts +0 -107
- package/src/duplicates/detect/filtering.ts +0 -112
- package/src/duplicates/detect/lcp.ts +0 -27
- package/src/duplicates/detect/ranking.ts +0 -16
- package/src/duplicates/detect/statistics.ts +0 -69
- package/src/duplicates/detect/suffix-array.ts +0 -88
- package/src/duplicates/families.ts +0 -95
- package/src/duplicates/normalize.ts +0 -58
- package/src/duplicates/shingle-filter.ts +0 -37
- package/src/duplicates/token-types.ts +0 -62
- package/src/duplicates/tokenize/index.ts +0 -104
- package/src/error/fallow-error.ts +0 -94
- package/src/error.ts +0 -47
- package/src/export/adjacency-matrix.ts +0 -127
- package/src/export/analysis-json.ts +0 -87
- package/src/export/badge.ts +0 -105
- package/src/export/canvas.ts +0 -42
- package/src/export/codeclimate.ts +0 -201
- package/src/export/compact-health.ts +0 -119
- package/src/export/compact.ts +0 -83
- package/src/export/csv.ts +0 -33
- package/src/export/cypher.ts +0 -33
- package/src/export/dot.ts +0 -52
- package/src/export/gexf.ts +0 -59
- package/src/export/graphml.ts +0 -50
- package/src/export/html.ts +0 -548
- package/src/export/index.ts +0 -9
- package/src/export/json.ts +0 -36
- package/src/export/markdown.ts +0 -290
- package/src/export/mermaid.ts +0 -100
- package/src/export/obsidian.ts +0 -44
- package/src/export/sarif.ts +0 -245
- package/src/export/svg.ts +0 -68
- package/src/fix/deps.ts +0 -70
- package/src/fix/enum-members.ts +0 -103
- package/src/fix/export-surgery.ts +0 -197
- package/src/fix/exports.ts +0 -93
- package/src/fix/orchestrator.ts +0 -67
- package/src/graph/analyzer.ts +0 -69
- package/src/graph/author-analytics.ts +0 -217
- package/src/graph/baseline.ts +0 -432
- package/src/graph/clone-families.ts +0 -132
- package/src/graph/codeowners-extended.ts +0 -114
- package/src/graph/codeowners-gitlab.ts +0 -150
- package/src/graph/codeowners.ts +0 -217
- package/src/graph/complexity.ts +0 -200
- package/src/graph/cross-reference-findings.ts +0 -85
- package/src/graph/cross-reference.ts +0 -139
- package/src/graph/cycle-detection.ts +0 -311
- package/src/graph/cycles.ts +0 -222
- package/src/graph/dead-code.ts +0 -128
- package/src/graph/dependency-closure.ts +0 -126
- package/src/graph/dfs.ts +0 -118
- package/src/graph/diff.ts +0 -92
- package/src/graph/duplication-stats.ts +0 -79
- package/src/graph/edge-filter.ts +0 -117
- package/src/graph/explain.ts +0 -133
- package/src/graph/external-style-usage.ts +0 -81
- package/src/graph/health-score.ts +0 -179
- package/src/graph/hotspots.ts +0 -219
- package/src/graph/import-chain.ts +0 -148
- package/src/graph/loader.ts +0 -44
- package/src/graph/maintainability.ts +0 -156
- package/src/graph/merge.ts +0 -174
- package/src/graph/mirrored-dirs.ts +0 -202
- package/src/graph/narrowing.ts +0 -92
- package/src/graph/node-search.ts +0 -201
- package/src/graph/node-types.ts +0 -67
- package/src/graph/normalize-id.ts +0 -138
- package/src/graph/pagerank.ts +0 -165
- package/src/graph/prune.ts +0 -95
- package/src/graph/re-exports/propagate.ts +0 -95
- package/src/graph/reachability.ts +0 -99
- package/src/graph/regex-search.ts +0 -232
- package/src/graph/regression.ts +0 -199
- package/src/graph/resolve/discover-types.ts +0 -45
- package/src/graph/resolve/dynamic-imports.ts +0 -102
- package/src/graph/resolve/fallbacks.ts +0 -79
- package/src/graph/resolve/index.ts +0 -68
- package/src/graph/resolve/path-info.ts +0 -41
- package/src/graph/resolve/re-exports.ts +0 -14
- package/src/graph/resolve/react-native.ts +0 -27
- package/src/graph/resolve/require-imports.ts +0 -18
- package/src/graph/resolve/specifier.ts +0 -120
- package/src/graph/resolve/static-imports.ts +0 -14
- package/src/graph/resolve/types.ts +0 -108
- package/src/graph/resolve/upgrades.ts +0 -32
- package/src/graph/ripple-impact.ts +0 -131
- package/src/graph/risk-profile.ts +0 -179
- package/src/graph/statistics.ts +0 -165
- package/src/graph/stats.ts +0 -157
- package/src/graph/subgraph.ts +0 -162
- package/src/graph/topo-sort.ts +0 -171
- package/src/graph/wcc.ts +0 -187
- package/src/groups/contract-bridge.ts +0 -103
- package/src/groups/contract-registry.ts +0 -263
- package/src/groups/group-config.ts +0 -108
- package/src/groups/group-search.ts +0 -139
- package/src/groups/group-sync.ts +0 -82
- package/src/groups/grpc-extractor.ts +0 -64
- package/src/groups/service-boundary.ts +0 -119
- package/src/groups/topic-extractor.ts +0 -90
- package/src/health/analysis-counts-snapshot.ts +0 -57
- package/src/health/analysis-counts.ts +0 -70
- package/src/health/complexity-findings.ts +0 -115
- package/src/health/distribution-thresholds.ts +0 -54
- package/src/health/grouping.ts +0 -138
- package/src/health/health-grouping.ts +0 -86
- package/src/health/health-report-types.ts +0 -165
- package/src/health/health-report.ts +0 -81
- package/src/health/health-score.ts +0 -65
- package/src/health/hotspot-utils.ts +0 -55
- package/src/health/hotspots.ts +0 -104
- package/src/health/large-functions.ts +0 -34
- package/src/health/ownership-metrics.ts +0 -61
- package/src/health/ownership-risk.ts +0 -98
- package/src/health/ownership.ts +0 -174
- package/src/health/quality-gate.ts +0 -57
- package/src/health/risk-profile.ts +0 -39
- package/src/health/runtime-coverage-report.ts +0 -101
- package/src/health/runtime-coverage.ts +0 -71
- package/src/health/scores.ts +0 -72
- package/src/health/scoring-types.ts +0 -48
- package/src/health/target-thresholds.ts +0 -92
- package/src/health/target-types.ts +0 -54
- package/src/health/targets.ts +0 -151
- package/src/health/timings.ts +0 -86
- package/src/health/trend-types.ts +0 -57
- package/src/health/trends.ts +0 -86
- package/src/health/vital-signs-compute.ts +0 -108
- package/src/health/vital-signs-snapshot.ts +0 -72
- package/src/health/vital-signs.ts +0 -101
- package/src/index.ts +0 -111
- package/src/ingest/git-clone.ts +0 -246
- package/src/ingest/query-memory.ts +0 -132
- package/src/ingest/transcribe.ts +0 -254
- package/src/ingest/url-ingest.ts +0 -87
- package/src/init/agent-hooks.ts +0 -86
- package/src/init/git-hooks.ts +0 -71
- package/src/init/project-detection.ts +0 -105
- package/src/license/manager.ts +0 -120
- package/src/lsp/code-actions.ts +0 -127
- package/src/lsp/code-lens.ts +0 -56
- package/src/lsp/diagnostics-ext.ts +0 -150
- package/src/lsp/diagnostics-push.ts +0 -103
- package/src/lsp/diagnostics.ts +0 -98
- package/src/lsp/hover.ts +0 -64
- package/src/lsp/server.ts +0 -254
- package/src/mcp/params.ts +0 -201
- package/src/mcp/resources.ts +0 -124
- package/src/mcp/tool-builders.ts +0 -203
- package/src/mcp-resources/communities-resource.ts +0 -72
- package/src/mcp-resources/graph-resource.ts +0 -14
- package/src/mcp-resources/index.ts +0 -9
- package/src/mcp-resources/named-cluster-resource.ts +0 -35
- package/src/mcp-resources/named-process-resource.ts +0 -26
- package/src/mcp-resources/processes-resource.ts +0 -67
- package/src/mcp-resources/repo-context-resource.ts +0 -36
- package/src/mcp-resources/repos-resource.ts +0 -21
- package/src/mcp-resources/schema-resource.ts +0 -46
- package/src/mcp-resources/wiki-resource.ts +0 -23
- package/src/mcp-tools/api-impact.ts +0 -181
- package/src/mcp-tools/context.ts +0 -111
- package/src/mcp-tools/cypher.ts +0 -29
- package/src/mcp-tools/detect-changes.ts +0 -116
- package/src/mcp-tools/explain.ts +0 -65
- package/src/mcp-tools/graph-query.ts +0 -128
- package/src/mcp-tools/group-list.ts +0 -88
- package/src/mcp-tools/group-query.ts +0 -26
- package/src/mcp-tools/group-sync.ts +0 -32
- package/src/mcp-tools/impact.ts +0 -202
- package/src/mcp-tools/index.ts +0 -21
- package/src/mcp-tools/list-repos.ts +0 -38
- package/src/mcp-tools/neighbors.ts +0 -80
- package/src/mcp-tools/query.ts +0 -86
- package/src/mcp-tools/rename.ts +0 -118
- package/src/mcp-tools/route-map.ts +0 -98
- package/src/mcp-tools/serve.ts +0 -41
- package/src/mcp-tools/shape-check.ts +0 -182
- package/src/mcp-tools/staleness.ts +0 -13
- package/src/mcp-tools/tool-map.ts +0 -66
- package/src/mcp-tools/wiki-build.ts +0 -37
- package/src/mcp-tools/wiki.ts +0 -28
- package/src/migrate/jscpd.ts +0 -78
- package/src/migrate/jsonc-gen.ts +0 -38
- package/src/migrate/knip.ts +0 -126
- package/src/migrate/toml-gen.ts +0 -48
- package/src/parsers/c.ts +0 -31
- package/src/parsers/cpp.ts +0 -29
- package/src/parsers/csharp.ts +0 -43
- package/src/parsers/dart.ts +0 -39
- package/src/parsers/extractor.ts +0 -202
- package/src/parsers/go.ts +0 -27
- package/src/parsers/java.ts +0 -27
- package/src/parsers/kotlin.ts +0 -36
- package/src/parsers/language-config.ts +0 -28
- package/src/parsers/language-parsers.ts +0 -120
- package/src/parsers/loader.ts +0 -149
- package/src/parsers/named-bindings.ts +0 -63
- package/src/parsers/php.ts +0 -37
- package/src/parsers/python.ts +0 -26
- package/src/parsers/ruby.ts +0 -39
- package/src/parsers/rust.ts +0 -25
- package/src/parsers/swift.ts +0 -28
- package/src/parsers/typescript.ts +0 -41
- package/src/parsers/vue.ts +0 -79
- package/src/pipeline/cluster-only.ts +0 -64
- package/src/pipeline/effort.ts +0 -50
- package/src/pipeline/orchestrator.ts +0 -384
- package/src/pipeline/phases/boundary.ts +0 -151
- package/src/pipeline/phases/bridge-adapters/electron-ipc.ts +0 -91
- package/src/pipeline/phases/bridge-adapters/registry.ts +0 -14
- package/src/pipeline/phases/bridge-adapters/tauri.ts +0 -103
- package/src/pipeline/phases/bridge-adapters/types.ts +0 -31
- package/src/pipeline/phases/bridge-adapters/wails.ts +0 -33
- package/src/pipeline/phases/bridge-resolver.ts +0 -77
- package/src/pipeline/phases/call-site-extractors.ts +0 -177
- package/src/pipeline/phases/communities.ts +0 -183
- package/src/pipeline/phases/contextual-proximity.ts +0 -88
- package/src/pipeline/phases/cross-file.ts +0 -116
- package/src/pipeline/phases/docs-parse.ts +0 -307
- package/src/pipeline/phases/evidence.ts +0 -9
- package/src/pipeline/phases/field-access.ts +0 -49
- package/src/pipeline/phases/framework-detect.ts +0 -109
- package/src/pipeline/phases/god-nodes.ts +0 -163
- package/src/pipeline/phases/import-resolver.ts +0 -114
- package/src/pipeline/phases/leiden.ts +0 -77
- package/src/pipeline/phases/llm-extract.ts +0 -178
- package/src/pipeline/phases/markdown.ts +0 -121
- package/src/pipeline/phases/middleware-extractor.ts +0 -127
- package/src/pipeline/phases/module-resolution.ts +0 -294
- package/src/pipeline/phases/mro.ts +0 -56
- package/src/pipeline/phases/orm.ts +0 -503
- package/src/pipeline/phases/parse.ts +0 -222
- package/src/pipeline/phases/pdf-parse.ts +0 -133
- package/src/pipeline/phases/processes.ts +0 -249
- package/src/pipeline/phases/re-export-propagation.ts +0 -160
- package/src/pipeline/phases/reachability.ts +0 -156
- package/src/pipeline/phases/routes.ts +0 -350
- package/src/pipeline/phases/scan.ts +0 -133
- package/src/pipeline/phases/scope-resolution.ts +0 -442
- package/src/pipeline/phases/structure.ts +0 -68
- package/src/pipeline/phases/suggest.ts +0 -92
- package/src/pipeline/phases/surprises.ts +0 -83
- package/src/pipeline/phases/tools.ts +0 -180
- package/src/pipeline/phases/variables-phase.ts +0 -37
- package/src/pipeline/phases/variables.ts +0 -67
- package/src/pipeline/phases/wildcard-phase.ts +0 -50
- package/src/pipeline/phases/wildcard-synthesis.ts +0 -214
- package/src/pipeline/progress.ts +0 -58
- package/src/pipeline/runner.ts +0 -88
- package/src/pipeline/types.ts +0 -41
- package/src/query/cypher-parser.ts +0 -450
- package/src/registry/repo-registry.ts +0 -125
- package/src/regression/baseline-deltas.ts +0 -215
- package/src/regression/baseline.ts +0 -76
- package/src/regression/counts.ts +0 -87
- package/src/regression/outcome.ts +0 -78
- package/src/regression/tolerance.ts +0 -35
- package/src/report/attributed-duplication.ts +0 -112
- package/src/report/badge-svg.ts +0 -100
- package/src/report/cross-ref-human.ts +0 -50
- package/src/report/duplication-grouping.ts +0 -74
- package/src/report/grouping.ts +0 -137
- package/src/report/human-check.ts +0 -291
- package/src/report/human-dupes.ts +0 -142
- package/src/report/human-health.ts +0 -195
- package/src/report/human.ts +0 -120
- package/src/report/json-actions.ts +0 -91
- package/src/report/json-builders.ts +0 -70
- package/src/report/json-schema.ts +0 -75
- package/src/report/number-format.ts +0 -91
- package/src/report/output-grouped.ts +0 -102
- package/src/report/pipeline-perf.ts +0 -56
- package/src/report/trace-human.ts +0 -127
- package/src/reporting/graph-report.ts +0 -431
- package/src/results/fallow-results.ts +0 -152
- package/src/results/types.ts +0 -149
- package/src/scope-resolution/evidence-weights.ts +0 -41
- package/src/search/ast-chunker.ts +0 -206
- package/src/search/diacritic.ts +0 -7
- package/src/search/hybrid-query.ts +0 -65
- package/src/search/rrf.ts +0 -51
- package/src/security/safe-fetch.ts +0 -113
- package/src/security/sensitive-files.ts +0 -24
- package/src/skills/platform-skills.ts +0 -233
- package/src/staleness/git-staleness.ts +0 -66
- package/src/storage/db.ts +0 -110
- package/src/storage/edge-store.ts +0 -103
- package/src/storage/file-cache.ts +0 -78
- package/src/storage/fts-store.ts +0 -385
- package/src/storage/node-store.ts +0 -209
- package/src/storage/schema.ts +0 -171
- package/src/storage/suppressions.ts +0 -145
- package/src/storage/unlinked-refs.ts +0 -117
- package/src/types.ts +0 -197
- package/src/validation/extraction-validator.ts +0 -54
- package/src/watch/watcher.ts +0 -160
- package/src/web/analyze-api.ts +0 -146
- package/src/web/api.ts +0 -584
- package/src/web/async-jobs.ts +0 -109
- package/src/web/mcp-http.ts +0 -227
- package/src/web/react-ui.ts +0 -78
- package/src/web/server.ts +0 -90
- package/src/web/ui/index.html +0 -204
- package/src/wiki/gist-publisher.ts +0 -76
- package/src/wiki/prompt-builder.ts +0 -35
- package/src/wiki/providers.ts +0 -134
- package/src/wiki/wiki-generator.ts +0 -223
- package/src/wiki/wiki-store.ts +0 -49
- package/tsconfig.json +0 -11
- package/vitest.config.ts +0 -20
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
import type { MonographDb } from '../storage/db.js';
|
|
2
|
-
|
|
3
|
-
export interface UntestedFile {
|
|
4
|
-
nodeId: string;
|
|
5
|
-
filePath: string;
|
|
6
|
-
reachabilityRole: string; // 'runtime'
|
|
7
|
-
inDegree: number; // from runtime files
|
|
8
|
-
reason: string; // e.g. 'No test imports this file'
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface UntestedExport {
|
|
12
|
-
nodeId: string;
|
|
13
|
-
name: string;
|
|
14
|
-
filePath: string | null;
|
|
15
|
-
startLine: number | null;
|
|
16
|
-
exportType: string; // label
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface CoverageGapsResult {
|
|
20
|
-
untestedFiles: UntestedFile[];
|
|
21
|
-
untestedExports: UntestedExport[];
|
|
22
|
-
fileCoveragePct: number; // (runtime files reachable by tests) / (total runtime files) * 100
|
|
23
|
-
exportCoveragePct: number;
|
|
24
|
-
summary: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface FileRow {
|
|
28
|
-
id: string;
|
|
29
|
-
file_path: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
interface ImportEdgeRow {
|
|
33
|
-
source_id: string;
|
|
34
|
-
target_id: string;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface ExportRow {
|
|
38
|
-
id: string;
|
|
39
|
-
name: string;
|
|
40
|
-
file_path: string | null;
|
|
41
|
-
start_line: number | null;
|
|
42
|
-
label: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interface InDegreeRow {
|
|
46
|
-
target_id: string;
|
|
47
|
-
cnt: number;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function computeCoverageGaps(db: MonographDb): CoverageGapsResult {
|
|
51
|
-
// Runtime-reachable files
|
|
52
|
-
const runtimeFiles = db.prepare(
|
|
53
|
-
`SELECT id, file_path FROM nodes
|
|
54
|
-
WHERE label = 'File'
|
|
55
|
-
AND json_extract(properties, '$.reachabilityRole') = 'runtime'`
|
|
56
|
-
).all() as FileRow[];
|
|
57
|
-
|
|
58
|
-
// Test entry points
|
|
59
|
-
const testFiles = db.prepare(
|
|
60
|
-
`SELECT id, file_path FROM nodes
|
|
61
|
-
WHERE label = 'File'
|
|
62
|
-
AND json_extract(properties, '$.reachabilityRole') = 'test'`
|
|
63
|
-
).all() as FileRow[];
|
|
64
|
-
|
|
65
|
-
// All IMPORTS edges between files for BFS
|
|
66
|
-
const allImportEdges = db.prepare(
|
|
67
|
-
`SELECT e.source_id, e.target_id
|
|
68
|
-
FROM edges e
|
|
69
|
-
WHERE e.relation IN ('IMPORTS', 'RE_EXPORTS')
|
|
70
|
-
AND e.source_id IN (SELECT id FROM nodes WHERE label = 'File')
|
|
71
|
-
AND e.target_id IN (SELECT id FROM nodes WHERE label = 'File')`
|
|
72
|
-
).all() as ImportEdgeRow[];
|
|
73
|
-
|
|
74
|
-
// Build forward adjacency for BFS
|
|
75
|
-
const forwardAdj = new Map<string, string[]>();
|
|
76
|
-
for (const edge of allImportEdges) {
|
|
77
|
-
let list = forwardAdj.get(edge.source_id);
|
|
78
|
-
if (!list) {
|
|
79
|
-
list = [];
|
|
80
|
-
forwardAdj.set(edge.source_id, list);
|
|
81
|
-
}
|
|
82
|
-
list.push(edge.target_id);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// BFS from test entry points
|
|
86
|
-
const testReachable = new Set<string>();
|
|
87
|
-
const queue: string[] = [];
|
|
88
|
-
for (const tf of testFiles) {
|
|
89
|
-
if (!testReachable.has(tf.id)) {
|
|
90
|
-
testReachable.add(tf.id);
|
|
91
|
-
queue.push(tf.id);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
let head = 0;
|
|
96
|
-
while (head < queue.length) {
|
|
97
|
-
const current = queue[head++];
|
|
98
|
-
const neighbors = forwardAdj.get(current) ?? [];
|
|
99
|
-
for (const neighbor of neighbors) {
|
|
100
|
-
if (!testReachable.has(neighbor)) {
|
|
101
|
-
testReachable.add(neighbor);
|
|
102
|
-
queue.push(neighbor);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Compute in-degree from runtime files only (not test files) so fan-in reflects
|
|
108
|
-
// real dependency weight, not test coverage depth.
|
|
109
|
-
const runtimeFileIdSet = new Set(runtimeFiles.map(rf => rf.id));
|
|
110
|
-
const inDegreeMap = new Map<string, number>();
|
|
111
|
-
for (const edge of allImportEdges) {
|
|
112
|
-
if (!runtimeFileIdSet.has(edge.source_id)) continue;
|
|
113
|
-
const current = inDegreeMap.get(edge.target_id) ?? 0;
|
|
114
|
-
inDegreeMap.set(edge.target_id, current + 1);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Untested files = runtime files NOT in the test-reachable set
|
|
118
|
-
const untestedFiles: UntestedFile[] = [];
|
|
119
|
-
for (const rf of runtimeFiles) {
|
|
120
|
-
if (!testReachable.has(rf.id)) {
|
|
121
|
-
untestedFiles.push({
|
|
122
|
-
nodeId: rf.id,
|
|
123
|
-
filePath: rf.file_path,
|
|
124
|
-
reachabilityRole: 'runtime',
|
|
125
|
-
inDegree: inDegreeMap.get(rf.id) ?? 0,
|
|
126
|
-
reason: 'No test imports this file',
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// All exported symbols
|
|
132
|
-
const allExportedRows = db.prepare(
|
|
133
|
-
`SELECT n.id, n.name, n.file_path, n.start_line, n.label
|
|
134
|
-
FROM nodes n
|
|
135
|
-
WHERE n.is_exported = 1
|
|
136
|
-
AND n.label IN ('Function','Class','Method','Interface','Const','TypeAlias','Enum','Variable')`
|
|
137
|
-
).all() as ExportRow[];
|
|
138
|
-
|
|
139
|
-
// Runtime file IDs set for quick lookup
|
|
140
|
-
const runtimeFileIds = new Set(runtimeFiles.map(rf => rf.id));
|
|
141
|
-
|
|
142
|
-
// Map file_path -> file node id for runtime files
|
|
143
|
-
const runtimeFilePathToId = new Map<string, string>();
|
|
144
|
-
for (const rf of runtimeFiles) {
|
|
145
|
-
runtimeFilePathToId.set(rf.file_path, rf.id);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Determine which file a symbol belongs to (by file_path)
|
|
149
|
-
const testedRuntimeFileIds = new Set<string>();
|
|
150
|
-
for (const rf of runtimeFiles) {
|
|
151
|
-
if (testReachable.has(rf.id)) {
|
|
152
|
-
testedRuntimeFileIds.add(rf.id);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const untestedExports: UntestedExport[] = [];
|
|
157
|
-
let totalRuntimeExports = 0;
|
|
158
|
-
let testedRuntimeExports = 0;
|
|
159
|
-
|
|
160
|
-
for (const exp of allExportedRows) {
|
|
161
|
-
if (!exp.file_path) continue;
|
|
162
|
-
const fileId = runtimeFilePathToId.get(exp.file_path);
|
|
163
|
-
if (!fileId) continue; // not a runtime file
|
|
164
|
-
|
|
165
|
-
totalRuntimeExports++;
|
|
166
|
-
if (testedRuntimeFileIds.has(fileId)) {
|
|
167
|
-
testedRuntimeExports++;
|
|
168
|
-
} else {
|
|
169
|
-
untestedExports.push({
|
|
170
|
-
nodeId: exp.id,
|
|
171
|
-
name: exp.name,
|
|
172
|
-
filePath: exp.file_path,
|
|
173
|
-
startLine: exp.start_line ?? null,
|
|
174
|
-
exportType: exp.label,
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const totalRuntimeFiles = runtimeFiles.length;
|
|
180
|
-
const testedRuntimeFiles = runtimeFiles.filter(rf => testReachable.has(rf.id)).length;
|
|
181
|
-
|
|
182
|
-
const fileCoveragePct = totalRuntimeFiles > 0
|
|
183
|
-
? (testedRuntimeFiles / totalRuntimeFiles) * 100
|
|
184
|
-
: 100;
|
|
185
|
-
|
|
186
|
-
const exportCoveragePct = totalRuntimeExports > 0
|
|
187
|
-
? (testedRuntimeExports / totalRuntimeExports) * 100
|
|
188
|
-
: 100;
|
|
189
|
-
|
|
190
|
-
const summary = [
|
|
191
|
-
`${testedRuntimeFiles}/${totalRuntimeFiles} runtime files reachable by tests`,
|
|
192
|
-
`(${fileCoveragePct.toFixed(1)}% file coverage,`,
|
|
193
|
-
`${exportCoveragePct.toFixed(1)}% export coverage).`,
|
|
194
|
-
untestedFiles.length > 0
|
|
195
|
-
? `${untestedFiles.length} untested file(s) found.`
|
|
196
|
-
: 'All runtime files are test-reachable.',
|
|
197
|
-
].join(' ');
|
|
198
|
-
|
|
199
|
-
return {
|
|
200
|
-
untestedFiles,
|
|
201
|
-
untestedExports,
|
|
202
|
-
fileCoveragePct,
|
|
203
|
-
exportCoveragePct,
|
|
204
|
-
summary,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/** Format CoverageGapsResult as structured text with file:line hints for LLM navigation. */
|
|
209
|
-
export function formatCoverageGaps(result: CoverageGapsResult, topN = 20): string {
|
|
210
|
-
const lines: string[] = [result.summary, ''];
|
|
211
|
-
|
|
212
|
-
if (result.untestedFiles.length > 0) {
|
|
213
|
-
// Sort untested files by inDegree descending — highest-impact first
|
|
214
|
-
const sorted = [...result.untestedFiles].sort((a, b) => b.inDegree - a.inDegree);
|
|
215
|
-
const shown = sorted.slice(0, topN);
|
|
216
|
-
lines.push(`Top untested files by import-count (${shown.length}/${result.untestedFiles.length} shown):`);
|
|
217
|
-
for (const f of shown) {
|
|
218
|
-
lines.push(` ${f.filePath} in-degree:${f.inDegree}`);
|
|
219
|
-
}
|
|
220
|
-
lines.push('');
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (result.untestedExports.length > 0) {
|
|
224
|
-
// Group untested exports by file
|
|
225
|
-
const byFile = new Map<string, UntestedExport[]>();
|
|
226
|
-
for (const exp of result.untestedExports) {
|
|
227
|
-
const key = exp.filePath ?? '(unknown)';
|
|
228
|
-
let group = byFile.get(key);
|
|
229
|
-
if (!group) { group = []; byFile.set(key, group); }
|
|
230
|
-
group.push(exp);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
lines.push(`Untested exported symbols (${result.untestedExports.length}) grouped by file:`);
|
|
234
|
-
for (const [filePath, exports] of byFile) {
|
|
235
|
-
lines.push(` ${filePath}`);
|
|
236
|
-
for (const exp of exports) {
|
|
237
|
-
const ref = exp.startLine != null ? `${filePath}:${exp.startLine}` : filePath;
|
|
238
|
-
lines.push(` ${exp.exportType} ${exp.name} (${ref})`);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
lines.push('');
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
lines.push('Fix: add tests importing the untested files, or mark files as non-runtime if they are build artifacts.');
|
|
245
|
-
return lines.join('\n').trimEnd();
|
|
246
|
-
}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import type { MonographDb } from '../storage/db.js';
|
|
2
|
-
|
|
3
|
-
export interface PackageDepClassification {
|
|
4
|
-
packageName: string;
|
|
5
|
-
usedAsValue: boolean; // has any non-type-only import
|
|
6
|
-
usedAsTypeOnly: boolean; // has any type-only import
|
|
7
|
-
recommendation: 'keep-as-dep' | 'move-to-devdeps' | 'type-only' | 'unused';
|
|
8
|
-
importCount: number;
|
|
9
|
-
typeOnlyImportCount: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface DepClassificationResult {
|
|
13
|
-
packages: PackageDepClassification[];
|
|
14
|
-
typeOnlyCount: number; // packages only used in type positions
|
|
15
|
-
mixedCount: number; // packages used in both
|
|
16
|
-
valueOnlyCount: number;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface EdgeRow {
|
|
20
|
-
relation: string;
|
|
21
|
-
confidence: string | null;
|
|
22
|
-
src: string;
|
|
23
|
-
tgt: string;
|
|
24
|
-
tgt_name: string;
|
|
25
|
-
properties: string | null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function isExternalPackage(tgtName: string, tgtFilePath: string): boolean {
|
|
29
|
-
// External if the file_path doesn't start with '/' or '.'
|
|
30
|
-
// and doesn't look like a relative import
|
|
31
|
-
if (!tgtFilePath) {
|
|
32
|
-
// Fall back to name heuristic: starts with alpha, no path separators
|
|
33
|
-
return /^[a-zA-Z@]/.test(tgtName) && !tgtName.includes('/') || /^@[a-zA-Z]/.test(tgtName);
|
|
34
|
-
}
|
|
35
|
-
return !tgtFilePath.startsWith('/') && !tgtFilePath.startsWith('.');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function extractPackageName(tgt: string): string {
|
|
39
|
-
// Handle scoped packages like @scope/name
|
|
40
|
-
if (tgt.startsWith('@')) {
|
|
41
|
-
const parts = tgt.split('/');
|
|
42
|
-
return parts.slice(0, 2).join('/');
|
|
43
|
-
}
|
|
44
|
-
// Plain packages: take only the package name portion (before any '/')
|
|
45
|
-
return tgt.split('/')[0];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function classifyDependencies(db: MonographDb): DepClassificationResult {
|
|
49
|
-
const rows = db.prepare(`
|
|
50
|
-
SELECT e.relation, e.confidence, n_src.file_path as src, n_tgt.file_path as tgt, n_tgt.name as tgt_name, e.properties
|
|
51
|
-
FROM edges e
|
|
52
|
-
JOIN nodes n_src ON n_src.id = e.source_id
|
|
53
|
-
JOIN nodes n_tgt ON n_tgt.id = e.target_id
|
|
54
|
-
WHERE e.relation = 'IMPORTS'
|
|
55
|
-
`).all() as EdgeRow[];
|
|
56
|
-
|
|
57
|
-
// Aggregate per external package
|
|
58
|
-
const packageMap = new Map<string, { valueImports: number; typeImports: number }>();
|
|
59
|
-
|
|
60
|
-
for (const row of rows) {
|
|
61
|
-
const tgtPath = row.tgt ?? '';
|
|
62
|
-
const tgtName = row.tgt_name ?? '';
|
|
63
|
-
|
|
64
|
-
if (!isExternalPackage(tgtName, tgtPath)) continue;
|
|
65
|
-
|
|
66
|
-
const packageName = extractPackageName(tgtName || tgtPath);
|
|
67
|
-
if (!packageName) continue;
|
|
68
|
-
|
|
69
|
-
// Check if type-only: parse properties JSON for isTypeOnly flag
|
|
70
|
-
let isTypeOnly = false;
|
|
71
|
-
if (row.properties) {
|
|
72
|
-
try {
|
|
73
|
-
const props = JSON.parse(row.properties) as Record<string, unknown>;
|
|
74
|
-
isTypeOnly = props['isTypeOnly'] === true;
|
|
75
|
-
} catch {
|
|
76
|
-
// fall through — infer from confidence
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// Note: INFERRED confidence is NOT a reliable signal for type-only imports —
|
|
80
|
-
// re-export propagation and wildcard synthesis both emit INFERRED edges for real
|
|
81
|
-
// runtime imports. Only trust the explicit isTypeOnly property.
|
|
82
|
-
|
|
83
|
-
const existing = packageMap.get(packageName) ?? { valueImports: 0, typeImports: 0 };
|
|
84
|
-
if (isTypeOnly) {
|
|
85
|
-
existing.typeImports++;
|
|
86
|
-
} else {
|
|
87
|
-
existing.valueImports++;
|
|
88
|
-
}
|
|
89
|
-
packageMap.set(packageName, existing);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const packages: PackageDepClassification[] = [];
|
|
93
|
-
|
|
94
|
-
for (const [packageName, counts] of packageMap) {
|
|
95
|
-
const usedAsValue = counts.valueImports > 0;
|
|
96
|
-
const usedAsTypeOnly = counts.typeImports > 0;
|
|
97
|
-
|
|
98
|
-
let recommendation: PackageDepClassification['recommendation'];
|
|
99
|
-
if (usedAsValue && usedAsTypeOnly) {
|
|
100
|
-
recommendation = 'keep-as-dep';
|
|
101
|
-
} else if (usedAsValue && !usedAsTypeOnly) {
|
|
102
|
-
recommendation = 'keep-as-dep';
|
|
103
|
-
} else if (!usedAsValue && usedAsTypeOnly) {
|
|
104
|
-
recommendation = 'type-only';
|
|
105
|
-
} else {
|
|
106
|
-
recommendation = 'unused';
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
packages.push({
|
|
110
|
-
packageName,
|
|
111
|
-
usedAsValue,
|
|
112
|
-
usedAsTypeOnly,
|
|
113
|
-
recommendation,
|
|
114
|
-
importCount: counts.valueImports + counts.typeImports,
|
|
115
|
-
typeOnlyImportCount: counts.typeImports,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Sort: 'type-only' first, then 'unused', then rest
|
|
120
|
-
const ORDER: Record<string, number> = { 'type-only': 0, 'unused': 1, 'move-to-devdeps': 2, 'keep-as-dep': 3 };
|
|
121
|
-
packages.sort((a, b) => (ORDER[a.recommendation] ?? 3) - (ORDER[b.recommendation] ?? 3));
|
|
122
|
-
|
|
123
|
-
const typeOnlyCount = packages.filter(p => p.recommendation === 'type-only').length;
|
|
124
|
-
const mixedCount = packages.filter(p => p.usedAsValue && p.usedAsTypeOnly).length;
|
|
125
|
-
const valueOnlyCount = packages.filter(p => p.usedAsValue && !p.usedAsTypeOnly).length;
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
packages,
|
|
129
|
-
typeOnlyCount,
|
|
130
|
-
mixedCount,
|
|
131
|
-
valueOnlyCount,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/** Format DepClassificationResult as structured text for LLM navigation and actionable guidance. */
|
|
136
|
-
export function formatDepClassification(result: DepClassificationResult): string {
|
|
137
|
-
if (result.packages.length === 0) {
|
|
138
|
-
return 'Dependency classification: no external packages detected.';
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const lines: string[] = [
|
|
142
|
-
`Dependency classification: ${result.packages.length} external package(s).`,
|
|
143
|
-
` type-only: ${result.typeOnlyCount} mixed: ${result.mixedCount} value-only: ${result.valueOnlyCount}`,
|
|
144
|
-
'',
|
|
145
|
-
];
|
|
146
|
-
|
|
147
|
-
const groups: Array<[PackageDepClassification['recommendation'], string, string]> = [
|
|
148
|
-
['type-only', 'Type-only (move to devDependencies or use @types)', 'Move to devDependencies — not needed at runtime.'],
|
|
149
|
-
['unused', 'Unused', 'Remove from dependencies — no imports detected.'],
|
|
150
|
-
['move-to-devdeps', 'Move to devDependencies', 'Only used in non-production code paths.'],
|
|
151
|
-
['keep-as-dep', 'Keep as dependency', 'Used as runtime value imports — keep in dependencies.'],
|
|
152
|
-
];
|
|
153
|
-
|
|
154
|
-
for (const [rec, heading, advice] of groups) {
|
|
155
|
-
const pkgs = result.packages.filter(p => p.recommendation === rec);
|
|
156
|
-
if (pkgs.length === 0) continue;
|
|
157
|
-
lines.push(`${heading} (${pkgs.length}):`);
|
|
158
|
-
for (const p of pkgs) {
|
|
159
|
-
const typeNote = p.typeOnlyImportCount > 0 ? ` (${p.typeOnlyImportCount} type-only)` : '';
|
|
160
|
-
lines.push(` ${p.packageName} imports:${p.importCount}${typeNote}`);
|
|
161
|
-
}
|
|
162
|
-
lines.push(` → ${advice}`);
|
|
163
|
-
lines.push('');
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return lines.join('\n').trimEnd();
|
|
167
|
-
}
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Dependency health scoring.
|
|
3
|
-
*
|
|
4
|
-
* Produces a composite [0, 1] score by combining four sub-metrics:
|
|
5
|
-
*
|
|
6
|
-
* 1. Cycle penalty — fraction of nodes involved in cycles (lower = worse)
|
|
7
|
-
* 2. Dead-code ratio — fraction of nodes that are unreachable / unused
|
|
8
|
-
* 3. Fan-out skew — coefficient of variation of out-degrees (high skew = god nodes)
|
|
9
|
-
* 4. God-node concentration — max in-degree / total edges (hub dominance)
|
|
10
|
-
*
|
|
11
|
-
* Final score = 1 − weighted average of penalties.
|
|
12
|
-
* All individual penalty components are clamped to [0, 1].
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
export interface DependencyHealthEdge {
|
|
16
|
-
sourceId: string;
|
|
17
|
-
targetId: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface DependencyHealthInput {
|
|
21
|
-
/** All node IDs in the graph. */
|
|
22
|
-
nodes: string[];
|
|
23
|
-
/** All directed edges. */
|
|
24
|
-
edges: DependencyHealthEdge[];
|
|
25
|
-
/** Pre-computed number of cycles (e.g., from detectCycles). */
|
|
26
|
-
cycleCount: number;
|
|
27
|
-
/** Pre-computed count of dead nodes (e.g., from detectDeadCode). */
|
|
28
|
-
deadNodeCount: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface DependencyHealthDetails {
|
|
32
|
-
/** Fraction of nodes involved in cycles in [0, 1]. */
|
|
33
|
-
cyclePenalty: number;
|
|
34
|
-
/** Fraction of dead nodes in [0, 1]. */
|
|
35
|
-
deadCodeRatio: number;
|
|
36
|
-
/** Coefficient of variation for out-degree distribution (normalised to [0,1]). */
|
|
37
|
-
fanSkew: number;
|
|
38
|
-
/** Max in-degree / total edge count — hub dominance in [0, 1]. */
|
|
39
|
-
godNodeConcentration: number;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface DependencyHealthResult {
|
|
43
|
-
/** Composite health score in [0, 1] where 1 is perfectly healthy. */
|
|
44
|
-
score: number;
|
|
45
|
-
details: DependencyHealthDetails;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function stdDev(values: number[]): number {
|
|
49
|
-
if (values.length === 0) return 0;
|
|
50
|
-
const mean = values.reduce((a, b) => a + b, 0) / values.length;
|
|
51
|
-
const variance = values.reduce((a, b) => a + (b - mean) ** 2, 0) / values.length;
|
|
52
|
-
return Math.sqrt(variance);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function clamp(x: number): number {
|
|
56
|
-
return Math.max(0, Math.min(1, x));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Compute a composite dependency health score for the given graph.
|
|
61
|
-
*/
|
|
62
|
-
export function dependencyHealth(input: DependencyHealthInput): DependencyHealthResult {
|
|
63
|
-
const { nodes, edges, cycleCount, deadNodeCount } = input;
|
|
64
|
-
const n = nodes.length;
|
|
65
|
-
const m = edges.length;
|
|
66
|
-
|
|
67
|
-
if (n === 0) {
|
|
68
|
-
return {
|
|
69
|
-
score: 1,
|
|
70
|
-
details: { cyclePenalty: 0, deadCodeRatio: 0, fanSkew: 0, godNodeConcentration: 0 },
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// 1. Cycle penalty: cycleCount is the number of nodes in cycles (from topologicalLevelSort)
|
|
75
|
-
// Normalised by node count. Capped at 1.
|
|
76
|
-
const cyclePenalty = clamp(cycleCount / n);
|
|
77
|
-
|
|
78
|
-
// 2. Dead-code ratio
|
|
79
|
-
const deadCodeRatio = clamp(deadNodeCount / n);
|
|
80
|
-
|
|
81
|
-
// 3. Fan-out skew: coefficient of variation of out-degrees, normalised
|
|
82
|
-
const outDegree = new Map<string, number>(nodes.map(id => [id, 0]));
|
|
83
|
-
for (const { sourceId } of edges) {
|
|
84
|
-
outDegree.set(sourceId, (outDegree.get(sourceId) ?? 0) + 1);
|
|
85
|
-
}
|
|
86
|
-
const outValues = [...outDegree.values()];
|
|
87
|
-
const outMean = outValues.reduce((a, b) => a + b, 0) / n;
|
|
88
|
-
const cv = outMean > 0 ? stdDev(outValues) / outMean : 0;
|
|
89
|
-
// CV > 2 → very skewed; normalise to [0,1] by clamping at 4
|
|
90
|
-
const fanSkew = clamp(cv / 4);
|
|
91
|
-
|
|
92
|
-
// 4. God-node concentration: max in-degree / total edges
|
|
93
|
-
const inDegree = new Map<string, number>(nodes.map(id => [id, 0]));
|
|
94
|
-
for (const { targetId } of edges) {
|
|
95
|
-
inDegree.set(targetId, (inDegree.get(targetId) ?? 0) + 1);
|
|
96
|
-
}
|
|
97
|
-
// Use reduce instead of spread to avoid RangeError on graphs with 65k+ nodes
|
|
98
|
-
const maxInDeg = inDegree.size > 0
|
|
99
|
-
? [...inDegree.values()].reduce((a, b) => Math.max(a, b), 0)
|
|
100
|
-
: 0;
|
|
101
|
-
const godNodeConcentration = m > 0 ? clamp(maxInDeg / m) : 0;
|
|
102
|
-
|
|
103
|
-
// Weighted composite penalty (weights sum to 1)
|
|
104
|
-
const W_CYCLE = 0.35;
|
|
105
|
-
const W_DEAD = 0.25;
|
|
106
|
-
const W_FAN = 0.20;
|
|
107
|
-
const W_GOD = 0.20;
|
|
108
|
-
|
|
109
|
-
const penalty =
|
|
110
|
-
W_CYCLE * cyclePenalty +
|
|
111
|
-
W_DEAD * deadCodeRatio +
|
|
112
|
-
W_FAN * fanSkew +
|
|
113
|
-
W_GOD * godNodeConcentration;
|
|
114
|
-
|
|
115
|
-
const score = clamp(1 - penalty);
|
|
116
|
-
|
|
117
|
-
return {
|
|
118
|
-
score,
|
|
119
|
-
details: { cyclePenalty, deadCodeRatio, fanSkew, godNodeConcentration },
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Format dependency health results as structured text for LLM consumption.
|
|
125
|
-
*/
|
|
126
|
-
export function formatDependencyHealth(result: DependencyHealthResult): string {
|
|
127
|
-
const { score, details } = result;
|
|
128
|
-
const pct = (v: number) => `${(v * 100).toFixed(1)}%`;
|
|
129
|
-
const grade = score >= 0.9 ? 'Excellent' : score >= 0.75 ? 'Good' : score >= 0.5 ? 'Fair' : 'Poor';
|
|
130
|
-
const lines: string[] = [
|
|
131
|
-
`Dependency health score: ${pct(score)} (${grade})`,
|
|
132
|
-
` Cycle penalty : ${pct(details.cyclePenalty)} (fraction of nodes in cycles; weight 35%)`,
|
|
133
|
-
` Dead-code ratio : ${pct(details.deadCodeRatio)} (fraction of unreachable nodes; weight 25%)`,
|
|
134
|
-
` Fan-out skew : ${pct(details.fanSkew)} (out-degree coefficient of variation / 4; weight 20%)`,
|
|
135
|
-
` God-node density : ${pct(details.godNodeConcentration)} (max in-degree / total edges; weight 20%)`,
|
|
136
|
-
];
|
|
137
|
-
const advice: string[] = [];
|
|
138
|
-
if (details.cyclePenalty > 0.1) advice.push('reduce circular imports (cyclePenalty high)');
|
|
139
|
-
if (details.deadCodeRatio > 0.1) advice.push('remove unreachable exports (deadCodeRatio high)');
|
|
140
|
-
if (details.fanSkew > 0.25) advice.push('break up high-fan-out modules (fanSkew high)');
|
|
141
|
-
if (details.godNodeConcentration > 0.1) advice.push('distribute hub dependencies (godNodeConcentration high)');
|
|
142
|
-
if (advice.length > 0) {
|
|
143
|
-
lines.push(' Recommendations: ' + advice.join('; '));
|
|
144
|
-
}
|
|
145
|
-
return lines.join('\n');
|
|
146
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import type { MonographDb } from '../storage/db.js';
|
|
2
|
-
|
|
3
|
-
export interface DuplicateExportLocation {
|
|
4
|
-
nodeId: string;
|
|
5
|
-
filePath: string | null;
|
|
6
|
-
startLine: number | null;
|
|
7
|
-
label: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface DuplicateExportGroup {
|
|
11
|
-
exportName: string;
|
|
12
|
-
locations: DuplicateExportLocation[];
|
|
13
|
-
count: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface DuplicateExportsResult {
|
|
17
|
-
groups: DuplicateExportGroup[];
|
|
18
|
-
totalDuplicates: number;
|
|
19
|
-
affectedFiles: number;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface ExportedRow {
|
|
23
|
-
id: string;
|
|
24
|
-
name: string;
|
|
25
|
-
file_path: string | null;
|
|
26
|
-
start_line: number | null;
|
|
27
|
-
label: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Generic names that are too common to be meaningful duplicates. */
|
|
31
|
-
const GENERIC_NAMES = new Set(['default', 'index', 'module']);
|
|
32
|
-
|
|
33
|
-
export function detectDuplicateExports(db: MonographDb): DuplicateExportsResult {
|
|
34
|
-
const rows = db.prepare(
|
|
35
|
-
`SELECT id, name, file_path, start_line, label
|
|
36
|
-
FROM nodes
|
|
37
|
-
WHERE is_exported = 1
|
|
38
|
-
AND label IN ('Function','Class','Method','Interface','Const','TypeAlias','Enum','Variable')`
|
|
39
|
-
).all() as ExportedRow[];
|
|
40
|
-
|
|
41
|
-
// Group by normalized name
|
|
42
|
-
const groups = new Map<string, DuplicateExportLocation[]>();
|
|
43
|
-
|
|
44
|
-
for (const row of rows) {
|
|
45
|
-
const normalized = row.name.toLowerCase().trim();
|
|
46
|
-
if (GENERIC_NAMES.has(normalized)) continue;
|
|
47
|
-
|
|
48
|
-
let list = groups.get(normalized);
|
|
49
|
-
if (!list) {
|
|
50
|
-
list = [];
|
|
51
|
-
groups.set(normalized, list);
|
|
52
|
-
}
|
|
53
|
-
list.push({ nodeId: row.id, filePath: row.file_path, startLine: row.start_line ?? null, label: row.label });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Filter to duplicates only (count > 1)
|
|
57
|
-
const duplicateGroups: DuplicateExportGroup[] = [];
|
|
58
|
-
const affectedFileSet = new Set<string>();
|
|
59
|
-
|
|
60
|
-
for (const [name, locations] of groups) {
|
|
61
|
-
if (locations.length <= 1) continue;
|
|
62
|
-
|
|
63
|
-
duplicateGroups.push({
|
|
64
|
-
exportName: name,
|
|
65
|
-
locations,
|
|
66
|
-
count: locations.length,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
for (const loc of locations) {
|
|
70
|
-
if (loc.filePath) affectedFileSet.add(loc.filePath);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Sort by count descending
|
|
75
|
-
duplicateGroups.sort((a, b) => b.count - a.count);
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
groups: duplicateGroups,
|
|
79
|
-
totalDuplicates: duplicateGroups.length,
|
|
80
|
-
affectedFiles: affectedFileSet.size,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** Format DuplicateExportsResult as structured text with file:line hints for LLM navigation. */
|
|
85
|
-
export function formatDuplicateExports(result: DuplicateExportsResult): string {
|
|
86
|
-
if (result.totalDuplicates === 0) {
|
|
87
|
-
return 'Duplicate exports: none detected.';
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const lines: string[] = [
|
|
91
|
-
`Duplicate exports: ${result.totalDuplicates} name(s) exported from multiple files (${result.affectedFiles} file(s) affected).`,
|
|
92
|
-
'',
|
|
93
|
-
];
|
|
94
|
-
|
|
95
|
-
for (const group of result.groups) {
|
|
96
|
-
lines.push(` ${group.exportName} (${group.count} locations):`);
|
|
97
|
-
for (const loc of group.locations) {
|
|
98
|
-
const ref = loc.filePath
|
|
99
|
-
? loc.startLine != null
|
|
100
|
-
? `${loc.filePath}:${loc.startLine}`
|
|
101
|
-
: loc.filePath
|
|
102
|
-
: '(unknown)';
|
|
103
|
-
lines.push(` ${loc.label} ${ref}`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
lines.push('');
|
|
108
|
-
lines.push('Fix: consolidate duplicate exports into a single canonical location or rename to avoid conflicts.');
|
|
109
|
-
return lines.join('\n').trimEnd();
|
|
110
|
-
}
|