@monoes/monograph 1.5.3 → 1.5.4
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/.monodesign/hook.cache.json +1 -1
- package/__tests__/integration/call-attribution.test.ts +116 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/coverage-summary.json +399 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +881 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/coverage/src/analysis/benchmark.ts.html +481 -0
- package/coverage/src/analysis/changed-files.ts.html +304 -0
- package/coverage/src/analysis/changed-workspaces.ts.html +367 -0
- package/coverage/src/analysis/churn-cache.ts.html +622 -0
- package/coverage/src/analysis/churn-trend.ts.html +256 -0
- package/coverage/src/analysis/churn.ts.html +874 -0
- package/coverage/src/analysis/cluster-quality.ts.html +511 -0
- package/coverage/src/analysis/combined.ts.html +208 -0
- package/coverage/src/analysis/corpus-health.ts.html +208 -0
- package/coverage/src/analysis/coverage-gaps.ts.html +823 -0
- package/coverage/src/analysis/dep-classification.ts.html +586 -0
- package/coverage/src/analysis/dependency-health.ts.html +523 -0
- package/coverage/src/analysis/duplicate-exports.ts.html +415 -0
- package/coverage/src/analysis/fallow-suppression.ts.html +379 -0
- package/coverage/src/analysis/feature-flags-config.ts.html +226 -0
- package/coverage/src/analysis/feature-flags.ts.html +754 -0
- package/coverage/src/analysis/file-classifier.ts.html +346 -0
- package/coverage/src/analysis/git-changed-files.ts.html +271 -0
- package/coverage/src/analysis/health-baseline.ts.html +325 -0
- package/coverage/src/analysis/index.html +641 -0
- package/coverage/src/analysis/issue-filters.ts.html +253 -0
- package/coverage/src/analysis/list.ts.html +307 -0
- package/coverage/src/analysis/node-similarity.ts.html +430 -0
- package/coverage/src/analysis/private-type-leaks.ts.html +442 -0
- package/coverage/src/analysis/progress.ts.html +214 -0
- package/coverage/src/analysis/project-state.ts.html +370 -0
- package/coverage/src/analysis/regression-config.ts.html +193 -0
- package/coverage/src/analysis/rule-overrides.ts.html +328 -0
- package/coverage/src/analysis/scripts.ts.html +370 -0
- package/coverage/src/analysis/shape-extractor.ts.html +691 -0
- package/coverage/src/analysis/since-duration.ts.html +211 -0
- package/coverage/src/analysis/suppression-context.ts.html +370 -0
- package/coverage/src/analysis/suppressions.ts.html +325 -0
- package/coverage/src/analysis/surprise-scorer.ts.html +307 -0
- package/coverage/src/analysis/targets.ts.html +796 -0
- package/coverage/src/analysis/unused-class-members.ts.html +322 -0
- package/coverage/src/analysis/workspace-filter.ts.html +352 -0
- package/coverage/src/analyze/boundary-analysis.ts.html +472 -0
- package/coverage/src/analyze/index.html +161 -0
- package/coverage/src/analyze/predicates/file.ts.html +343 -0
- package/coverage/src/analyze/predicates/import.ts.html +355 -0
- package/coverage/src/analyze/predicates/index.html +146 -0
- package/coverage/src/analyze/predicates/lifecycle.ts.html +250 -0
- package/coverage/src/analyze/unused-deps.ts.html +295 -0
- package/coverage/src/analyze/unused-exports.ts.html +520 -0
- package/coverage/src/analyze/unused-files.ts.html +223 -0
- package/coverage/src/api/index.html +131 -0
- package/coverage/src/api/production-override.ts.html +274 -0
- package/coverage/src/api/programmatic.ts.html +439 -0
- package/coverage/src/audit.ts.html +787 -0
- package/coverage/src/cache/augment-cache.ts.html +274 -0
- package/coverage/src/cache/extraction-cache.ts.html +508 -0
- package/coverage/src/cache/index.html +131 -0
- package/coverage/src/check/filtering.ts.html +319 -0
- package/coverage/src/check/index.html +161 -0
- package/coverage/src/check/index.ts.html +382 -0
- package/coverage/src/check/output.ts.html +322 -0
- package/coverage/src/check/rules.ts.html +268 -0
- package/coverage/src/ci-template.ts.html +337 -0
- package/coverage/src/claude-cli.ts.html +262 -0
- package/coverage/src/cli/ai-context.ts.html +664 -0
- package/coverage/src/cli/augment.ts.html +427 -0
- package/coverage/src/cli/check-update.ts.html +205 -0
- package/coverage/src/cli/doctor.ts.html +631 -0
- package/coverage/src/cli/eval-server.ts.html +463 -0
- package/coverage/src/cli/hooks-install.ts.html +691 -0
- package/coverage/src/cli/index.html +221 -0
- package/coverage/src/cli/setup.ts.html +676 -0
- package/coverage/src/cli/skill-gen.ts.html +1126 -0
- package/coverage/src/commands/flags.ts.html +301 -0
- package/coverage/src/commands/index.html +116 -0
- package/coverage/src/config/boundary-config.ts.html +634 -0
- package/coverage/src/config/cli-schema.ts.html +328 -0
- package/coverage/src/config/config-parsing.ts.html +391 -0
- package/coverage/src/config/duplicates-config.ts.html +271 -0
- package/coverage/src/config/external-plugin.ts.html +316 -0
- package/coverage/src/config/health-config.ts.html +211 -0
- package/coverage/src/config/ignore-exports-used-in-file.ts.html +223 -0
- package/coverage/src/config/index.html +341 -0
- package/coverage/src/config/migration-types.ts.html +304 -0
- package/coverage/src/config/output-format.ts.html +157 -0
- package/coverage/src/config/plugins/builtin.ts.html +1318 -0
- package/coverage/src/config/plugins/index.html +146 -0
- package/coverage/src/config/plugins/registry.ts.html +316 -0
- package/coverage/src/config/plugins/types.ts.html +127 -0
- package/coverage/src/config/resolution.ts.html +391 -0
- package/coverage/src/config/rules.ts.html +295 -0
- package/coverage/src/config/schema-gen.ts.html +430 -0
- package/coverage/src/config/types.ts.html +532 -0
- package/coverage/src/config/used-class-members.ts.html +244 -0
- package/coverage/src/config/validate.ts.html +409 -0
- package/coverage/src/config/workspace.ts.html +496 -0
- package/coverage/src/coverage/cloud-client.ts.html +418 -0
- package/coverage/src/coverage/index.html +146 -0
- package/coverage/src/coverage/upload-inventory.ts.html +337 -0
- package/coverage/src/coverage/upload-source-maps.ts.html +376 -0
- package/coverage/src/discover/entry-points.ts.html +238 -0
- package/coverage/src/discover/index.html +131 -0
- package/coverage/src/discover/infrastructure-entries.ts.html +610 -0
- package/coverage/src/duplicates/detect/concatenation.ts.html +196 -0
- package/coverage/src/duplicates/detect/extraction.ts.html +406 -0
- package/coverage/src/duplicates/detect/filtering.ts.html +421 -0
- package/coverage/src/duplicates/detect/index.html +206 -0
- package/coverage/src/duplicates/detect/lcp.ts.html +166 -0
- package/coverage/src/duplicates/detect/ranking.ts.html +133 -0
- package/coverage/src/duplicates/detect/statistics.ts.html +292 -0
- package/coverage/src/duplicates/detect/suffix-array.ts.html +349 -0
- package/coverage/src/duplicates/families.ts.html +370 -0
- package/coverage/src/duplicates/index.html +161 -0
- package/coverage/src/duplicates/normalize.ts.html +259 -0
- package/coverage/src/duplicates/shingle-filter.ts.html +196 -0
- package/coverage/src/duplicates/token-types.ts.html +271 -0
- package/coverage/src/duplicates/tokenize/index.html +116 -0
- package/coverage/src/duplicates/tokenize/index.ts.html +397 -0
- package/coverage/src/error/fallow-error.ts.html +367 -0
- package/coverage/src/error/index.html +116 -0
- package/coverage/src/error.ts.html +226 -0
- package/coverage/src/export/adjacency-matrix.ts.html +466 -0
- package/coverage/src/export/analysis-json.ts.html +346 -0
- package/coverage/src/export/badge.ts.html +400 -0
- package/coverage/src/export/canvas.ts.html +211 -0
- package/coverage/src/export/codeclimate.ts.html +688 -0
- package/coverage/src/export/compact-health.ts.html +442 -0
- package/coverage/src/export/compact.ts.html +334 -0
- package/coverage/src/export/csv.ts.html +184 -0
- package/coverage/src/export/cypher.ts.html +184 -0
- package/coverage/src/export/dot.ts.html +241 -0
- package/coverage/src/export/gexf.ts.html +262 -0
- package/coverage/src/export/graphml.ts.html +235 -0
- package/coverage/src/export/html.ts.html +1729 -0
- package/coverage/src/export/index.html +401 -0
- package/coverage/src/export/index.ts.html +112 -0
- package/coverage/src/export/json.ts.html +193 -0
- package/coverage/src/export/markdown.ts.html +955 -0
- package/coverage/src/export/mermaid.ts.html +385 -0
- package/coverage/src/export/obsidian.ts.html +217 -0
- package/coverage/src/export/sarif.ts.html +820 -0
- package/coverage/src/export/svg.ts.html +289 -0
- package/coverage/src/fix/deps.ts.html +295 -0
- package/coverage/src/fix/enum-members.ts.html +394 -0
- package/coverage/src/fix/export-surgery.ts.html +676 -0
- package/coverage/src/fix/exports.ts.html +364 -0
- package/coverage/src/fix/index.html +176 -0
- package/coverage/src/fix/orchestrator.ts.html +286 -0
- package/coverage/src/graph/analyzer.ts.html +292 -0
- package/coverage/src/graph/author-analytics.ts.html +736 -0
- package/coverage/src/graph/baseline.ts.html +1381 -0
- package/coverage/src/graph/clone-families.ts.html +481 -0
- package/coverage/src/graph/codeowners-extended.ts.html +427 -0
- package/coverage/src/graph/codeowners-gitlab.ts.html +535 -0
- package/coverage/src/graph/codeowners.ts.html +736 -0
- package/coverage/src/graph/complexity.ts.html +685 -0
- package/coverage/src/graph/cross-reference-findings.ts.html +340 -0
- package/coverage/src/graph/cross-reference.ts.html +502 -0
- package/coverage/src/graph/cycle-detection.ts.html +1018 -0
- package/coverage/src/graph/cycles.ts.html +751 -0
- package/coverage/src/graph/dead-code.ts.html +469 -0
- package/coverage/src/graph/dependency-closure.ts.html +463 -0
- package/coverage/src/graph/dfs.ts.html +439 -0
- package/coverage/src/graph/diff.ts.html +361 -0
- package/coverage/src/graph/duplication-stats.ts.html +322 -0
- package/coverage/src/graph/edge-filter.ts.html +436 -0
- package/coverage/src/graph/explain.ts.html +484 -0
- package/coverage/src/graph/external-style-usage.ts.html +328 -0
- package/coverage/src/graph/health-score.ts.html +622 -0
- package/coverage/src/graph/hotspots.ts.html +742 -0
- package/coverage/src/graph/import-chain.ts.html +529 -0
- package/coverage/src/graph/index.html +746 -0
- package/coverage/src/graph/loader.ts.html +217 -0
- package/coverage/src/graph/maintainability.ts.html +553 -0
- package/coverage/src/graph/merge.ts.html +607 -0
- package/coverage/src/graph/mirrored-dirs.ts.html +691 -0
- package/coverage/src/graph/narrowing.ts.html +361 -0
- package/coverage/src/graph/node-search.ts.html +688 -0
- package/coverage/src/graph/node-types.ts.html +286 -0
- package/coverage/src/graph/normalize-id.ts.html +499 -0
- package/coverage/src/graph/pagerank.ts.html +580 -0
- package/coverage/src/graph/prune.ts.html +370 -0
- package/coverage/src/graph/re-exports/index.html +116 -0
- package/coverage/src/graph/re-exports/propagate.ts.html +370 -0
- package/coverage/src/graph/reachability.ts.html +382 -0
- package/coverage/src/graph/regex-search.ts.html +781 -0
- package/coverage/src/graph/regression.ts.html +682 -0
- package/coverage/src/graph/resolve/discover-types.ts.html +220 -0
- package/coverage/src/graph/resolve/dynamic-imports.ts.html +391 -0
- package/coverage/src/graph/resolve/fallbacks.ts.html +322 -0
- package/coverage/src/graph/resolve/index.html +281 -0
- package/coverage/src/graph/resolve/index.ts.html +289 -0
- package/coverage/src/graph/resolve/path-info.ts.html +208 -0
- package/coverage/src/graph/resolve/re-exports.ts.html +127 -0
- package/coverage/src/graph/resolve/react-native.ts.html +166 -0
- package/coverage/src/graph/resolve/require-imports.ts.html +139 -0
- package/coverage/src/graph/resolve/specifier.ts.html +445 -0
- package/coverage/src/graph/resolve/static-imports.ts.html +127 -0
- package/coverage/src/graph/resolve/types.ts.html +409 -0
- package/coverage/src/graph/resolve/upgrades.ts.html +181 -0
- package/coverage/src/graph/ripple-impact.ts.html +478 -0
- package/coverage/src/graph/risk-profile.ts.html +622 -0
- package/coverage/src/graph/statistics.ts.html +580 -0
- package/coverage/src/graph/stats.ts.html +556 -0
- package/coverage/src/graph/subgraph.ts.html +571 -0
- package/coverage/src/graph/topo-sort.ts.html +598 -0
- package/coverage/src/graph/wcc.ts.html +646 -0
- package/coverage/src/groups/contract-bridge.ts.html +394 -0
- package/coverage/src/groups/contract-registry.ts.html +874 -0
- package/coverage/src/groups/group-config.ts.html +409 -0
- package/coverage/src/groups/group-search.ts.html +502 -0
- package/coverage/src/groups/group-sync.ts.html +331 -0
- package/coverage/src/groups/grpc-extractor.ts.html +277 -0
- package/coverage/src/groups/index.html +221 -0
- package/coverage/src/groups/service-boundary.ts.html +442 -0
- package/coverage/src/groups/topic-extractor.ts.html +355 -0
- package/coverage/src/health/analysis-counts-snapshot.ts.html +256 -0
- package/coverage/src/health/analysis-counts.ts.html +295 -0
- package/coverage/src/health/complexity-findings.ts.html +430 -0
- package/coverage/src/health/distribution-thresholds.ts.html +247 -0
- package/coverage/src/health/grouping.ts.html +499 -0
- package/coverage/src/health/health-grouping.ts.html +343 -0
- package/coverage/src/health/health-report-types.ts.html +580 -0
- package/coverage/src/health/health-report.ts.html +328 -0
- package/coverage/src/health/health-score.ts.html +280 -0
- package/coverage/src/health/hotspot-utils.ts.html +250 -0
- package/coverage/src/health/hotspots.ts.html +397 -0
- package/coverage/src/health/index.html +551 -0
- package/coverage/src/health/large-functions.ts.html +187 -0
- package/coverage/src/health/ownership-metrics.ts.html +268 -0
- package/coverage/src/health/ownership-risk.ts.html +379 -0
- package/coverage/src/health/ownership.ts.html +607 -0
- package/coverage/src/health/quality-gate.ts.html +256 -0
- package/coverage/src/health/risk-profile.ts.html +202 -0
- package/coverage/src/health/runtime-coverage-report.ts.html +388 -0
- package/coverage/src/health/runtime-coverage.ts.html +298 -0
- package/coverage/src/health/scores.ts.html +301 -0
- package/coverage/src/health/scoring-types.ts.html +229 -0
- package/coverage/src/health/target-thresholds.ts.html +361 -0
- package/coverage/src/health/target-types.ts.html +247 -0
- package/coverage/src/health/targets.ts.html +538 -0
- package/coverage/src/health/timings.ts.html +343 -0
- package/coverage/src/health/trend-types.ts.html +256 -0
- package/coverage/src/health/trends.ts.html +343 -0
- package/coverage/src/health/vital-signs-compute.ts.html +409 -0
- package/coverage/src/health/vital-signs-snapshot.ts.html +301 -0
- package/coverage/src/health/vital-signs.ts.html +388 -0
- package/coverage/src/index.html +191 -0
- package/coverage/src/index.ts.html +418 -0
- package/coverage/src/ingest/git-clone.ts.html +823 -0
- package/coverage/src/ingest/index.html +161 -0
- package/coverage/src/ingest/query-memory.ts.html +481 -0
- package/coverage/src/ingest/transcribe.ts.html +847 -0
- package/coverage/src/ingest/url-ingest.ts.html +346 -0
- package/coverage/src/init/agent-hooks.ts.html +343 -0
- package/coverage/src/init/git-hooks.ts.html +298 -0
- package/coverage/src/init/index.html +146 -0
- package/coverage/src/init/project-detection.ts.html +400 -0
- package/coverage/src/license/index.html +116 -0
- package/coverage/src/license/manager.ts.html +445 -0
- package/coverage/src/lsp/code-actions.ts.html +466 -0
- package/coverage/src/lsp/code-lens.ts.html +253 -0
- package/coverage/src/lsp/diagnostics-ext.ts.html +535 -0
- package/coverage/src/lsp/diagnostics-push.ts.html +394 -0
- package/coverage/src/lsp/diagnostics.ts.html +379 -0
- package/coverage/src/lsp/hover.ts.html +277 -0
- package/coverage/src/lsp/index.html +206 -0
- package/coverage/src/lsp/server.ts.html +847 -0
- package/coverage/src/mcp/index.html +146 -0
- package/coverage/src/mcp/params.ts.html +688 -0
- package/coverage/src/mcp/resources.ts.html +457 -0
- package/coverage/src/mcp/tool-builders.ts.html +694 -0
- package/coverage/src/mcp-resources/communities-resource.ts.html +301 -0
- package/coverage/src/mcp-resources/graph-resource.ts.html +127 -0
- package/coverage/src/mcp-resources/index.html +251 -0
- package/coverage/src/mcp-resources/index.ts.html +112 -0
- package/coverage/src/mcp-resources/named-cluster-resource.ts.html +190 -0
- package/coverage/src/mcp-resources/named-process-resource.ts.html +163 -0
- package/coverage/src/mcp-resources/processes-resource.ts.html +286 -0
- package/coverage/src/mcp-resources/repo-context-resource.ts.html +193 -0
- package/coverage/src/mcp-resources/repos-resource.ts.html +148 -0
- package/coverage/src/mcp-resources/schema-resource.ts.html +223 -0
- package/coverage/src/mcp-resources/wiki-resource.ts.html +154 -0
- package/coverage/src/mcp-tools/api-impact.ts.html +628 -0
- package/coverage/src/mcp-tools/context.ts.html +418 -0
- package/coverage/src/mcp-tools/cypher.ts.html +172 -0
- package/coverage/src/mcp-tools/detect-changes.ts.html +433 -0
- package/coverage/src/mcp-tools/explain.ts.html +280 -0
- package/coverage/src/mcp-tools/graph-query.ts.html +469 -0
- package/coverage/src/mcp-tools/group-list.ts.html +349 -0
- package/coverage/src/mcp-tools/group-query.ts.html +163 -0
- package/coverage/src/mcp-tools/group-sync.ts.html +181 -0
- package/coverage/src/mcp-tools/impact.ts.html +691 -0
- package/coverage/src/mcp-tools/index.html +431 -0
- package/coverage/src/mcp-tools/index.ts.html +148 -0
- package/coverage/src/mcp-tools/list-repos.ts.html +199 -0
- package/coverage/src/mcp-tools/neighbors.ts.html +325 -0
- package/coverage/src/mcp-tools/query.ts.html +343 -0
- package/coverage/src/mcp-tools/rename.ts.html +439 -0
- package/coverage/src/mcp-tools/route-map.ts.html +379 -0
- package/coverage/src/mcp-tools/serve.ts.html +208 -0
- package/coverage/src/mcp-tools/shape-check.ts.html +631 -0
- package/coverage/src/mcp-tools/staleness.ts.html +124 -0
- package/coverage/src/mcp-tools/tool-map.ts.html +283 -0
- package/coverage/src/mcp-tools/wiki-build.ts.html +196 -0
- package/coverage/src/mcp-tools/wiki.ts.html +169 -0
- package/coverage/src/migrate/index.html +161 -0
- package/coverage/src/migrate/jscpd.ts.html +319 -0
- package/coverage/src/migrate/jsonc-gen.ts.html +199 -0
- package/coverage/src/migrate/knip.ts.html +463 -0
- package/coverage/src/migrate/toml-gen.ts.html +229 -0
- package/coverage/src/parsers/c.ts.html +178 -0
- package/coverage/src/parsers/cpp.ts.html +172 -0
- package/coverage/src/parsers/csharp.ts.html +214 -0
- package/coverage/src/parsers/dart.ts.html +202 -0
- package/coverage/src/parsers/extractor.ts.html +691 -0
- package/coverage/src/parsers/go.ts.html +166 -0
- package/coverage/src/parsers/index.html +386 -0
- package/coverage/src/parsers/java.ts.html +166 -0
- package/coverage/src/parsers/kotlin.ts.html +193 -0
- package/coverage/src/parsers/language-config.ts.html +169 -0
- package/coverage/src/parsers/language-parsers.ts.html +445 -0
- package/coverage/src/parsers/loader.ts.html +532 -0
- package/coverage/src/parsers/named-bindings.ts.html +274 -0
- package/coverage/src/parsers/php.ts.html +196 -0
- package/coverage/src/parsers/python.ts.html +163 -0
- package/coverage/src/parsers/ruby.ts.html +202 -0
- package/coverage/src/parsers/rust.ts.html +160 -0
- package/coverage/src/parsers/swift.ts.html +169 -0
- package/coverage/src/parsers/typescript.ts.html +208 -0
- package/coverage/src/parsers/vue.ts.html +322 -0
- package/coverage/src/pipeline/cluster-only.ts.html +277 -0
- package/coverage/src/pipeline/effort.ts.html +235 -0
- package/coverage/src/pipeline/index.html +191 -0
- package/coverage/src/pipeline/orchestrator.ts.html +844 -0
- package/coverage/src/pipeline/phases/boundary.ts.html +538 -0
- package/coverage/src/pipeline/phases/bridge-adapters/electron-ipc.ts.html +358 -0
- package/coverage/src/pipeline/phases/bridge-adapters/index.html +176 -0
- package/coverage/src/pipeline/phases/bridge-adapters/registry.ts.html +127 -0
- package/coverage/src/pipeline/phases/bridge-adapters/tauri.ts.html +394 -0
- package/coverage/src/pipeline/phases/bridge-adapters/types.ts.html +178 -0
- package/coverage/src/pipeline/phases/bridge-adapters/wails.ts.html +184 -0
- package/coverage/src/pipeline/phases/bridge-resolver.ts.html +316 -0
- package/coverage/src/pipeline/phases/call-site-extractors.ts.html +592 -0
- package/coverage/src/pipeline/phases/communities.ts.html +634 -0
- package/coverage/src/pipeline/phases/contextual-proximity.ts.html +349 -0
- package/coverage/src/pipeline/phases/cross-file.ts.html +433 -0
- package/coverage/src/pipeline/phases/docs-parse.ts.html +1006 -0
- package/coverage/src/pipeline/phases/evidence.ts.html +112 -0
- package/coverage/src/pipeline/phases/field-access.ts.html +232 -0
- package/coverage/src/pipeline/phases/framework-detect.ts.html +412 -0
- package/coverage/src/pipeline/phases/god-nodes.ts.html +574 -0
- package/coverage/src/pipeline/phases/import-resolver.ts.html +427 -0
- package/coverage/src/pipeline/phases/index.html +626 -0
- package/coverage/src/pipeline/phases/leiden.ts.html +316 -0
- package/coverage/src/pipeline/phases/llm-extract.ts.html +577 -0
- package/coverage/src/pipeline/phases/markdown.ts.html +448 -0
- package/coverage/src/pipeline/phases/middleware-extractor.ts.html +466 -0
- package/coverage/src/pipeline/phases/module-resolution.ts.html +967 -0
- package/coverage/src/pipeline/phases/mro.ts.html +253 -0
- package/coverage/src/pipeline/phases/orm.ts.html +1594 -0
- package/coverage/src/pipeline/phases/parse.ts.html +751 -0
- package/coverage/src/pipeline/phases/pdf-parse.ts.html +484 -0
- package/coverage/src/pipeline/phases/processes.ts.html +832 -0
- package/coverage/src/pipeline/phases/re-export-propagation.ts.html +565 -0
- package/coverage/src/pipeline/phases/reachability.ts.html +553 -0
- package/coverage/src/pipeline/phases/routes.ts.html +1135 -0
- package/coverage/src/pipeline/phases/scan.ts.html +484 -0
- package/coverage/src/pipeline/phases/scope-resolution.ts.html +1147 -0
- package/coverage/src/pipeline/phases/structure.ts.html +289 -0
- package/coverage/src/pipeline/phases/suggest.ts.html +361 -0
- package/coverage/src/pipeline/phases/surprises.ts.html +334 -0
- package/coverage/src/pipeline/phases/tools.ts.html +625 -0
- package/coverage/src/pipeline/phases/variables-phase.ts.html +196 -0
- package/coverage/src/pipeline/phases/variables.ts.html +286 -0
- package/coverage/src/pipeline/phases/wildcard-phase.ts.html +235 -0
- package/coverage/src/pipeline/phases/wildcard-synthesis.ts.html +727 -0
- package/coverage/src/pipeline/progress.ts.html +259 -0
- package/coverage/src/pipeline/runner.ts.html +469 -0
- package/coverage/src/pipeline/types.ts.html +208 -0
- package/coverage/src/query/cypher-parser.ts.html +1435 -0
- package/coverage/src/query/index.html +116 -0
- package/coverage/src/registry/index.html +116 -0
- package/coverage/src/registry/repo-registry.ts.html +460 -0
- package/coverage/src/regression/baseline-deltas.ts.html +730 -0
- package/coverage/src/regression/baseline.ts.html +313 -0
- package/coverage/src/regression/counts.ts.html +346 -0
- package/coverage/src/regression/index.html +176 -0
- package/coverage/src/regression/outcome.ts.html +319 -0
- package/coverage/src/regression/tolerance.ts.html +190 -0
- package/coverage/src/report/attributed-duplication.ts.html +421 -0
- package/coverage/src/report/badge-svg.ts.html +385 -0
- package/coverage/src/report/cross-ref-human.ts.html +235 -0
- package/coverage/src/report/duplication-grouping.ts.html +307 -0
- package/coverage/src/report/grouping.ts.html +496 -0
- package/coverage/src/report/human-check.ts.html +958 -0
- package/coverage/src/report/human-dupes.ts.html +511 -0
- package/coverage/src/report/human-health.ts.html +670 -0
- package/coverage/src/report/human.ts.html +445 -0
- package/coverage/src/report/index.html +341 -0
- package/coverage/src/report/json-actions.ts.html +358 -0
- package/coverage/src/report/json-builders.ts.html +295 -0
- package/coverage/src/report/json-schema.ts.html +310 -0
- package/coverage/src/report/number-format.ts.html +358 -0
- package/coverage/src/report/output-grouped.ts.html +391 -0
- package/coverage/src/report/pipeline-perf.ts.html +253 -0
- package/coverage/src/report/trace-human.ts.html +466 -0
- package/coverage/src/reporting/graph-report.ts.html +1378 -0
- package/coverage/src/reporting/index.html +116 -0
- package/coverage/src/results/fallow-results.ts.html +541 -0
- package/coverage/src/results/index.html +131 -0
- package/coverage/src/results/types.ts.html +532 -0
- package/coverage/src/scope-resolution/evidence-weights.ts.html +208 -0
- package/coverage/src/scope-resolution/index.html +116 -0
- package/coverage/src/search/ast-chunker.ts.html +703 -0
- package/coverage/src/search/diacritic.ts.html +106 -0
- package/coverage/src/search/hybrid-query.ts.html +280 -0
- package/coverage/src/search/index.html +161 -0
- package/coverage/src/search/rrf.ts.html +238 -0
- package/coverage/src/security/index.html +131 -0
- package/coverage/src/security/safe-fetch.ts.html +424 -0
- package/coverage/src/security/sensitive-files.ts.html +157 -0
- package/coverage/src/skills/index.html +116 -0
- package/coverage/src/skills/platform-skills.ts.html +784 -0
- package/coverage/src/staleness/git-staleness.ts.html +283 -0
- package/coverage/src/staleness/index.html +116 -0
- package/coverage/src/storage/db.ts.html +415 -0
- package/coverage/src/storage/edge-store.ts.html +400 -0
- package/coverage/src/storage/file-cache.ts.html +319 -0
- package/coverage/src/storage/fts-store.ts.html +1240 -0
- package/coverage/src/storage/index.html +221 -0
- package/coverage/src/storage/node-store.ts.html +712 -0
- package/coverage/src/storage/schema.ts.html +598 -0
- package/coverage/src/storage/suppressions.ts.html +520 -0
- package/coverage/src/storage/unlinked-refs.ts.html +436 -0
- package/coverage/src/types.ts.html +676 -0
- package/coverage/src/validation/extraction-validator.ts.html +247 -0
- package/coverage/src/validation/index.html +116 -0
- package/coverage/src/watch/index.html +116 -0
- package/coverage/src/watch/watcher.ts.html +499 -0
- package/coverage/src/web/analyze-api.ts.html +523 -0
- package/coverage/src/web/api.ts.html +1837 -0
- package/coverage/src/web/async-jobs.ts.html +412 -0
- package/coverage/src/web/index.html +191 -0
- package/coverage/src/web/mcp-http.ts.html +766 -0
- package/coverage/src/web/react-ui.ts.html +319 -0
- package/coverage/src/web/server.ts.html +355 -0
- package/coverage/src/wiki/gist-publisher.ts.html +313 -0
- package/coverage/src/wiki/index.html +176 -0
- package/coverage/src/wiki/prompt-builder.ts.html +190 -0
- package/coverage/src/wiki/providers.ts.html +487 -0
- package/coverage/src/wiki/wiki-generator.ts.html +736 -0
- package/coverage/src/wiki/wiki-store.ts.html +232 -0
- package/dist/src/cli/eval-server.d.ts.map +1 -1
- package/dist/src/cli/eval-server.js +8 -1
- package/dist/src/cli/eval-server.js.map +1 -1
- package/dist/src/cli/skill-gen.js.map +1 -1
- package/dist/src/graph/regex-search.d.ts.map +1 -1
- package/dist/src/graph/regex-search.js +13 -13
- package/dist/src/graph/regex-search.js.map +1 -1
- package/dist/src/graph/statistics.d.ts +0 -4
- package/dist/src/graph/statistics.d.ts.map +1 -1
- package/dist/src/graph/statistics.js +0 -7
- package/dist/src/graph/statistics.js.map +1 -1
- package/dist/src/pipeline/phases/call-site-extractors.d.ts +8 -0
- package/dist/src/pipeline/phases/call-site-extractors.d.ts.map +1 -1
- package/dist/src/pipeline/phases/call-site-extractors.js +9 -9
- package/dist/src/pipeline/phases/call-site-extractors.js.map +1 -1
- package/dist/src/pipeline/phases/module-resolution.js +2 -2
- package/dist/src/pipeline/phases/module-resolution.js.map +1 -1
- package/dist/src/pipeline/phases/scope-resolution.d.ts.map +1 -1
- package/dist/src/pipeline/phases/scope-resolution.js +76 -1
- package/dist/src/pipeline/phases/scope-resolution.js.map +1 -1
- package/dist/src/registry/repo-registry.d.ts.map +1 -1
- package/dist/src/registry/repo-registry.js +1 -2
- package/dist/src/registry/repo-registry.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -3
- package/src/cli/eval-server.ts +8 -1
- package/src/cli/skill-gen.ts +16 -16
- package/src/graph/regex-search.ts +13 -14
- package/src/graph/statistics.ts +0 -8
- package/src/pipeline/phases/call-site-extractors.ts +17 -9
- package/src/pipeline/phases/module-resolution.ts +2 -2
- package/src/pipeline/phases/scope-resolution.ts +89 -1
- package/src/registry/repo-registry.ts +1 -2
- package/vitest.config.ts +7 -0
- package/src/analysis/cycles.ts +0 -268
- package/src/analysis/trace.ts +0 -300
- package/src/analysis/worker-pool.ts +0 -81
- package/src/graph/clone-detector.ts +0 -163
- package/src/graph/shingle-filter.ts +0 -149
- package/src/watch/watch-runner.ts +0 -64
package/src/analysis/trace.ts
DELETED
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
export type TraceReason = 'no_references' | 'only_re_exported' | 'self_import' | 'has_references';
|
|
2
|
-
|
|
3
|
-
export interface ReferenceLocation {
|
|
4
|
-
filePath: string;
|
|
5
|
-
line: number;
|
|
6
|
-
col: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface ReExportChain {
|
|
10
|
-
path: string;
|
|
11
|
-
exportName: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface ExportTrace {
|
|
15
|
-
file: string;
|
|
16
|
-
exportName: string;
|
|
17
|
-
isUsed: boolean;
|
|
18
|
-
directReferences: ReferenceLocation[];
|
|
19
|
-
reExportChains: ReExportChain[];
|
|
20
|
-
reason: TraceReason;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface FileTrace {
|
|
24
|
-
file: string;
|
|
25
|
-
exports: Array<{ name: string; isUsed: boolean; line: number }>;
|
|
26
|
-
importsFrom: string[];
|
|
27
|
-
importedBy: string[];
|
|
28
|
-
reExports: Array<{ name: string; fromFile: string }>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface DependencyTrace {
|
|
32
|
-
packageName: string;
|
|
33
|
-
directImporters: string[];
|
|
34
|
-
transitiveImporters: string[];
|
|
35
|
-
isUsed: boolean;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface CloneInstance {
|
|
39
|
-
filePath: string;
|
|
40
|
-
startLine: number;
|
|
41
|
-
endLine: number;
|
|
42
|
-
similarity: number;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface CloneTrace {
|
|
46
|
-
sourceFile: string;
|
|
47
|
-
sourceLine: number;
|
|
48
|
-
matchingInstances: CloneInstance[];
|
|
49
|
-
groupId?: number;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface GraphNode {
|
|
53
|
-
id: string;
|
|
54
|
-
filePath?: string;
|
|
55
|
-
name: string;
|
|
56
|
-
isExported: boolean;
|
|
57
|
-
startLine?: number;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
interface GraphEdge {
|
|
61
|
-
sourceId: string;
|
|
62
|
-
targetId: string;
|
|
63
|
-
relation: string;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
interface Graph {
|
|
67
|
-
nodes: GraphNode[];
|
|
68
|
-
edges: GraphEdge[];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** Build an O(1) id→node index. Pass to the trace functions when calling multiple times on the same graph. */
|
|
72
|
-
export function buildNodeIndex(graph: Graph): Map<string, GraphNode> {
|
|
73
|
-
const index = new Map<string, GraphNode>();
|
|
74
|
-
for (const n of graph.nodes) index.set(n.id, n);
|
|
75
|
-
return index;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function traceExport(
|
|
79
|
-
graph: Graph,
|
|
80
|
-
file: string,
|
|
81
|
-
exportName: string,
|
|
82
|
-
nodeIndex?: Map<string, GraphNode>,
|
|
83
|
-
): ExportTrace {
|
|
84
|
-
// Build index once if not supplied — O(N) amortised when caller reuses it
|
|
85
|
-
const idx = nodeIndex ?? buildNodeIndex(graph);
|
|
86
|
-
|
|
87
|
-
// Find nodes in the target file matching exportName
|
|
88
|
-
const targetIds = new Set<string>();
|
|
89
|
-
for (const n of graph.nodes) {
|
|
90
|
-
if (n.filePath === file && n.name === exportName) targetIds.add(n.id);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Find CALLS or IMPORTS edges pointing to these nodes from other files
|
|
94
|
-
const directReferences: ReferenceLocation[] = [];
|
|
95
|
-
const reExportChains: ReExportChain[] = [];
|
|
96
|
-
|
|
97
|
-
for (const edge of graph.edges) {
|
|
98
|
-
if (!targetIds.has(edge.targetId)) continue;
|
|
99
|
-
|
|
100
|
-
const sourceNode = idx.get(edge.sourceId);
|
|
101
|
-
if (!sourceNode) continue;
|
|
102
|
-
|
|
103
|
-
// Skip self-references (same file)
|
|
104
|
-
if (sourceNode.filePath === file) continue;
|
|
105
|
-
|
|
106
|
-
if (edge.relation === 'CALLS' || edge.relation === 'IMPORTS') {
|
|
107
|
-
directReferences.push({
|
|
108
|
-
filePath: sourceNode.filePath ?? sourceNode.id,
|
|
109
|
-
line: sourceNode.startLine ?? 0,
|
|
110
|
-
col: 0,
|
|
111
|
-
});
|
|
112
|
-
} else if (edge.relation === 'RE_EXPORTS') {
|
|
113
|
-
reExportChains.push({
|
|
114
|
-
path: sourceNode.filePath ?? sourceNode.id,
|
|
115
|
-
exportName: sourceNode.name,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Determine reason
|
|
121
|
-
let reason: TraceReason;
|
|
122
|
-
let isUsed: boolean;
|
|
123
|
-
|
|
124
|
-
if (directReferences.length > 0) {
|
|
125
|
-
reason = 'has_references';
|
|
126
|
-
isUsed = true;
|
|
127
|
-
} else if (reExportChains.length > 0) {
|
|
128
|
-
reason = 'only_re_exported';
|
|
129
|
-
isUsed = false;
|
|
130
|
-
} else {
|
|
131
|
-
reason = 'no_references';
|
|
132
|
-
isUsed = false;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
file,
|
|
137
|
-
exportName,
|
|
138
|
-
isUsed,
|
|
139
|
-
directReferences,
|
|
140
|
-
reExportChains,
|
|
141
|
-
reason,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export function traceFile(
|
|
146
|
-
graph: Graph,
|
|
147
|
-
file: string,
|
|
148
|
-
nodeIndex?: Map<string, GraphNode>,
|
|
149
|
-
): FileTrace {
|
|
150
|
-
// Build index once if not supplied
|
|
151
|
-
const idx = nodeIndex ?? buildNodeIndex(graph);
|
|
152
|
-
|
|
153
|
-
// Find all nodes in this file
|
|
154
|
-
const fileNodes = graph.nodes.filter((n) => n.filePath === file);
|
|
155
|
-
const fileNodeIds = new Set(fileNodes.map((n) => n.id));
|
|
156
|
-
|
|
157
|
-
// Pre-compute which target node ids have external references in one edge pass
|
|
158
|
-
// to avoid O(exported_nodes * edges) in the map below.
|
|
159
|
-
const externallyReferenced = new Set<string>();
|
|
160
|
-
const importsFromSet = new Set<string>();
|
|
161
|
-
const importedBySet = new Set<string>();
|
|
162
|
-
const reExports: Array<{ name: string; fromFile: string }> = [];
|
|
163
|
-
|
|
164
|
-
for (const edge of graph.edges) {
|
|
165
|
-
const srcInFile = fileNodeIds.has(edge.sourceId);
|
|
166
|
-
const tgtInFile = fileNodeIds.has(edge.targetId);
|
|
167
|
-
|
|
168
|
-
if (edge.relation === 'IMPORTS') {
|
|
169
|
-
if (srcInFile) {
|
|
170
|
-
const targetNode = idx.get(edge.targetId);
|
|
171
|
-
if (targetNode?.filePath && targetNode.filePath !== file) {
|
|
172
|
-
importsFromSet.add(targetNode.filePath);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
if (tgtInFile) {
|
|
176
|
-
const sourceNode = idx.get(edge.sourceId);
|
|
177
|
-
if (sourceNode?.filePath && sourceNode.filePath !== file) {
|
|
178
|
-
importedBySet.add(sourceNode.filePath);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
// External IMPORTS into a file node → that node is externally referenced
|
|
182
|
-
if (tgtInFile && !srcInFile) {
|
|
183
|
-
externallyReferenced.add(edge.targetId);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (edge.relation === 'CALLS' && tgtInFile && !srcInFile) {
|
|
188
|
-
externallyReferenced.add(edge.targetId);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (edge.relation === 'RE_EXPORTS' && srcInFile) {
|
|
192
|
-
const sourceNode = idx.get(edge.sourceId);
|
|
193
|
-
const targetNode = idx.get(edge.targetId);
|
|
194
|
-
if (sourceNode && targetNode?.filePath) {
|
|
195
|
-
reExports.push({ name: sourceNode.name, fromFile: targetNode.filePath });
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Build exports list using pre-computed set — O(exported_nodes) not O(exported_nodes * edges)
|
|
201
|
-
const exports = fileNodes
|
|
202
|
-
.filter((n) => n.isExported)
|
|
203
|
-
.map((n) => ({
|
|
204
|
-
name: n.name,
|
|
205
|
-
isUsed: externallyReferenced.has(n.id),
|
|
206
|
-
line: n.startLine ?? 0,
|
|
207
|
-
}));
|
|
208
|
-
|
|
209
|
-
return {
|
|
210
|
-
file,
|
|
211
|
-
exports,
|
|
212
|
-
importsFrom: Array.from(importsFromSet),
|
|
213
|
-
importedBy: Array.from(importedBySet),
|
|
214
|
-
reExports,
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export function traceDependency(
|
|
219
|
-
importEdges: Array<{ sourceFile: string; targetPackage: string }>,
|
|
220
|
-
packageName: string,
|
|
221
|
-
): DependencyTrace {
|
|
222
|
-
// Find direct importers
|
|
223
|
-
const directImporters = importEdges
|
|
224
|
-
.filter((e) => e.targetPackage === packageName)
|
|
225
|
-
.map((e) => e.sourceFile);
|
|
226
|
-
|
|
227
|
-
const directSet = new Set(directImporters);
|
|
228
|
-
|
|
229
|
-
// BFS to find transitive importers via reverse import graph
|
|
230
|
-
const reverseImportMap = new Map<string, Set<string>>();
|
|
231
|
-
for (const edge of importEdges) {
|
|
232
|
-
if (!reverseImportMap.has(edge.targetPackage)) {
|
|
233
|
-
reverseImportMap.set(edge.targetPackage, new Set());
|
|
234
|
-
}
|
|
235
|
-
reverseImportMap.get(edge.targetPackage)!.add(edge.sourceFile);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const transitiveSet = new Set<string>();
|
|
239
|
-
const queue = [...directImporters];
|
|
240
|
-
const visited = new Set(directImporters);
|
|
241
|
-
|
|
242
|
-
while (queue.length > 0) {
|
|
243
|
-
const current = queue.shift()!;
|
|
244
|
-
const upstream = reverseImportMap.get(current);
|
|
245
|
-
if (upstream) {
|
|
246
|
-
for (const file of upstream) {
|
|
247
|
-
if (!visited.has(file) && !directSet.has(file)) {
|
|
248
|
-
visited.add(file);
|
|
249
|
-
transitiveSet.add(file);
|
|
250
|
-
queue.push(file);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return {
|
|
257
|
-
packageName,
|
|
258
|
-
directImporters,
|
|
259
|
-
transitiveImporters: Array.from(transitiveSet),
|
|
260
|
-
isUsed: directImporters.length > 0 || transitiveSet.size > 0,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
export function traceClone(
|
|
265
|
-
cloneGroups: Array<{ id: number; instances: CloneInstance[] }>,
|
|
266
|
-
file: string,
|
|
267
|
-
line: number,
|
|
268
|
-
): CloneTrace {
|
|
269
|
-
// Find groups containing an instance at (file, line)
|
|
270
|
-
const matchingGroups = cloneGroups.filter((group) =>
|
|
271
|
-
group.instances.some(
|
|
272
|
-
(inst) =>
|
|
273
|
-
inst.filePath === file && inst.startLine <= line && inst.endLine >= line,
|
|
274
|
-
),
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
if (matchingGroups.length === 0) {
|
|
278
|
-
return {
|
|
279
|
-
sourceFile: file,
|
|
280
|
-
sourceLine: line,
|
|
281
|
-
matchingInstances: [],
|
|
282
|
-
groupId: undefined,
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Use the first matching group
|
|
287
|
-
const group = matchingGroups[0];
|
|
288
|
-
|
|
289
|
-
// Return all OTHER instances (not the source one)
|
|
290
|
-
const matchingInstances = group.instances.filter(
|
|
291
|
-
(inst) => !(inst.filePath === file && inst.startLine <= line && inst.endLine >= line),
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
return {
|
|
295
|
-
sourceFile: file,
|
|
296
|
-
sourceLine: line,
|
|
297
|
-
matchingInstances,
|
|
298
|
-
groupId: group.id,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { Worker } from 'node:worker_threads';
|
|
2
|
-
import { cpus } from 'node:os';
|
|
3
|
-
|
|
4
|
-
const DEFAULT_STACK_SIZE_MB = 16;
|
|
5
|
-
|
|
6
|
-
export interface WorkerPoolOptions {
|
|
7
|
-
threads?: number;
|
|
8
|
-
stackSizeMb?: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface QueuedTask {
|
|
12
|
-
script: string;
|
|
13
|
-
input: unknown;
|
|
14
|
-
resolve: (value: unknown) => void;
|
|
15
|
-
reject: (reason: unknown) => void;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
let _globalPool: WorkerPool | null = null;
|
|
19
|
-
|
|
20
|
-
export class WorkerPool {
|
|
21
|
-
readonly threads: number;
|
|
22
|
-
readonly stackSizeMb: number;
|
|
23
|
-
|
|
24
|
-
private _active = 0;
|
|
25
|
-
private readonly _queue: QueuedTask[] = [];
|
|
26
|
-
|
|
27
|
-
constructor(opts: WorkerPoolOptions = {}) {
|
|
28
|
-
this.threads = opts.threads ?? cpus().length;
|
|
29
|
-
this.stackSizeMb = opts.stackSizeMb ?? DEFAULT_STACK_SIZE_MB;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
run<T>(workerScript: string, input: unknown): Promise<T> {
|
|
33
|
-
return new Promise<T>((resolve, reject) => {
|
|
34
|
-
this._queue.push({ script: workerScript, input, resolve: resolve as (v: unknown) => void, reject });
|
|
35
|
-
this._drain();
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
private _drain(): void {
|
|
40
|
-
while (this._active < this.threads && this._queue.length > 0) {
|
|
41
|
-
const task = this._queue.shift()!;
|
|
42
|
-
this._active++;
|
|
43
|
-
const worker = new Worker(task.script, {
|
|
44
|
-
workerData: task.input,
|
|
45
|
-
resourceLimits: { stackSizeMb: this.stackSizeMb },
|
|
46
|
-
});
|
|
47
|
-
let settled = false;
|
|
48
|
-
const settle = (fn: () => void) => {
|
|
49
|
-
if (settled) return;
|
|
50
|
-
settled = true;
|
|
51
|
-
fn();
|
|
52
|
-
this._active--;
|
|
53
|
-
this._drain();
|
|
54
|
-
};
|
|
55
|
-
worker.on('message', (v: unknown) => {
|
|
56
|
-
settle(() => task.resolve(v));
|
|
57
|
-
});
|
|
58
|
-
worker.on('error', (err: unknown) => {
|
|
59
|
-
settle(() => task.reject(err));
|
|
60
|
-
});
|
|
61
|
-
worker.on('exit', (code: number) => {
|
|
62
|
-
if (code !== 0) {
|
|
63
|
-
settle(() => task.reject(new Error(`Worker exited with code ${code}`)));
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function configureGlobalPool(threads?: number, stackSizeMb?: number): WorkerPool {
|
|
71
|
-
if (!_globalPool) _globalPool = new WorkerPool({ threads, stackSizeMb });
|
|
72
|
-
return _globalPool;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function getGlobalPool(): WorkerPool {
|
|
76
|
-
return _globalPool ?? configureGlobalPool();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function resetGlobalPool(): void {
|
|
80
|
-
_globalPool = null;
|
|
81
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import type { MonographDb } from '../storage/db.js';
|
|
2
|
-
import { insertEdge } from '../storage/edge-store.js';
|
|
3
|
-
import { makeId } from '../types.js';
|
|
4
|
-
|
|
5
|
-
export interface ClonePair {
|
|
6
|
-
fileA: string;
|
|
7
|
-
fileB: string;
|
|
8
|
-
similarity: number; // 0-1
|
|
9
|
-
cloneType: 'exact' | 'renamed' | 'structural';
|
|
10
|
-
tokenCount: number; // shared token run length
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface CloneDetectionResult {
|
|
14
|
-
pairs: ClonePair[];
|
|
15
|
-
totalFiles: number;
|
|
16
|
-
cloneRatio: number; // fraction of files involved in at least one clone pair
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** Tokenize a file path into lowercase alphanumeric tokens. */
|
|
20
|
-
function tokenizePath(filePath: string): string[] {
|
|
21
|
-
return filePath
|
|
22
|
-
.toLowerCase()
|
|
23
|
-
.split(/[^a-z0-9]+/)
|
|
24
|
-
.filter(t => t.length > 0);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** Extract the base filename (without directory) from a path. */
|
|
28
|
-
function baseName(filePath: string): string {
|
|
29
|
-
return filePath.replace(/^.*[\\/]/, '');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Compute both Jaccard similarity and shared token count in a single pass.
|
|
34
|
-
* Avoids building the countA Map twice (previously done separately in
|
|
35
|
-
* jaccardSimilarity and sharedTokenCount).
|
|
36
|
-
*/
|
|
37
|
-
function computeSimilarityAndShared(a: string[], b: string[]): { similarity: number; shared: number } {
|
|
38
|
-
const countA = new Map<string, number>();
|
|
39
|
-
for (const t of a) countA.set(t, (countA.get(t) ?? 0) + 1);
|
|
40
|
-
|
|
41
|
-
let intersection = 0;
|
|
42
|
-
const seen = new Map<string, number>();
|
|
43
|
-
for (const t of b) {
|
|
44
|
-
const limit = countA.get(t) ?? 0;
|
|
45
|
-
const used = seen.get(t) ?? 0;
|
|
46
|
-
if (used < limit) {
|
|
47
|
-
intersection++;
|
|
48
|
-
seen.set(t, used + 1);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const union = a.length + b.length - intersection;
|
|
53
|
-
const similarity = union === 0 ? 1 : intersection / union;
|
|
54
|
-
return { similarity, shared: intersection };
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function detectClones(
|
|
58
|
-
db: MonographDb,
|
|
59
|
-
minSimilarity = 0.8,
|
|
60
|
-
minTokens = 2,
|
|
61
|
-
): CloneDetectionResult {
|
|
62
|
-
// Query all File nodes with file_path
|
|
63
|
-
const rows = db
|
|
64
|
-
.prepare(`SELECT id, file_path FROM nodes WHERE label = 'File' AND file_path IS NOT NULL`)
|
|
65
|
-
.all() as { id: string; file_path: string }[];
|
|
66
|
-
|
|
67
|
-
const totalFiles = rows.length;
|
|
68
|
-
const pairs: ClonePair[] = [];
|
|
69
|
-
const involvedFiles = new Set<string>();
|
|
70
|
-
|
|
71
|
-
// Pre-compute path tokens and name tokens for each file
|
|
72
|
-
const tokenMap = new Map<string, { pathTokens: string[]; nameTokens: string[] }>();
|
|
73
|
-
for (const row of rows) {
|
|
74
|
-
const pathTokens = tokenizePath(row.file_path);
|
|
75
|
-
const nameTokens = tokenizePath(baseName(row.file_path));
|
|
76
|
-
tokenMap.set(row.file_path, { pathTokens, nameTokens });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Compare all pairs
|
|
80
|
-
for (let i = 0; i < rows.length; i++) {
|
|
81
|
-
for (let j = i + 1; j < rows.length; j++) {
|
|
82
|
-
const pathA = rows[i].file_path;
|
|
83
|
-
const pathB = rows[j].file_path;
|
|
84
|
-
const entryA = tokenMap.get(pathA)!;
|
|
85
|
-
const entryB = tokenMap.get(pathB)!;
|
|
86
|
-
|
|
87
|
-
const { similarity: sim, shared } = computeSimilarityAndShared(entryA.pathTokens, entryB.pathTokens);
|
|
88
|
-
|
|
89
|
-
if (sim < minSimilarity || shared < minTokens) {
|
|
90
|
-
// Also check near-duplicate file names (same name, different dir)
|
|
91
|
-
const { similarity: nameSim, shared: nameShared } = computeSimilarityAndShared(entryA.nameTokens, entryB.nameTokens);
|
|
92
|
-
|
|
93
|
-
if (nameSim >= minSimilarity && nameShared >= Math.min(minTokens, entryA.nameTokens.length)) {
|
|
94
|
-
// Same-name files in different directories → structural similarity
|
|
95
|
-
const pair: ClonePair = {
|
|
96
|
-
fileA: pathA,
|
|
97
|
-
fileB: pathB,
|
|
98
|
-
similarity: nameSim,
|
|
99
|
-
cloneType: 'structural',
|
|
100
|
-
tokenCount: nameShared,
|
|
101
|
-
};
|
|
102
|
-
pairs.push(pair);
|
|
103
|
-
involvedFiles.add(pathA);
|
|
104
|
-
involvedFiles.add(pathB);
|
|
105
|
-
|
|
106
|
-
// Emit edge
|
|
107
|
-
const edgeId = makeId('structurally_similar', rows[i].id, rows[j].id);
|
|
108
|
-
try {
|
|
109
|
-
insertEdge(db, {
|
|
110
|
-
id: edgeId,
|
|
111
|
-
sourceId: rows[i].id,
|
|
112
|
-
targetId: rows[j].id,
|
|
113
|
-
relation: 'STRUCTURALLY_SIMILAR',
|
|
114
|
-
confidence: 'INFERRED',
|
|
115
|
-
confidenceScore: nameSim,
|
|
116
|
-
weight: nameSim,
|
|
117
|
-
});
|
|
118
|
-
} catch { /* ignore duplicate edge errors */ }
|
|
119
|
-
}
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Determine clone type
|
|
124
|
-
let cloneType: ClonePair['cloneType'];
|
|
125
|
-
if (sim >= 0.99) {
|
|
126
|
-
cloneType = 'exact';
|
|
127
|
-
} else if (baseName(pathA) === baseName(pathB)) {
|
|
128
|
-
cloneType = 'renamed';
|
|
129
|
-
} else {
|
|
130
|
-
cloneType = 'structural';
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const pair: ClonePair = {
|
|
134
|
-
fileA: pathA,
|
|
135
|
-
fileB: pathB,
|
|
136
|
-
similarity: sim,
|
|
137
|
-
cloneType,
|
|
138
|
-
tokenCount: shared,
|
|
139
|
-
};
|
|
140
|
-
pairs.push(pair);
|
|
141
|
-
involvedFiles.add(pathA);
|
|
142
|
-
involvedFiles.add(pathB);
|
|
143
|
-
|
|
144
|
-
// Emit STRUCTURALLY_SIMILAR edge into the edges table
|
|
145
|
-
const edgeId = makeId('structurally_similar', rows[i].id, rows[j].id);
|
|
146
|
-
try {
|
|
147
|
-
insertEdge(db, {
|
|
148
|
-
id: edgeId,
|
|
149
|
-
sourceId: rows[i].id,
|
|
150
|
-
targetId: rows[j].id,
|
|
151
|
-
relation: 'STRUCTURALLY_SIMILAR',
|
|
152
|
-
confidence: 'INFERRED',
|
|
153
|
-
confidenceScore: sim,
|
|
154
|
-
weight: sim,
|
|
155
|
-
});
|
|
156
|
-
} catch { /* ignore duplicate edge errors */ }
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const cloneRatio = totalFiles === 0 ? 0 : involvedFiles.size / totalFiles;
|
|
161
|
-
|
|
162
|
-
return { pairs, totalFiles, cloneRatio };
|
|
163
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
export interface ShingleFilter {
|
|
2
|
-
add(id: string, tokens: string[]): void;
|
|
3
|
-
candidates(tokens: string[], topK?: number): string[]; // fast pre-filter
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Generate k-shingles (k-grams) from a token array.
|
|
8
|
-
* Each shingle is the concatenation of k consecutive tokens joined by a space.
|
|
9
|
-
*/
|
|
10
|
-
function kShingles(tokens: string[], k: number): string[] {
|
|
11
|
-
if (tokens.length < k) return [tokens.join(' ')];
|
|
12
|
-
const shingles: string[] = [];
|
|
13
|
-
for (let i = 0; i <= tokens.length - k; i++) {
|
|
14
|
-
shingles.push(tokens.slice(i, i + k).join(' '));
|
|
15
|
-
}
|
|
16
|
-
return shingles;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Simple string hash that produces a non-negative 32-bit integer.
|
|
21
|
-
* Uses a djb2-style hash.
|
|
22
|
-
*/
|
|
23
|
-
function hashString(s: string): number {
|
|
24
|
-
let h = 5381;
|
|
25
|
-
for (let i = 0; i < s.length; i++) {
|
|
26
|
-
h = ((h << 5) + h) ^ s.charCodeAt(i);
|
|
27
|
-
h = h >>> 0; // keep unsigned 32-bit
|
|
28
|
-
}
|
|
29
|
-
return h;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const MINHASH_PRIME = BigInt(4294967311); // first prime > 2^32
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Compute a MinHash signature for a set of shingles using
|
|
36
|
-
* numHashes linear hash functions: h_i(x) = (a_i * x + b_i) % prime.
|
|
37
|
-
*
|
|
38
|
-
* @param seedsA Precomputed BigInt a-coefficients (length numHashes)
|
|
39
|
-
* @param seedsB Precomputed BigInt b-constants (length numHashes)
|
|
40
|
-
*/
|
|
41
|
-
function minHashSignature(
|
|
42
|
-
shingles: string[],
|
|
43
|
-
numHashes: number,
|
|
44
|
-
seedsA: BigInt64Array,
|
|
45
|
-
seedsB: BigInt64Array,
|
|
46
|
-
): Uint32Array {
|
|
47
|
-
const sig = new Uint32Array(numHashes).fill(0xffffffff);
|
|
48
|
-
|
|
49
|
-
for (const shingle of shingles) {
|
|
50
|
-
const x = BigInt(hashString(shingle));
|
|
51
|
-
for (let i = 0; i < numHashes; i++) {
|
|
52
|
-
// Precomputed seeds avoid recomputing the same (a, b) per shingle per call.
|
|
53
|
-
const hashVal = Number((seedsA[i]! * x + seedsB[i]!) % MINHASH_PRIME) >>> 0;
|
|
54
|
-
if (hashVal < sig[i]!) sig[i] = hashVal;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return sig;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function createShingleFilter(k = 5, numHashes = 128): ShingleFilter {
|
|
61
|
-
// Each entry: { sig: Uint32Array }
|
|
62
|
-
const index = new Map<string, Uint32Array>();
|
|
63
|
-
|
|
64
|
-
// LSH: split numHashes into bands of rows
|
|
65
|
-
// Standard LSH: numBands * numRows = numHashes, threshold ≈ (1/numBands)^(1/numRows)
|
|
66
|
-
// We target threshold ~0.5: solve (1/b)^(1/r) = 0.5 with b*r = numHashes
|
|
67
|
-
// A reasonable split is sqrt(numHashes) bands of sqrt(numHashes) rows each.
|
|
68
|
-
const numBands = Math.round(Math.sqrt(numHashes));
|
|
69
|
-
const numRows = Math.floor(numHashes / numBands);
|
|
70
|
-
|
|
71
|
-
// Precompute MinHash seeds once per filter instance to avoid recomputing
|
|
72
|
-
// (a, b) inside the hot inner loop of minHashSignature().
|
|
73
|
-
const seedsA = new BigInt64Array(numHashes);
|
|
74
|
-
const seedsB = new BigInt64Array(numHashes);
|
|
75
|
-
for (let i = 0; i < numHashes; i++) {
|
|
76
|
-
seedsA[i] = BigInt(((i * 2654435761 + 0x9e3779b9) >>> 0));
|
|
77
|
-
seedsB[i] = BigInt(((i * 2246822519 + 0x85ebca6b) >>> 0));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function getBandKey(band: number, sig: Uint32Array): string {
|
|
81
|
-
const parts: number[] = [];
|
|
82
|
-
for (let r = 0; r < numRows; r++) {
|
|
83
|
-
const idx = band * numRows + r;
|
|
84
|
-
if (idx < numHashes) parts.push(sig[idx]!);
|
|
85
|
-
}
|
|
86
|
-
return `b${band}:${parts.join(',')}`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Band bucket → list of candidate IDs
|
|
90
|
-
const bandBuckets = new Map<string, string[]>();
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
add(id: string, tokens: string[]): void {
|
|
94
|
-
const shingles = kShingles(tokens, k);
|
|
95
|
-
const sig = minHashSignature(shingles, numHashes, seedsA, seedsB);
|
|
96
|
-
index.set(id, sig);
|
|
97
|
-
|
|
98
|
-
// Insert into LSH band buckets
|
|
99
|
-
for (let band = 0; band < numBands; band++) {
|
|
100
|
-
const key = getBandKey(band, sig);
|
|
101
|
-
const bucket = bandBuckets.get(key);
|
|
102
|
-
if (bucket) {
|
|
103
|
-
bucket.push(id);
|
|
104
|
-
} else {
|
|
105
|
-
bandBuckets.set(key, [id]);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
|
|
110
|
-
candidates(tokens: string[], topK = 10): string[] {
|
|
111
|
-
const shingles = kShingles(tokens, k);
|
|
112
|
-
const querySig = minHashSignature(shingles, numHashes, seedsA, seedsB);
|
|
113
|
-
|
|
114
|
-
// Collect candidate IDs via LSH band matching.
|
|
115
|
-
// Use getBandKey() consistently — eliminates the duplicate inline computation.
|
|
116
|
-
const candidateScores = new Map<string, number>();
|
|
117
|
-
|
|
118
|
-
for (let band = 0; band < numBands; band++) {
|
|
119
|
-
const queryKey = getBandKey(band, querySig);
|
|
120
|
-
const bucket = bandBuckets.get(queryKey);
|
|
121
|
-
if (bucket) {
|
|
122
|
-
for (const id of bucket) {
|
|
123
|
-
candidateScores.set(id, (candidateScores.get(id) ?? 0) + 1);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (candidateScores.size === 0) return [];
|
|
129
|
-
|
|
130
|
-
// Compute Jaccard estimate from signature agreement for ranked results
|
|
131
|
-
const ranked = [...candidateScores.keys()].map(id => {
|
|
132
|
-
const sig = index.get(id)!;
|
|
133
|
-
let matches = 0;
|
|
134
|
-
for (let i = 0; i < numHashes; i++) {
|
|
135
|
-
if (sig[i] === querySig[i]) matches++;
|
|
136
|
-
}
|
|
137
|
-
const jaccardEst = matches / numHashes;
|
|
138
|
-
return { id, jaccardEst };
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// Filter by estimated Jaccard > 0.5 and return topK
|
|
142
|
-
return ranked
|
|
143
|
-
.filter(r => r.jaccardEst > 0.5)
|
|
144
|
-
.sort((a, b) => b.jaccardEst - a.jaccardEst)
|
|
145
|
-
.slice(0, topK)
|
|
146
|
-
.map(r => r.id);
|
|
147
|
-
},
|
|
148
|
-
};
|
|
149
|
-
}
|