@monoes/monograph 1.5.2 → 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/build-atomicity.test.ts +61 -0
- 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/orchestrator.js +22 -0
- package/dist/src/pipeline/orchestrator.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/orchestrator.ts +18 -0
- 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monograph",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Native TypeScript code intelligence engine for monomind",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc",
|
|
23
|
-
"test": "vitest run"
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:coverage": "vitest run --coverage"
|
|
24
25
|
},
|
|
25
26
|
"dependencies": {
|
|
26
27
|
"better-sqlite3": "^12.0.0",
|
|
@@ -56,4 +57,4 @@
|
|
|
56
57
|
"typescript": "^7.0.2",
|
|
57
58
|
"vitest": "^4.1.4"
|
|
58
59
|
}
|
|
59
|
-
}
|
|
60
|
+
}
|
package/src/cli/eval-server.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* createEvalServer('/path/to/repo', 4848)
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { createRequire } from 'node:module';
|
|
12
13
|
import type { Server } from 'http';
|
|
13
14
|
import type { Application } from 'express';
|
|
14
15
|
import { openDb, closeDb } from '../storage/db.js';
|
|
@@ -49,7 +50,13 @@ export function createEvalServer(repoPath: string, _port?: number): EvalServerHa
|
|
|
49
50
|
function getApp(): Application {
|
|
50
51
|
if (_app) return _app;
|
|
51
52
|
|
|
52
|
-
//
|
|
53
|
+
// createRequire, not a bare require(): this package is ESM
|
|
54
|
+
// ("type": "module"), where `require` is undefined at runtime — the
|
|
55
|
+
// eslint-disable that used to sit here silenced the lint but the call
|
|
56
|
+
// still threw "require is not defined" the moment getApp() ran.
|
|
57
|
+
// getApp() is synchronous, so `await import()` is not an option; this is
|
|
58
|
+
// the correct ESM escape hatch for a deliberately deferred load.
|
|
59
|
+
const require = createRequire(import.meta.url);
|
|
53
60
|
const express = require('express') as typeof import('express');
|
|
54
61
|
const app = express();
|
|
55
62
|
app.use(express.json());
|
package/src/cli/skill-gen.ts
CHANGED
|
@@ -60,29 +60,29 @@ export async function generateSkillFiles(
|
|
|
60
60
|
const db = openDb(dbPath);
|
|
61
61
|
|
|
62
62
|
try {
|
|
63
|
-
|
|
63
|
+
const communities = queryCommunities(db);
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
if (communities.length === 0) {
|
|
66
|
+
return { filesWritten: [], communityCount: 0 };
|
|
67
|
+
}
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
await fs.mkdir(skillsDir, { recursive: true });
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
const filesWritten: string[] = [];
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
for (const community of communities) {
|
|
74
|
+
const members = queryMembers(db, community.community_id);
|
|
75
|
+
const crossConnections = queryCrossConnections(db, community.community_id);
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
const content = renderSkillMarkdown(community, members, crossConnections, repoPath);
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
const kebab = toKebabName(community.label || `community-${community.community_id}`);
|
|
80
|
+
const filePath = path.join(skillsDir, `${kebab}.md`);
|
|
81
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
82
|
+
filesWritten.push(filePath);
|
|
83
|
+
}
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
return { filesWritten, communityCount: communities.length };
|
|
86
86
|
} finally {
|
|
87
87
|
closeDb(db);
|
|
88
88
|
}
|
|
@@ -48,20 +48,6 @@ export function regexSearchNodes(
|
|
|
48
48
|
const results: RegexNodeMatch[] = [];
|
|
49
49
|
|
|
50
50
|
for (const r of rows) {
|
|
51
|
-
const node: MonographNode = {
|
|
52
|
-
id: r.id,
|
|
53
|
-
label: r.label as MonographNode['label'],
|
|
54
|
-
name: r.name,
|
|
55
|
-
normLabel: r.norm_label,
|
|
56
|
-
filePath: r.file_path ?? undefined,
|
|
57
|
-
startLine: r.start_line ?? undefined,
|
|
58
|
-
endLine: r.end_line ?? undefined,
|
|
59
|
-
communityId: r.community_id ?? undefined,
|
|
60
|
-
isExported: r.is_exported === 1,
|
|
61
|
-
language: r.language ?? undefined,
|
|
62
|
-
properties: r.properties ? (JSON.parse(r.properties) as Record<string, unknown>) : undefined,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
51
|
for (const field of fields) {
|
|
66
52
|
const value =
|
|
67
53
|
field === 'name' ? r.name :
|
|
@@ -70,6 +56,19 @@ export function regexSearchNodes(
|
|
|
70
56
|
r.label;
|
|
71
57
|
|
|
72
58
|
if (value && re.test(value)) {
|
|
59
|
+
const node: MonographNode = {
|
|
60
|
+
id: r.id,
|
|
61
|
+
label: r.label as MonographNode['label'],
|
|
62
|
+
name: r.name,
|
|
63
|
+
normLabel: r.norm_label,
|
|
64
|
+
filePath: r.file_path ?? undefined,
|
|
65
|
+
startLine: r.start_line ?? undefined,
|
|
66
|
+
endLine: r.end_line ?? undefined,
|
|
67
|
+
communityId: r.community_id ?? undefined,
|
|
68
|
+
isExported: r.is_exported === 1,
|
|
69
|
+
language: r.language ?? undefined,
|
|
70
|
+
properties: r.properties ? (JSON.parse(r.properties) as Record<string, unknown>) : undefined,
|
|
71
|
+
};
|
|
73
72
|
results.push({ node, field });
|
|
74
73
|
break;
|
|
75
74
|
}
|
package/src/graph/statistics.ts
CHANGED
|
@@ -27,14 +27,6 @@ function getGraph(db: MonographDb): Graph {
|
|
|
27
27
|
return graph;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
/**
|
|
31
|
-
* Evict the cached graph for a given DB instance (call after writes).
|
|
32
|
-
*/
|
|
33
|
-
export function invalidateGraphCache(db: MonographDb): void {
|
|
34
|
-
const key = (db as unknown as { name: string }).name ?? '__default__';
|
|
35
|
-
_graphCache.delete(key);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
30
|
/**
|
|
39
31
|
* Graph density: ratio of actual edges to maximum possible directed edges.
|
|
40
32
|
* For a directed graph with n nodes: max = n * (n - 1).
|
|
@@ -132,6 +132,17 @@ async function buildAsyncLocked(
|
|
|
132
132
|
|
|
133
133
|
const db = openDb(dbPath);
|
|
134
134
|
|
|
135
|
+
// The whole build is one SQL transaction: a phase throwing (e.g. issue
|
|
136
|
+
// #40's FK violation) used to leave whatever earlier phases had already
|
|
137
|
+
// autocommitted sitting in the DB, silently corrupting the index into a
|
|
138
|
+
// stale partial state that a later build wouldn't repair (cache hits skip
|
|
139
|
+
// re-scanning the files that would restore the missing rows). BEGIN/COMMIT/
|
|
140
|
+
// ROLLBACK are issued directly via db.exec() rather than better-sqlite3's
|
|
141
|
+
// `.transaction()` helper, which requires a synchronous callback — the
|
|
142
|
+
// phases below are async. This is still safe: every phase writes through
|
|
143
|
+
// this same single connection, so SQLite serializes them regardless of how
|
|
144
|
+
// the JS event loop interleaves the awaits between phases.
|
|
145
|
+
db.exec('BEGIN');
|
|
135
146
|
try {
|
|
136
147
|
const graph = new Graph({ multi: true, type: 'directed' });
|
|
137
148
|
const ctx: PipelineContext = {
|
|
@@ -229,6 +240,13 @@ async function buildAsyncLocked(
|
|
|
229
240
|
}
|
|
230
241
|
}
|
|
231
242
|
db.prepare("INSERT OR REPLACE INTO index_meta VALUES ('indexed_at', ?)").run(new Date().toISOString());
|
|
243
|
+
db.exec('COMMIT');
|
|
244
|
+
} catch (err) {
|
|
245
|
+
// Best-effort: if the connection is already broken (e.g. the failure was
|
|
246
|
+
// itself a corrupt-database error), rolling back can throw too — the
|
|
247
|
+
// original error is what matters and must not be masked by this one.
|
|
248
|
+
try { db.exec('ROLLBACK'); } catch { /* ignore */ }
|
|
249
|
+
throw err;
|
|
232
250
|
} finally {
|
|
233
251
|
closeDb(db);
|
|
234
252
|
}
|
|
@@ -7,6 +7,14 @@ export interface CallSite {
|
|
|
7
7
|
form: 'method' | 'direct' | 'dynamic';
|
|
8
8
|
receiverName?: string;
|
|
9
9
|
methodName?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Byte offset of the match in the source, used by scope resolution to find
|
|
12
|
+
* the function enclosing this call. Without it every CALLS edge is
|
|
13
|
+
* attributed to the containing File, which makes a function look "used" by
|
|
14
|
+
* its own file just for being declared there — see the dead-code masking
|
|
15
|
+
* described in graph/dead-code.ts.
|
|
16
|
+
*/
|
|
17
|
+
offset?: number;
|
|
10
18
|
}
|
|
11
19
|
|
|
12
20
|
// ── Language keyword sets ────────────────────────────────────────────────────
|
|
@@ -71,13 +79,13 @@ function extractSimpleCallSites(
|
|
|
71
79
|
const methodPattern = /(\w+)\.(\w+)\s*\(/g;
|
|
72
80
|
let m: RegExpExecArray | null;
|
|
73
81
|
while ((m = methodPattern.exec(source)) !== null) {
|
|
74
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `${m[1]}.${m[2]}`, form: 'method', receiverName: m[1], methodName: m[2] });
|
|
82
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `${m[1]}.${m[2]}`, form: 'method', receiverName: m[1], methodName: m[2] });
|
|
75
83
|
}
|
|
76
84
|
const directPattern = new RegExp(`(?<![.[\\w])(${directCharClass})\\s*\\(`, 'g');
|
|
77
85
|
while ((m = directPattern.exec(source)) !== null) {
|
|
78
86
|
const name = m[1]!;
|
|
79
87
|
if (keywords.has(name)) continue;
|
|
80
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: name, form: 'direct' });
|
|
88
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: name, form: 'direct' });
|
|
81
89
|
}
|
|
82
90
|
return sites;
|
|
83
91
|
}
|
|
@@ -112,44 +120,44 @@ export function extractCallSites(
|
|
|
112
120
|
const methodPattern = /(\w+)\.(\w+)\s*(?:<[^>]*>\s*)?\(/g;
|
|
113
121
|
let m: RegExpExecArray | null;
|
|
114
122
|
while ((m = methodPattern.exec(source)) !== null) {
|
|
115
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `${m[1]}.${m[2]}`, form: 'method', receiverName: m[1], methodName: m[2] });
|
|
123
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `${m[1]}.${m[2]}`, form: 'method', receiverName: m[1], methodName: m[2] });
|
|
116
124
|
}
|
|
117
125
|
|
|
118
126
|
const chainedPattern = /[)\]]\s*\.(\w+)\s*(?:<[^>]*>\s*)?\(/g;
|
|
119
127
|
while ((m = chainedPattern.exec(source)) !== null) {
|
|
120
128
|
const name = m[1];
|
|
121
129
|
if (JS_KEYWORDS.has(name)) continue;
|
|
122
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `?.${name}`, form: 'method', methodName: name });
|
|
130
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `?.${name}`, form: 'method', methodName: name });
|
|
123
131
|
}
|
|
124
132
|
|
|
125
133
|
const directPattern = /(?<![.[\w])([A-Za-z_$][\w$]*)\s*(?:<[^>]*>\s*)?\(/g;
|
|
126
134
|
while ((m = directPattern.exec(source)) !== null) {
|
|
127
135
|
const name = m[1];
|
|
128
136
|
if (JS_KEYWORDS.has(name)) continue;
|
|
129
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: name, form: 'direct', methodName: name });
|
|
137
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: name, form: 'direct', methodName: name });
|
|
130
138
|
}
|
|
131
139
|
|
|
132
140
|
const newPattern = /\bnew\s+([A-Z][\w$]*)\s*(?:<[^>]*>\s*)?\(/g;
|
|
133
141
|
while ((m = newPattern.exec(source)) !== null) {
|
|
134
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `new ${m[1]}`, form: 'direct', methodName: m[1] });
|
|
142
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `new ${m[1]}`, form: 'direct', methodName: m[1] });
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
const dynamicPattern = /\w+\s*\[[\w'"` ]+\]\s*\(/g;
|
|
138
146
|
while ((m = dynamicPattern.exec(source)) !== null) {
|
|
139
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: m[0], form: 'dynamic' });
|
|
147
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: m[0], form: 'dynamic' });
|
|
140
148
|
}
|
|
141
149
|
} else if (PY_EXTS.has(ext)) {
|
|
142
150
|
const methodPattern = /(\w+)\.(\w+)\s*\(/g;
|
|
143
151
|
let m: RegExpExecArray | null;
|
|
144
152
|
while ((m = methodPattern.exec(source)) !== null) {
|
|
145
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `${m[1]}.${m[2]}`, form: 'method', receiverName: m[1], methodName: m[2] });
|
|
153
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: `${m[1]}.${m[2]}`, form: 'method', receiverName: m[1], methodName: m[2] });
|
|
146
154
|
}
|
|
147
155
|
|
|
148
156
|
const directPattern = /(?<![.[\w])([A-Za-z_][\w]*)\s*\(/g;
|
|
149
157
|
while ((m = directPattern.exec(source)) !== null) {
|
|
150
158
|
const name = m[1];
|
|
151
159
|
if (PY_KEYWORDS.has(name)) continue;
|
|
152
|
-
sites.push({ callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: name, form: 'direct', methodName: name });
|
|
160
|
+
sites.push({ offset: m.index, callerFileNodeId: fileNodeId, callerFilePath: filePath, calleeRaw: name, form: 'direct', methodName: name });
|
|
153
161
|
}
|
|
154
162
|
}
|
|
155
163
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// ── Module resolution for import specifiers ──────────────────────────────────
|
|
2
2
|
|
|
3
|
-
import { readFileSync, existsSync } from 'fs';
|
|
3
|
+
import { readFileSync, existsSync, readdirSync } from 'fs';
|
|
4
4
|
import { join, extname, dirname, resolve as resolvePath } from 'path';
|
|
5
5
|
import type { MonographNode } from '../../types.js';
|
|
6
6
|
import { TS_JS_EXTS, CJS_MJS_EXTS } from './call-site-extractors.js';
|
|
@@ -40,7 +40,7 @@ export function buildWorkspacePackageMap(repoPath: string): Map<string, string>
|
|
|
40
40
|
const scanDirs = (base: string, depth: number) => {
|
|
41
41
|
if (depth > 2) return;
|
|
42
42
|
let entries: string[];
|
|
43
|
-
try { entries =
|
|
43
|
+
try { entries = readdirSync(base); } catch { return; }
|
|
44
44
|
for (const e of entries) {
|
|
45
45
|
const full = join(base, e);
|
|
46
46
|
const pkgJson = join(full, 'package.json');
|
|
@@ -56,6 +56,86 @@ function buildFunctionIndex(ctx: PipelineContext): {
|
|
|
56
56
|
return { byFilePath, nameCounts };
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/** A callable node with a known line range, used to attribute a call to its caller. */
|
|
60
|
+
interface EnclosingSymbol {
|
|
61
|
+
id: string;
|
|
62
|
+
startLine: number;
|
|
63
|
+
endLine: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Line ranges of every callable, grouped by file, innermost-first.
|
|
68
|
+
*
|
|
69
|
+
* Call edges are attributed to the enclosing function rather than the file.
|
|
70
|
+
* Attributing them to the file makes a function appear "used" by its own file
|
|
71
|
+
* purely because it is declared there, which silently disabled dead-export
|
|
72
|
+
* detection: `detectDeadCodeNodes` rejects any candidate with an inbound CALLS
|
|
73
|
+
* edge, and that self-edge always existed.
|
|
74
|
+
*/
|
|
75
|
+
function buildEnclosingIndex(ctx: PipelineContext): Map<string, EnclosingSymbol[]> {
|
|
76
|
+
const byFile = new Map<string, EnclosingSymbol[]>();
|
|
77
|
+
if (!ctx.db) return byFile;
|
|
78
|
+
|
|
79
|
+
const rows = ctx.db
|
|
80
|
+
.prepare(
|
|
81
|
+
`SELECT id, file_path, start_line, end_line FROM nodes
|
|
82
|
+
WHERE label IN ('Function', 'Method', 'Constructor')
|
|
83
|
+
AND file_path IS NOT NULL AND start_line IS NOT NULL AND end_line IS NOT NULL`
|
|
84
|
+
)
|
|
85
|
+
.all() as { id: string; file_path: string; start_line: number; end_line: number }[];
|
|
86
|
+
|
|
87
|
+
for (const row of rows) {
|
|
88
|
+
let list = byFile.get(row.file_path);
|
|
89
|
+
if (!list) { list = []; byFile.set(row.file_path, list); }
|
|
90
|
+
list.push({ id: row.id, startLine: row.start_line, endLine: row.end_line });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Narrowest range first, so the first containing match is the innermost
|
|
94
|
+
// scope — a call inside a closure belongs to the closure, not the function
|
|
95
|
+
// that happens to wrap it.
|
|
96
|
+
for (const list of byFile.values()) {
|
|
97
|
+
list.sort((a, b) => (a.endLine - a.startLine) - (b.endLine - b.startLine));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return byFile;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Line-start offsets, for turning a match offset into a 1-based line number. */
|
|
104
|
+
function buildLineOffsets(source: string): number[] {
|
|
105
|
+
const offsets = [0];
|
|
106
|
+
for (let i = 0; i < source.length; i++) {
|
|
107
|
+
if (source.charCodeAt(i) === 10) offsets.push(i + 1);
|
|
108
|
+
}
|
|
109
|
+
return offsets;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function lineAtOffset(lineOffsets: number[], offset: number): number {
|
|
113
|
+
let lo = 0, hi = lineOffsets.length - 1;
|
|
114
|
+
while (lo < hi) {
|
|
115
|
+
const mid = (lo + hi + 1) >> 1;
|
|
116
|
+
if (lineOffsets[mid]! <= offset) lo = mid; else hi = mid - 1;
|
|
117
|
+
}
|
|
118
|
+
return lo + 1;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* The innermost callable containing `offset`, or null when the call sits at
|
|
123
|
+
* module top level — which is genuinely file-scoped, so the file node stays
|
|
124
|
+
* the correct source for those.
|
|
125
|
+
*/
|
|
126
|
+
function findEnclosingSymbolId(
|
|
127
|
+
enclosing: EnclosingSymbol[] | undefined,
|
|
128
|
+
lineOffsets: number[],
|
|
129
|
+
offset: number | undefined,
|
|
130
|
+
): string | null {
|
|
131
|
+
if (!enclosing || enclosing.length === 0 || offset === undefined) return null;
|
|
132
|
+
const line = lineAtOffset(lineOffsets, offset);
|
|
133
|
+
for (const sym of enclosing) {
|
|
134
|
+
if (line >= sym.startLine && line <= sym.endLine) return sym.id;
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
59
139
|
// ── Target resolution ────────────────────────────────────────────────────────
|
|
60
140
|
|
|
61
141
|
function pickBestId(ids: string[], site: CallSite): string | null {
|
|
@@ -226,6 +306,7 @@ export const scopeResolutionPhase: PipelinePhase<ScopeResolutionOutput> = {
|
|
|
226
306
|
|
|
227
307
|
const allImportMaps = buildAllImportMapsFromSource(ctx.repoPath, fileNodesByPath, fileContents);
|
|
228
308
|
const { byFilePath: fnIndex, nameCounts } = buildFunctionIndex(ctx);
|
|
309
|
+
const enclosingIndex = buildEnclosingIndex(ctx);
|
|
229
310
|
|
|
230
311
|
const edgeStmts = ctx.db ? prepareEdgeStmts(ctx.db) : null;
|
|
231
312
|
const resolveAllCalls = ctx.db?.transaction(() => {
|
|
@@ -243,6 +324,8 @@ export const scopeResolutionPhase: PipelinePhase<ScopeResolutionOutput> = {
|
|
|
243
324
|
}
|
|
244
325
|
|
|
245
326
|
const callSites = extractCallSites(source, filePath, fileNode.id, ext);
|
|
327
|
+
const lineOffsets = buildLineOffsets(source);
|
|
328
|
+
const enclosing = enclosingIndex.get(filePath);
|
|
246
329
|
const importMap = getImportMap(allImportMaps, fileNode.id);
|
|
247
330
|
const ctorMap = (TS_JS_EXTS.has(ext) || CJS_MJS_EXTS.has(ext)) ? extractConstructorAssignments(source) : undefined;
|
|
248
331
|
const importedFiles = [...new Set(importMap.values())];
|
|
@@ -260,7 +343,12 @@ export const scopeResolutionPhase: PipelinePhase<ScopeResolutionOutput> = {
|
|
|
260
343
|
ambiguous++;
|
|
261
344
|
}
|
|
262
345
|
|
|
263
|
-
|
|
346
|
+
// Attribute the call to the function it sits in; fall back to the
|
|
347
|
+
// file node for genuine module-top-level calls.
|
|
348
|
+
const sourceId =
|
|
349
|
+
findEnclosingSymbolId(enclosing, lineOffsets, site.offset) ?? site.callerFileNodeId;
|
|
350
|
+
|
|
351
|
+
const result = edgeStmts ? emitEdge(edgeStmts, sourceId, resolved.targetId) : 'skipped';
|
|
264
352
|
if (result === 'inserted' || result === 'upgraded') {
|
|
265
353
|
resolvedEdges++;
|
|
266
354
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Persists at ~/.monograph/registry.json and tracks all repos indexed by monograph.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { mkdirSync, readFileSync, writeFileSync, existsSync } from 'fs';
|
|
7
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync, renameSync } from 'fs';
|
|
8
8
|
import { join, basename, dirname } from 'path';
|
|
9
9
|
import { homedir } from 'os';
|
|
10
10
|
|
|
@@ -67,7 +67,6 @@ export function saveRegistry(registry: RepoRegistry): void {
|
|
|
67
67
|
const tmpPath = registryPath + '.tmp';
|
|
68
68
|
writeFileSync(tmpPath, JSON.stringify(registry, null, 2), 'utf8');
|
|
69
69
|
// Rename is atomic on POSIX systems
|
|
70
|
-
const { renameSync } = require('fs') as typeof import('fs');
|
|
71
70
|
renameSync(tmpPath, registryPath);
|
|
72
71
|
}
|
|
73
72
|
|
package/vitest.config.ts
CHANGED
|
@@ -6,8 +6,15 @@ export default defineConfig({
|
|
|
6
6
|
include: ['__tests__/**/*.test.ts', 'src/__tests__/**/*.test.ts'],
|
|
7
7
|
exclude: ['node_modules', 'dist', '**/._*'],
|
|
8
8
|
globals: true,
|
|
9
|
+
// Off by default to keep the edit/test loop fast; run
|
|
10
|
+
// `npm run test:coverage` (or pass --coverage) to measure.
|
|
9
11
|
coverage: {
|
|
10
12
|
enabled: false,
|
|
13
|
+
provider: 'v8',
|
|
14
|
+
reporter: ['text-summary', 'json-summary', 'html'],
|
|
15
|
+
reportsDirectory: './coverage',
|
|
16
|
+
include: ['src/**/*.ts'],
|
|
17
|
+
exclude: ['src/**/*.test.ts', 'src/__tests__/**', 'src/**/*.d.ts'],
|
|
11
18
|
},
|
|
12
19
|
},
|
|
13
20
|
});
|