@opencodehub/ingestion 0.1.0
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/LICENSE +202 -0
- package/README.md +69 -0
- package/dist/extract/index.d.ts +8 -0
- package/dist/extract/index.d.ts.map +1 -0
- package/dist/extract/index.js +6 -0
- package/dist/extract/index.js.map +1 -0
- package/dist/extract/orm-detector.d.ts +19 -0
- package/dist/extract/orm-detector.d.ts.map +1 -0
- package/dist/extract/orm-detector.js +209 -0
- package/dist/extract/orm-detector.js.map +1 -0
- package/dist/extract/property-access.d.ts +76 -0
- package/dist/extract/property-access.d.ts.map +1 -0
- package/dist/extract/property-access.js +260 -0
- package/dist/extract/property-access.js.map +1 -0
- package/dist/extract/receiver-resolver.d.ts +86 -0
- package/dist/extract/receiver-resolver.d.ts.map +1 -0
- package/dist/extract/receiver-resolver.js +77 -0
- package/dist/extract/receiver-resolver.js.map +1 -0
- package/dist/extract/route-detector-java.d.ts +29 -0
- package/dist/extract/route-detector-java.d.ts.map +1 -0
- package/dist/extract/route-detector-java.js +190 -0
- package/dist/extract/route-detector-java.js.map +1 -0
- package/dist/extract/route-detector-nestjs.d.ts +30 -0
- package/dist/extract/route-detector-nestjs.d.ts.map +1 -0
- package/dist/extract/route-detector-nestjs.js +134 -0
- package/dist/extract/route-detector-nestjs.js.map +1 -0
- package/dist/extract/route-detector-python.d.ts +28 -0
- package/dist/extract/route-detector-python.d.ts.map +1 -0
- package/dist/extract/route-detector-python.js +100 -0
- package/dist/extract/route-detector-python.js.map +1 -0
- package/dist/extract/route-detector-rails.d.ts +28 -0
- package/dist/extract/route-detector-rails.d.ts.map +1 -0
- package/dist/extract/route-detector-rails.js +162 -0
- package/dist/extract/route-detector-rails.js.map +1 -0
- package/dist/extract/route-detector.d.ts +45 -0
- package/dist/extract/route-detector.d.ts.map +1 -0
- package/dist/extract/route-detector.js +467 -0
- package/dist/extract/route-detector.js.map +1 -0
- package/dist/extract/tool-detector.d.ts +26 -0
- package/dist/extract/tool-detector.d.ts.map +1 -0
- package/dist/extract/tool-detector.js +364 -0
- package/dist/extract/tool-detector.js.map +1 -0
- package/dist/extract/types.d.ts +89 -0
- package/dist/extract/types.d.ts.map +1 -0
- package/dist/extract/types.js +11 -0
- package/dist/extract/types.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/parse/cobol-regex.d.ts +85 -0
- package/dist/parse/cobol-regex.d.ts.map +1 -0
- package/dist/parse/cobol-regex.js +355 -0
- package/dist/parse/cobol-regex.js.map +1 -0
- package/dist/parse/grammar-registry.d.ts +115 -0
- package/dist/parse/grammar-registry.d.ts.map +1 -0
- package/dist/parse/grammar-registry.js +278 -0
- package/dist/parse/grammar-registry.js.map +1 -0
- package/dist/parse/index.d.ts +14 -0
- package/dist/parse/index.d.ts.map +1 -0
- package/dist/parse/index.js +10 -0
- package/dist/parse/index.js.map +1 -0
- package/dist/parse/language-detector.d.ts +17 -0
- package/dist/parse/language-detector.d.ts.map +1 -0
- package/dist/parse/language-detector.js +104 -0
- package/dist/parse/language-detector.js.map +1 -0
- package/dist/parse/parse-worker.d.ts +24 -0
- package/dist/parse/parse-worker.d.ts.map +1 -0
- package/dist/parse/parse-worker.js +230 -0
- package/dist/parse/parse-worker.js.map +1 -0
- package/dist/parse/types.d.ts +49 -0
- package/dist/parse/types.d.ts.map +1 -0
- package/dist/parse/types.js +11 -0
- package/dist/parse/types.js.map +1 -0
- package/dist/parse/unified-queries.d.ts +37 -0
- package/dist/parse/unified-queries.d.ts.map +1 -0
- package/dist/parse/unified-queries.js +623 -0
- package/dist/parse/unified-queries.js.map +1 -0
- package/dist/parse/wasm-fallback.d.ts +88 -0
- package/dist/parse/wasm-fallback.d.ts.map +1 -0
- package/dist/parse/wasm-fallback.js +258 -0
- package/dist/parse/wasm-fallback.js.map +1 -0
- package/dist/parse/worker-pool.d.ts +48 -0
- package/dist/parse/worker-pool.d.ts.map +1 -0
- package/dist/parse/worker-pool.js +97 -0
- package/dist/parse/worker-pool.js.map +1 -0
- package/dist/pipeline/dep-parsers/go.d.ts +25 -0
- package/dist/pipeline/dep-parsers/go.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/go.js +146 -0
- package/dist/pipeline/dep-parsers/go.js.map +1 -0
- package/dist/pipeline/dep-parsers/index.d.ts +17 -0
- package/dist/pipeline/dep-parsers/index.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/index.js +16 -0
- package/dist/pipeline/dep-parsers/index.js.map +1 -0
- package/dist/pipeline/dep-parsers/maven.d.ts +24 -0
- package/dist/pipeline/dep-parsers/maven.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/maven.js +131 -0
- package/dist/pipeline/dep-parsers/maven.js.map +1 -0
- package/dist/pipeline/dep-parsers/npm.d.ts +30 -0
- package/dist/pipeline/dep-parsers/npm.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/npm.js +309 -0
- package/dist/pipeline/dep-parsers/npm.js.map +1 -0
- package/dist/pipeline/dep-parsers/nuget.d.ts +24 -0
- package/dist/pipeline/dep-parsers/nuget.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/nuget.js +178 -0
- package/dist/pipeline/dep-parsers/nuget.js.map +1 -0
- package/dist/pipeline/dep-parsers/python.d.ts +21 -0
- package/dist/pipeline/dep-parsers/python.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/python.js +369 -0
- package/dist/pipeline/dep-parsers/python.js.map +1 -0
- package/dist/pipeline/dep-parsers/rust.d.ts +18 -0
- package/dist/pipeline/dep-parsers/rust.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/rust.js +134 -0
- package/dist/pipeline/dep-parsers/rust.js.map +1 -0
- package/dist/pipeline/dep-parsers/spdx-normalize.d.ts +15 -0
- package/dist/pipeline/dep-parsers/spdx-normalize.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/spdx-normalize.js +31 -0
- package/dist/pipeline/dep-parsers/spdx-normalize.js.map +1 -0
- package/dist/pipeline/dep-parsers/types.d.ts +63 -0
- package/dist/pipeline/dep-parsers/types.d.ts.map +1 -0
- package/dist/pipeline/dep-parsers/types.js +56 -0
- package/dist/pipeline/dep-parsers/types.js.map +1 -0
- package/dist/pipeline/gitignore-stack.d.ts +44 -0
- package/dist/pipeline/gitignore-stack.d.ts.map +1 -0
- package/dist/pipeline/gitignore-stack.js +69 -0
- package/dist/pipeline/gitignore-stack.js.map +1 -0
- package/dist/pipeline/gitignore.d.ts +67 -0
- package/dist/pipeline/gitignore.d.ts.map +1 -0
- package/dist/pipeline/gitignore.js +210 -0
- package/dist/pipeline/gitignore.js.map +1 -0
- package/dist/pipeline/index.d.ts +53 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +29 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/orchestrator.d.ts +105 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -0
- package/dist/pipeline/orchestrator.js +175 -0
- package/dist/pipeline/orchestrator.js.map +1 -0
- package/dist/pipeline/ownership-helpers/drift.d.ts +41 -0
- package/dist/pipeline/ownership-helpers/drift.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/drift.js +122 -0
- package/dist/pipeline/ownership-helpers/drift.js.map +1 -0
- package/dist/pipeline/ownership-helpers/gini-community.d.ts +24 -0
- package/dist/pipeline/ownership-helpers/gini-community.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/gini-community.js +32 -0
- package/dist/pipeline/ownership-helpers/gini-community.js.map +1 -0
- package/dist/pipeline/ownership-helpers/git-blame-batcher.d.ts +71 -0
- package/dist/pipeline/ownership-helpers/git-blame-batcher.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/git-blame-batcher.js +178 -0
- package/dist/pipeline/ownership-helpers/git-blame-batcher.js.map +1 -0
- package/dist/pipeline/ownership-helpers/line-overlap.d.ts +35 -0
- package/dist/pipeline/ownership-helpers/line-overlap.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/line-overlap.js +62 -0
- package/dist/pipeline/ownership-helpers/line-overlap.js.map +1 -0
- package/dist/pipeline/ownership-helpers/orphan.d.ts +73 -0
- package/dist/pipeline/ownership-helpers/orphan.d.ts.map +1 -0
- package/dist/pipeline/ownership-helpers/orphan.js +117 -0
- package/dist/pipeline/ownership-helpers/orphan.js.map +1 -0
- package/dist/pipeline/phases/accesses.d.ts +44 -0
- package/dist/pipeline/phases/accesses.d.ts.map +1 -0
- package/dist/pipeline/phases/accesses.js +194 -0
- package/dist/pipeline/phases/accesses.js.map +1 -0
- package/dist/pipeline/phases/annotate.d.ts +28 -0
- package/dist/pipeline/phases/annotate.d.ts.map +1 -0
- package/dist/pipeline/phases/annotate.js +60 -0
- package/dist/pipeline/phases/annotate.js.map +1 -0
- package/dist/pipeline/phases/cochange.d.ts +42 -0
- package/dist/pipeline/phases/cochange.d.ts.map +1 -0
- package/dist/pipeline/phases/cochange.js +0 -0
- package/dist/pipeline/phases/cochange.js.map +1 -0
- package/dist/pipeline/phases/communities.d.ts +34 -0
- package/dist/pipeline/phases/communities.d.ts.map +1 -0
- package/dist/pipeline/phases/communities.js +412 -0
- package/dist/pipeline/phases/communities.js.map +1 -0
- package/dist/pipeline/phases/complexity.d.ts +50 -0
- package/dist/pipeline/phases/complexity.d.ts.map +1 -0
- package/dist/pipeline/phases/complexity.js +794 -0
- package/dist/pipeline/phases/complexity.js.map +1 -0
- package/dist/pipeline/phases/confidence-demote.d.ts +23 -0
- package/dist/pipeline/phases/confidence-demote.d.ts.map +1 -0
- package/dist/pipeline/phases/confidence-demote.js +113 -0
- package/dist/pipeline/phases/confidence-demote.js.map +1 -0
- package/dist/pipeline/phases/content-cache.d.ts +166 -0
- package/dist/pipeline/phases/content-cache.d.ts.map +1 -0
- package/dist/pipeline/phases/content-cache.js +323 -0
- package/dist/pipeline/phases/content-cache.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/cobertura.d.ts +25 -0
- package/dist/pipeline/phases/coverage-parsers/cobertura.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/cobertura.js +139 -0
- package/dist/pipeline/phases/coverage-parsers/cobertura.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/coverage-py.d.ts +25 -0
- package/dist/pipeline/phases/coverage-parsers/coverage-py.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/coverage-py.js +51 -0
- package/dist/pipeline/phases/coverage-parsers/coverage-py.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/jacoco.d.ts +32 -0
- package/dist/pipeline/phases/coverage-parsers/jacoco.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/jacoco.js +98 -0
- package/dist/pipeline/phases/coverage-parsers/jacoco.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/lcov.d.ts +21 -0
- package/dist/pipeline/phases/coverage-parsers/lcov.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/lcov.js +104 -0
- package/dist/pipeline/phases/coverage-parsers/lcov.js.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/types.d.ts +27 -0
- package/dist/pipeline/phases/coverage-parsers/types.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage-parsers/types.js +39 -0
- package/dist/pipeline/phases/coverage-parsers/types.js.map +1 -0
- package/dist/pipeline/phases/coverage.d.ts +39 -0
- package/dist/pipeline/phases/coverage.d.ts.map +1 -0
- package/dist/pipeline/phases/coverage.js +154 -0
- package/dist/pipeline/phases/coverage.js.map +1 -0
- package/dist/pipeline/phases/cross-file.d.ts +40 -0
- package/dist/pipeline/phases/cross-file.d.ts.map +1 -0
- package/dist/pipeline/phases/cross-file.js +411 -0
- package/dist/pipeline/phases/cross-file.js.map +1 -0
- package/dist/pipeline/phases/dead-code.d.ts +28 -0
- package/dist/pipeline/phases/dead-code.d.ts.map +1 -0
- package/dist/pipeline/phases/dead-code.js +157 -0
- package/dist/pipeline/phases/dead-code.js.map +1 -0
- package/dist/pipeline/phases/default-set.d.ts +24 -0
- package/dist/pipeline/phases/default-set.d.ts.map +1 -0
- package/dist/pipeline/phases/default-set.js +133 -0
- package/dist/pipeline/phases/default-set.js.map +1 -0
- package/dist/pipeline/phases/dependencies.d.ts +59 -0
- package/dist/pipeline/phases/dependencies.d.ts.map +1 -0
- package/dist/pipeline/phases/dependencies.js +281 -0
- package/dist/pipeline/phases/dependencies.js.map +1 -0
- package/dist/pipeline/phases/embedder-pool.d.ts +31 -0
- package/dist/pipeline/phases/embedder-pool.d.ts.map +1 -0
- package/dist/pipeline/phases/embedder-pool.js +79 -0
- package/dist/pipeline/phases/embedder-pool.js.map +1 -0
- package/dist/pipeline/phases/embedder-worker.d.ts +28 -0
- package/dist/pipeline/phases/embedder-worker.d.ts.map +1 -0
- package/dist/pipeline/phases/embedder-worker.js +43 -0
- package/dist/pipeline/phases/embedder-worker.js.map +1 -0
- package/dist/pipeline/phases/embeddings.d.ts +117 -0
- package/dist/pipeline/phases/embeddings.d.ts.map +1 -0
- package/dist/pipeline/phases/embeddings.js +697 -0
- package/dist/pipeline/phases/embeddings.js.map +1 -0
- package/dist/pipeline/phases/fetches.d.ts +47 -0
- package/dist/pipeline/phases/fetches.d.ts.map +1 -0
- package/dist/pipeline/phases/fetches.js +207 -0
- package/dist/pipeline/phases/fetches.js.map +1 -0
- package/dist/pipeline/phases/incremental-helper.d.ts +96 -0
- package/dist/pipeline/phases/incremental-helper.d.ts.map +1 -0
- package/dist/pipeline/phases/incremental-helper.js +125 -0
- package/dist/pipeline/phases/incremental-helper.js.map +1 -0
- package/dist/pipeline/phases/incremental-scope.d.ts +67 -0
- package/dist/pipeline/phases/incremental-scope.d.ts.map +1 -0
- package/dist/pipeline/phases/incremental-scope.js +225 -0
- package/dist/pipeline/phases/incremental-scope.js.map +1 -0
- package/dist/pipeline/phases/markdown.d.ts +29 -0
- package/dist/pipeline/phases/markdown.d.ts.map +1 -0
- package/dist/pipeline/phases/markdown.js +298 -0
- package/dist/pipeline/phases/markdown.js.map +1 -0
- package/dist/pipeline/phases/mro.d.ts +24 -0
- package/dist/pipeline/phases/mro.d.ts.map +1 -0
- package/dist/pipeline/phases/mro.js +303 -0
- package/dist/pipeline/phases/mro.js.map +1 -0
- package/dist/pipeline/phases/openapi.d.ts +52 -0
- package/dist/pipeline/phases/openapi.d.ts.map +1 -0
- package/dist/pipeline/phases/openapi.js +285 -0
- package/dist/pipeline/phases/openapi.js.map +1 -0
- package/dist/pipeline/phases/orm.d.ts +26 -0
- package/dist/pipeline/phases/orm.d.ts.map +1 -0
- package/dist/pipeline/phases/orm.js +183 -0
- package/dist/pipeline/phases/orm.js.map +1 -0
- package/dist/pipeline/phases/ownership.d.ts +88 -0
- package/dist/pipeline/phases/ownership.d.ts.map +1 -0
- package/dist/pipeline/phases/ownership.js +479 -0
- package/dist/pipeline/phases/ownership.js.map +1 -0
- package/dist/pipeline/phases/parse.d.ts +63 -0
- package/dist/pipeline/phases/parse.d.ts.map +1 -0
- package/dist/pipeline/phases/parse.js +994 -0
- package/dist/pipeline/phases/parse.js.map +1 -0
- package/dist/pipeline/phases/processes.d.ts +47 -0
- package/dist/pipeline/phases/processes.d.ts.map +1 -0
- package/dist/pipeline/phases/processes.js +620 -0
- package/dist/pipeline/phases/processes.js.map +1 -0
- package/dist/pipeline/phases/profile.d.ts +33 -0
- package/dist/pipeline/phases/profile.d.ts.map +1 -0
- package/dist/pipeline/phases/profile.js +91 -0
- package/dist/pipeline/phases/profile.js.map +1 -0
- package/dist/pipeline/phases/repo-node.d.ts +112 -0
- package/dist/pipeline/phases/repo-node.d.ts.map +1 -0
- package/dist/pipeline/phases/repo-node.js +272 -0
- package/dist/pipeline/phases/repo-node.js.map +1 -0
- package/dist/pipeline/phases/risk-snapshot.d.ts +34 -0
- package/dist/pipeline/phases/risk-snapshot.d.ts.map +1 -0
- package/dist/pipeline/phases/risk-snapshot.js +63 -0
- package/dist/pipeline/phases/risk-snapshot.js.map +1 -0
- package/dist/pipeline/phases/routes.d.ts +31 -0
- package/dist/pipeline/phases/routes.d.ts.map +1 -0
- package/dist/pipeline/phases/routes.js +262 -0
- package/dist/pipeline/phases/routes.js.map +1 -0
- package/dist/pipeline/phases/sbom.d.ts +45 -0
- package/dist/pipeline/phases/sbom.d.ts.map +1 -0
- package/dist/pipeline/phases/sbom.js +289 -0
- package/dist/pipeline/phases/sbom.js.map +1 -0
- package/dist/pipeline/phases/scan.d.ts +54 -0
- package/dist/pipeline/phases/scan.d.ts.map +1 -0
- package/dist/pipeline/phases/scan.js +340 -0
- package/dist/pipeline/phases/scan.js.map +1 -0
- package/dist/pipeline/phases/scip-index.d.ts +54 -0
- package/dist/pipeline/phases/scip-index.d.ts.map +1 -0
- package/dist/pipeline/phases/scip-index.js +469 -0
- package/dist/pipeline/phases/scip-index.js.map +1 -0
- package/dist/pipeline/phases/structure.d.ts +21 -0
- package/dist/pipeline/phases/structure.d.ts.map +1 -0
- package/dist/pipeline/phases/structure.js +115 -0
- package/dist/pipeline/phases/structure.js.map +1 -0
- package/dist/pipeline/phases/summarize.d.ts +126 -0
- package/dist/pipeline/phases/summarize.d.ts.map +1 -0
- package/dist/pipeline/phases/summarize.js +401 -0
- package/dist/pipeline/phases/summarize.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/branch-divergence.d.ts +42 -0
- package/dist/pipeline/phases/temporal-helpers/branch-divergence.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/branch-divergence.js +96 -0
- package/dist/pipeline/phases/temporal-helpers/branch-divergence.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/churn-decay.d.ts +22 -0
- package/dist/pipeline/phases/temporal-helpers/churn-decay.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/churn-decay.js +32 -0
- package/dist/pipeline/phases/temporal-helpers/churn-decay.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/conventional-commits.d.ts +21 -0
- package/dist/pipeline/phases/temporal-helpers/conventional-commits.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/conventional-commits.js +37 -0
- package/dist/pipeline/phases/temporal-helpers/conventional-commits.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/gini.d.ts +32 -0
- package/dist/pipeline/phases/temporal-helpers/gini.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/gini.js +78 -0
- package/dist/pipeline/phases/temporal-helpers/gini.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/revert-detect.d.ts +14 -0
- package/dist/pipeline/phases/temporal-helpers/revert-detect.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/revert-detect.js +25 -0
- package/dist/pipeline/phases/temporal-helpers/revert-detect.js.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/test-pair.d.ts +18 -0
- package/dist/pipeline/phases/temporal-helpers/test-pair.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal-helpers/test-pair.js +119 -0
- package/dist/pipeline/phases/temporal-helpers/test-pair.js.map +1 -0
- package/dist/pipeline/phases/temporal.d.ts +65 -0
- package/dist/pipeline/phases/temporal.d.ts.map +1 -0
- package/dist/pipeline/phases/temporal.js +621 -0
- package/dist/pipeline/phases/temporal.js.map +1 -0
- package/dist/pipeline/phases/tools.d.ts +21 -0
- package/dist/pipeline/phases/tools.d.ts.map +1 -0
- package/dist/pipeline/phases/tools.js +118 -0
- package/dist/pipeline/phases/tools.js.map +1 -0
- package/dist/pipeline/profile-detectors/api-contracts.d.ts +18 -0
- package/dist/pipeline/profile-detectors/api-contracts.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/api-contracts.js +78 -0
- package/dist/pipeline/profile-detectors/api-contracts.js.map +1 -0
- package/dist/pipeline/profile-detectors/framework-detector.d.ts +11 -0
- package/dist/pipeline/profile-detectors/framework-detector.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/framework-detector.js +11 -0
- package/dist/pipeline/profile-detectors/framework-detector.js.map +1 -0
- package/dist/pipeline/profile-detectors/frameworks-catalog.d.ts +7 -0
- package/dist/pipeline/profile-detectors/frameworks-catalog.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/frameworks-catalog.js +7 -0
- package/dist/pipeline/profile-detectors/frameworks-catalog.js.map +1 -0
- package/dist/pipeline/profile-detectors/frameworks.d.ts +7 -0
- package/dist/pipeline/profile-detectors/frameworks.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/frameworks.js +7 -0
- package/dist/pipeline/profile-detectors/frameworks.js.map +1 -0
- package/dist/pipeline/profile-detectors/iac.d.ts +22 -0
- package/dist/pipeline/profile-detectors/iac.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/iac.js +97 -0
- package/dist/pipeline/profile-detectors/iac.js.map +1 -0
- package/dist/pipeline/profile-detectors/languages.d.ts +18 -0
- package/dist/pipeline/profile-detectors/languages.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/languages.js +60 -0
- package/dist/pipeline/profile-detectors/languages.js.map +1 -0
- package/dist/pipeline/profile-detectors/manifests.d.ts +7 -0
- package/dist/pipeline/profile-detectors/manifests.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/manifests.js +7 -0
- package/dist/pipeline/profile-detectors/manifests.js.map +1 -0
- package/dist/pipeline/profile-detectors/src-dirs.d.ts +17 -0
- package/dist/pipeline/profile-detectors/src-dirs.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/src-dirs.js +89 -0
- package/dist/pipeline/profile-detectors/src-dirs.js.map +1 -0
- package/dist/pipeline/profile-detectors/variant-detectors.d.ts +7 -0
- package/dist/pipeline/profile-detectors/variant-detectors.d.ts.map +1 -0
- package/dist/pipeline/profile-detectors/variant-detectors.js +7 -0
- package/dist/pipeline/profile-detectors/variant-detectors.js.map +1 -0
- package/dist/pipeline/runner.d.ts +54 -0
- package/dist/pipeline/runner.d.ts.map +1 -0
- package/dist/pipeline/runner.js +247 -0
- package/dist/pipeline/runner.js.map +1 -0
- package/dist/pipeline/types.d.ts +235 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +15 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/providers/c.d.ts +3 -0
- package/dist/providers/c.d.ts.map +1 -0
- package/dist/providers/c.js +162 -0
- package/dist/providers/c.js.map +1 -0
- package/dist/providers/cobol.d.ts +19 -0
- package/dist/providers/cobol.d.ts.map +1 -0
- package/dist/providers/cobol.js +44 -0
- package/dist/providers/cobol.js.map +1 -0
- package/dist/providers/cpp.d.ts +3 -0
- package/dist/providers/cpp.d.ts.map +1 -0
- package/dist/providers/cpp.js +200 -0
- package/dist/providers/cpp.js.map +1 -0
- package/dist/providers/csharp.d.ts +3 -0
- package/dist/providers/csharp.d.ts.map +1 -0
- package/dist/providers/csharp.js +292 -0
- package/dist/providers/csharp.js.map +1 -0
- package/dist/providers/dart.d.ts +3 -0
- package/dist/providers/dart.d.ts.map +1 -0
- package/dist/providers/dart.js +214 -0
- package/dist/providers/dart.js.map +1 -0
- package/dist/providers/definition-ids.d.ts +18 -0
- package/dist/providers/definition-ids.d.ts.map +1 -0
- package/dist/providers/definition-ids.js +23 -0
- package/dist/providers/definition-ids.js.map +1 -0
- package/dist/providers/extract-helpers.d.ts +60 -0
- package/dist/providers/extract-helpers.d.ts.map +1 -0
- package/dist/providers/extract-helpers.js +296 -0
- package/dist/providers/extract-helpers.js.map +1 -0
- package/dist/providers/extraction-types.d.ts +85 -0
- package/dist/providers/extraction-types.d.ts.map +1 -0
- package/dist/providers/extraction-types.js +13 -0
- package/dist/providers/extraction-types.js.map +1 -0
- package/dist/providers/go.d.ts +3 -0
- package/dist/providers/go.d.ts.map +1 -0
- package/dist/providers/go.js +359 -0
- package/dist/providers/go.js.map +1 -0
- package/dist/providers/http-detect.d.ts +44 -0
- package/dist/providers/http-detect.d.ts.map +1 -0
- package/dist/providers/http-detect.js +307 -0
- package/dist/providers/http-detect.js.map +1 -0
- package/dist/providers/index.d.ts +38 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +33 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/java.d.ts +3 -0
- package/dist/providers/java.d.ts.map +1 -0
- package/dist/providers/java.js +259 -0
- package/dist/providers/java.js.map +1 -0
- package/dist/providers/javascript.d.ts +3 -0
- package/dist/providers/javascript.d.ts.map +1 -0
- package/dist/providers/javascript.js +139 -0
- package/dist/providers/javascript.js.map +1 -0
- package/dist/providers/kotlin.d.ts +3 -0
- package/dist/providers/kotlin.d.ts.map +1 -0
- package/dist/providers/kotlin.js +175 -0
- package/dist/providers/kotlin.js.map +1 -0
- package/dist/providers/php.d.ts +3 -0
- package/dist/providers/php.d.ts.map +1 -0
- package/dist/providers/php.js +218 -0
- package/dist/providers/php.js.map +1 -0
- package/dist/providers/python-accesses.d.ts +9 -0
- package/dist/providers/python-accesses.d.ts.map +1 -0
- package/dist/providers/python-accesses.js +22 -0
- package/dist/providers/python-accesses.js.map +1 -0
- package/dist/providers/python.d.ts +3 -0
- package/dist/providers/python.d.ts.map +1 -0
- package/dist/providers/python.js +323 -0
- package/dist/providers/python.js.map +1 -0
- package/dist/providers/registry.d.ts +4 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +46 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/resolution/c3.d.ts +6 -0
- package/dist/providers/resolution/c3.d.ts.map +1 -0
- package/dist/providers/resolution/c3.js +76 -0
- package/dist/providers/resolution/c3.js.map +1 -0
- package/dist/providers/resolution/context.d.ts +38 -0
- package/dist/providers/resolution/context.d.ts.map +1 -0
- package/dist/providers/resolution/context.js +45 -0
- package/dist/providers/resolution/context.js.map +1 -0
- package/dist/providers/resolution/first-wins.d.ts +3 -0
- package/dist/providers/resolution/first-wins.d.ts.map +1 -0
- package/dist/providers/resolution/first-wins.js +27 -0
- package/dist/providers/resolution/first-wins.js.map +1 -0
- package/dist/providers/resolution/mro.d.ts +16 -0
- package/dist/providers/resolution/mro.d.ts.map +1 -0
- package/dist/providers/resolution/mro.js +14 -0
- package/dist/providers/resolution/mro.js.map +1 -0
- package/dist/providers/resolution/none.d.ts +3 -0
- package/dist/providers/resolution/none.d.ts.map +1 -0
- package/dist/providers/resolution/none.js +11 -0
- package/dist/providers/resolution/none.js.map +1 -0
- package/dist/providers/resolution/python-all-filter.d.ts +25 -0
- package/dist/providers/resolution/python-all-filter.d.ts.map +1 -0
- package/dist/providers/resolution/python-all-filter.js +64 -0
- package/dist/providers/resolution/python-all-filter.js.map +1 -0
- package/dist/providers/resolution/resolver-strategy.d.ts +42 -0
- package/dist/providers/resolution/resolver-strategy.d.ts.map +1 -0
- package/dist/providers/resolution/resolver-strategy.js +50 -0
- package/dist/providers/resolution/resolver-strategy.js.map +1 -0
- package/dist/providers/resolution/single-inheritance.d.ts +3 -0
- package/dist/providers/resolution/single-inheritance.d.ts.map +1 -0
- package/dist/providers/resolution/single-inheritance.js +21 -0
- package/dist/providers/resolution/single-inheritance.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/__fixtures__/mock-tree.d.ts +16 -0
- package/dist/providers/resolution/stack-graphs/__fixtures__/mock-tree.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/__fixtures__/mock-tree.js +50 -0
- package/dist/providers/resolution/stack-graphs/__fixtures__/mock-tree.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/glue.d.ts +15 -0
- package/dist/providers/resolution/stack-graphs/glue.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/glue.js +44 -0
- package/dist/providers/resolution/stack-graphs/glue.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/node-edge-builder.d.ts +30 -0
- package/dist/providers/resolution/stack-graphs/node-edge-builder.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/node-edge-builder.js +366 -0
- package/dist/providers/resolution/stack-graphs/node-edge-builder.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/partial-path-engine.d.ts +9 -0
- package/dist/providers/resolution/stack-graphs/partial-path-engine.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/partial-path-engine.js +152 -0
- package/dist/providers/resolution/stack-graphs/partial-path-engine.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/rule-parser.d.ts +11 -0
- package/dist/providers/resolution/stack-graphs/rule-parser.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/rule-parser.js +247 -0
- package/dist/providers/resolution/stack-graphs/rule-parser.js.map +1 -0
- package/dist/providers/resolution/stack-graphs/types.d.ts +93 -0
- package/dist/providers/resolution/stack-graphs/types.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs/types.js +11 -0
- package/dist/providers/resolution/stack-graphs/types.js.map +1 -0
- package/dist/providers/resolution/stack-graphs-python.d.ts +27 -0
- package/dist/providers/resolution/stack-graphs-python.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs-python.js +104 -0
- package/dist/providers/resolution/stack-graphs-python.js.map +1 -0
- package/dist/providers/resolution/stack-graphs-ts.d.ts +134 -0
- package/dist/providers/resolution/stack-graphs-ts.d.ts.map +1 -0
- package/dist/providers/resolution/stack-graphs-ts.js +372 -0
- package/dist/providers/resolution/stack-graphs-ts.js.map +1 -0
- package/dist/providers/ruby.d.ts +3 -0
- package/dist/providers/ruby.d.ts.map +1 -0
- package/dist/providers/ruby.js +259 -0
- package/dist/providers/ruby.js.map +1 -0
- package/dist/providers/rust.d.ts +3 -0
- package/dist/providers/rust.d.ts.map +1 -0
- package/dist/providers/rust.js +318 -0
- package/dist/providers/rust.js.map +1 -0
- package/dist/providers/swift.d.ts +3 -0
- package/dist/providers/swift.d.ts.map +1 -0
- package/dist/providers/swift.js +177 -0
- package/dist/providers/swift.js.map +1 -0
- package/dist/providers/test-helpers.d.ts +24 -0
- package/dist/providers/test-helpers.d.ts.map +1 -0
- package/dist/providers/test-helpers.js +33 -0
- package/dist/providers/test-helpers.js.map +1 -0
- package/dist/providers/ts-shared.d.ts +30 -0
- package/dist/providers/ts-shared.d.ts.map +1 -0
- package/dist/providers/ts-shared.js +328 -0
- package/dist/providers/ts-shared.js.map +1 -0
- package/dist/providers/tsx.d.ts +7 -0
- package/dist/providers/tsx.d.ts.map +1 -0
- package/dist/providers/tsx.js +79 -0
- package/dist/providers/tsx.js.map +1 -0
- package/dist/providers/types.d.ts +166 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +7 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/providers/typescript-family-accesses.d.ts +14 -0
- package/dist/providers/typescript-family-accesses.d.ts.map +1 -0
- package/dist/providers/typescript-family-accesses.js +27 -0
- package/dist/providers/typescript-family-accesses.js.map +1 -0
- package/dist/providers/typescript.d.ts +9 -0
- package/dist/providers/typescript.d.ts.map +1 -0
- package/dist/providers/typescript.js +84 -0
- package/dist/providers/typescript.js.map +1 -0
- package/package.json +108 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch-blame helper for the ownership phase.
|
|
3
|
+
*
|
|
4
|
+
* `git` exposes no native multi-file blame command, so we parallelise per-file
|
|
5
|
+
* `git blame --porcelain` invocations behind a bounded concurrency pool. Two
|
|
6
|
+
* one-time set-up steps precede the fleet to minimise per-file cost:
|
|
7
|
+
* 1. `git commit-graph write --reachable --changed-paths` materialises Bloom
|
|
8
|
+
* filters the blame engine uses to skip unrelated commits (2-6× speedup).
|
|
9
|
+
* 2. We resolve parallelism to `max(2, availableParallelism - 2)` capped at
|
|
10
|
+
* 32 — past that, I/O contention dominates.
|
|
11
|
+
*
|
|
12
|
+
* The porcelain format is deterministic line-by-line:
|
|
13
|
+
* <commit-sha> <orig-line> <final-line> [<group-size>]
|
|
14
|
+
* author <name>
|
|
15
|
+
* author-mail <<email>>
|
|
16
|
+
* ... other headers, terminated by a `\t<literal source line>` marker.
|
|
17
|
+
*
|
|
18
|
+
* A commit-sha repeats its headers only on the first line of each group, so a
|
|
19
|
+
* cache of sha → author metadata short-circuits repeat headers. Output is a
|
|
20
|
+
* deterministic `Map<relPath, LineOwner[]>`; the map preserves caller-provided
|
|
21
|
+
* insertion order but each `LineOwner[]` is ordered by line number.
|
|
22
|
+
*/
|
|
23
|
+
import { execFile } from "node:child_process";
|
|
24
|
+
import { availableParallelism } from "node:os";
|
|
25
|
+
import { promisify } from "node:util";
|
|
26
|
+
const execFileAsync = promisify(execFile);
|
|
27
|
+
const GIT_MAX_BUFFER = 256 * 1024 * 1024; // 256 MB; large files still fit.
|
|
28
|
+
const BLAME_POOL_CAP = 32;
|
|
29
|
+
/**
|
|
30
|
+
* Run `git blame --porcelain` against each `relPaths` entry in parallel and
|
|
31
|
+
* return the aggregated attribution map.
|
|
32
|
+
*
|
|
33
|
+
* Determinism: outputs are inserted into the map in sorted `relPath` order
|
|
34
|
+
* regardless of completion order, and each per-file `LineOwner[]` is sorted
|
|
35
|
+
* by line number.
|
|
36
|
+
*/
|
|
37
|
+
export async function batchBlame(repoPath, relPaths, opts = {}) {
|
|
38
|
+
if (relPaths.length === 0) {
|
|
39
|
+
return { byFile: new Map(), subprocessCount: 0, skippedCount: 0 };
|
|
40
|
+
}
|
|
41
|
+
if (opts.warmCommitGraph !== false) {
|
|
42
|
+
try {
|
|
43
|
+
await execFileAsync("git", ["commit-graph", "write", "--reachable", "--changed-paths"], {
|
|
44
|
+
cwd: repoPath,
|
|
45
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Shallow clones, no commits, or missing bloom-filter support all
|
|
50
|
+
// surface as non-zero exit here. Blame still works without the warm-up.
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const poolSize = resolvePoolSize(opts.concurrency);
|
|
54
|
+
const sortedPaths = [...relPaths].sort();
|
|
55
|
+
const results = new Map();
|
|
56
|
+
let subprocessCount = 0;
|
|
57
|
+
let skippedCount = 0;
|
|
58
|
+
const queue = [...sortedPaths];
|
|
59
|
+
const workers = [];
|
|
60
|
+
for (let i = 0; i < Math.min(poolSize, queue.length); i += 1) {
|
|
61
|
+
workers.push((async () => {
|
|
62
|
+
for (;;) {
|
|
63
|
+
const relPath = queue.shift();
|
|
64
|
+
if (relPath === undefined)
|
|
65
|
+
return;
|
|
66
|
+
try {
|
|
67
|
+
const { stdout } = await execFileAsync("git", ["blame", "--porcelain", "--", relPath], {
|
|
68
|
+
cwd: repoPath,
|
|
69
|
+
maxBuffer: GIT_MAX_BUFFER,
|
|
70
|
+
encoding: "utf8",
|
|
71
|
+
});
|
|
72
|
+
subprocessCount += 1;
|
|
73
|
+
const lines = parsePorcelainBlame(stdout);
|
|
74
|
+
if (lines.length > 0) {
|
|
75
|
+
results.set(relPath, lines);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
skippedCount += 1;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
subprocessCount += 1;
|
|
83
|
+
skippedCount += 1;
|
|
84
|
+
opts.onWarn?.(relPath, err.message);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
})());
|
|
88
|
+
}
|
|
89
|
+
await Promise.all(workers);
|
|
90
|
+
// Re-materialise the map in sorted path order so downstream iteration is
|
|
91
|
+
// deterministic even if worker completion order was not.
|
|
92
|
+
const ordered = new Map();
|
|
93
|
+
for (const relPath of sortedPaths) {
|
|
94
|
+
const entry = results.get(relPath);
|
|
95
|
+
if (entry !== undefined)
|
|
96
|
+
ordered.set(relPath, entry);
|
|
97
|
+
}
|
|
98
|
+
return { byFile: ordered, subprocessCount, skippedCount };
|
|
99
|
+
}
|
|
100
|
+
function resolvePoolSize(overrideMaybe) {
|
|
101
|
+
if (overrideMaybe !== undefined) {
|
|
102
|
+
const clamped = Math.floor(Math.max(1, Math.min(overrideMaybe, BLAME_POOL_CAP)));
|
|
103
|
+
return clamped;
|
|
104
|
+
}
|
|
105
|
+
const cpus = availableParallelism();
|
|
106
|
+
const target = Math.max(2, cpus - 2);
|
|
107
|
+
return Math.min(target, BLAME_POOL_CAP);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Parse `git blame --porcelain` output into per-line owners.
|
|
111
|
+
*
|
|
112
|
+
* The format groups consecutive lines attributed to the same commit; only the
|
|
113
|
+
* first line of each group includes the `author` / `author-mail` headers. We
|
|
114
|
+
* cache per-sha author metadata across groups so later groups can reuse the
|
|
115
|
+
* first group's headers.
|
|
116
|
+
*/
|
|
117
|
+
export function parsePorcelainBlame(stdout) {
|
|
118
|
+
if (stdout.length === 0)
|
|
119
|
+
return [];
|
|
120
|
+
const out = [];
|
|
121
|
+
const authorBySha = new Map();
|
|
122
|
+
const lines = stdout.split("\n");
|
|
123
|
+
let i = 0;
|
|
124
|
+
while (i < lines.length) {
|
|
125
|
+
const header = lines[i] ?? "";
|
|
126
|
+
i += 1;
|
|
127
|
+
// Header line: `<sha> <origLine> <finalLine> [<groupSize>]`.
|
|
128
|
+
const headerMatch = /^([0-9a-f]{7,40}) (\d+) (\d+)(?: (\d+))?$/.exec(header);
|
|
129
|
+
if (headerMatch === null)
|
|
130
|
+
continue;
|
|
131
|
+
const sha = headerMatch[1] ?? "";
|
|
132
|
+
// Position 3 is the final (post-move) line number — that's the blame
|
|
133
|
+
// output we care about. Position 2 is the commit-time origin line.
|
|
134
|
+
const finalLine = Number(headerMatch[3] ?? "0");
|
|
135
|
+
if (!Number.isFinite(finalLine) || finalLine <= 0)
|
|
136
|
+
continue;
|
|
137
|
+
let currentName = authorBySha.get(sha)?.name ?? "";
|
|
138
|
+
let currentEmail = authorBySha.get(sha)?.email ?? "";
|
|
139
|
+
while (i < lines.length) {
|
|
140
|
+
const line = lines[i] ?? "";
|
|
141
|
+
if (line.startsWith("\t")) {
|
|
142
|
+
// Tab-prefixed line is the source text of the current record.
|
|
143
|
+
i += 1;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
if (line.startsWith("author ")) {
|
|
147
|
+
currentName = line.slice("author ".length);
|
|
148
|
+
}
|
|
149
|
+
else if (line.startsWith("author-mail ")) {
|
|
150
|
+
const raw = line.slice("author-mail ".length).trim();
|
|
151
|
+
currentEmail = normaliseEmail(raw);
|
|
152
|
+
}
|
|
153
|
+
i += 1;
|
|
154
|
+
}
|
|
155
|
+
if (sha.length > 0 && currentEmail.length > 0) {
|
|
156
|
+
const cached = authorBySha.get(sha);
|
|
157
|
+
if (cached === undefined) {
|
|
158
|
+
authorBySha.set(sha, { name: currentName, email: currentEmail });
|
|
159
|
+
}
|
|
160
|
+
out.push({
|
|
161
|
+
line: finalLine,
|
|
162
|
+
email: currentEmail,
|
|
163
|
+
authorName: currentName,
|
|
164
|
+
sha,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
out.sort((a, b) => a.line - b.line);
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
function normaliseEmail(rawWithBrackets) {
|
|
172
|
+
const trimmed = rawWithBrackets.trim();
|
|
173
|
+
if (trimmed.startsWith("<") && trimmed.endsWith(">")) {
|
|
174
|
+
return trimmed.slice(1, -1).trim().toLowerCase();
|
|
175
|
+
}
|
|
176
|
+
return trimmed.toLowerCase();
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=git-blame-batcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-blame-batcher.js","sourceRoot":"","sources":["../../../src/pipeline/ownership-helpers/git-blame-batcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Given a symbol's line range and a file's per-line blame attribution,
|
|
3
|
+
* compute each contributor's normalised line share.
|
|
4
|
+
*
|
|
5
|
+
* The formula is deliberately simple: count how many of the symbol's lines
|
|
6
|
+
* each contributor claims, divide by the symbol's line count, and emit the
|
|
7
|
+
* result sorted by email hash for determinism.
|
|
8
|
+
*
|
|
9
|
+
* File-level shares reuse this helper by passing `startLine=1` and
|
|
10
|
+
* `endLine=fileLineCount`.
|
|
11
|
+
*/
|
|
12
|
+
import type { LineOwner } from "./git-blame-batcher.js";
|
|
13
|
+
export interface ContributorWeight {
|
|
14
|
+
readonly email: string;
|
|
15
|
+
readonly lines: number;
|
|
16
|
+
/** Share in `[0, 1]` of the symbol's lines attributed to this contributor. */
|
|
17
|
+
readonly weight: number;
|
|
18
|
+
}
|
|
19
|
+
export interface AttributionOptions {
|
|
20
|
+
/** Minimum share to keep; defaults to 0 (no filter). */
|
|
21
|
+
readonly minWeight?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build a map from email → {lines, weight} for every contributor with at
|
|
25
|
+
* least one line in the `[startLine, endLine]` range.
|
|
26
|
+
*
|
|
27
|
+
* `fileBlame` is expected to be ordered by line ascending; the caller obtains
|
|
28
|
+
* it via `batchBlame`. Lines outside the range are ignored; lines inside
|
|
29
|
+
* the range with no blame entry (a rare parse-skip case) contribute to the
|
|
30
|
+
* denominator but not to any contributor's numerator.
|
|
31
|
+
*/
|
|
32
|
+
export declare function attributeSymbolOwnership(startLine: number, endLine: number, fileBlame: readonly LineOwner[], opts?: AttributionOptions): readonly ContributorWeight[];
|
|
33
|
+
/** Sum of lines attributed to each contributor across the whole file. */
|
|
34
|
+
export declare function attributeFileOwnership(fileBlame: readonly LineOwner[]): readonly ContributorWeight[];
|
|
35
|
+
//# sourceMappingURL=line-overlap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-overlap.d.ts","sourceRoot":"","sources":["../../../src/pipeline/ownership-helpers/line-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,SAAS,EAAE,EAC/B,IAAI,GAAE,kBAAuB,GAC5B,SAAS,iBAAiB,EAAE,CAuB9B;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,SAAS,EAAE,GAC9B,SAAS,iBAAiB,EAAE,CAO9B"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Given a symbol's line range and a file's per-line blame attribution,
|
|
3
|
+
* compute each contributor's normalised line share.
|
|
4
|
+
*
|
|
5
|
+
* The formula is deliberately simple: count how many of the symbol's lines
|
|
6
|
+
* each contributor claims, divide by the symbol's line count, and emit the
|
|
7
|
+
* result sorted by email hash for determinism.
|
|
8
|
+
*
|
|
9
|
+
* File-level shares reuse this helper by passing `startLine=1` and
|
|
10
|
+
* `endLine=fileLineCount`.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Build a map from email → {lines, weight} for every contributor with at
|
|
14
|
+
* least one line in the `[startLine, endLine]` range.
|
|
15
|
+
*
|
|
16
|
+
* `fileBlame` is expected to be ordered by line ascending; the caller obtains
|
|
17
|
+
* it via `batchBlame`. Lines outside the range are ignored; lines inside
|
|
18
|
+
* the range with no blame entry (a rare parse-skip case) contribute to the
|
|
19
|
+
* denominator but not to any contributor's numerator.
|
|
20
|
+
*/
|
|
21
|
+
export function attributeSymbolOwnership(startLine, endLine, fileBlame, opts = {}) {
|
|
22
|
+
if (endLine < startLine)
|
|
23
|
+
return [];
|
|
24
|
+
const span = endLine - startLine + 1;
|
|
25
|
+
if (span <= 0)
|
|
26
|
+
return [];
|
|
27
|
+
const counts = new Map();
|
|
28
|
+
for (const owner of fileBlame) {
|
|
29
|
+
if (owner.line < startLine || owner.line > endLine)
|
|
30
|
+
continue;
|
|
31
|
+
counts.set(owner.email, (counts.get(owner.email) ?? 0) + 1);
|
|
32
|
+
}
|
|
33
|
+
if (counts.size === 0)
|
|
34
|
+
return [];
|
|
35
|
+
const minWeight = opts.minWeight ?? 0;
|
|
36
|
+
const entries = [];
|
|
37
|
+
for (const [email, lines] of counts) {
|
|
38
|
+
const weight = lines / span;
|
|
39
|
+
if (weight < minWeight)
|
|
40
|
+
continue;
|
|
41
|
+
entries.push({ email, lines, weight });
|
|
42
|
+
}
|
|
43
|
+
// Sort by descending weight, then ascending email for stable tiebreaks.
|
|
44
|
+
entries.sort((a, b) => {
|
|
45
|
+
if (a.weight !== b.weight)
|
|
46
|
+
return b.weight - a.weight;
|
|
47
|
+
return a.email < b.email ? -1 : a.email > b.email ? 1 : 0;
|
|
48
|
+
});
|
|
49
|
+
return entries;
|
|
50
|
+
}
|
|
51
|
+
/** Sum of lines attributed to each contributor across the whole file. */
|
|
52
|
+
export function attributeFileOwnership(fileBlame) {
|
|
53
|
+
if (fileBlame.length === 0)
|
|
54
|
+
return [];
|
|
55
|
+
let maxLine = 0;
|
|
56
|
+
for (const owner of fileBlame) {
|
|
57
|
+
if (owner.line > maxLine)
|
|
58
|
+
maxLine = owner.line;
|
|
59
|
+
}
|
|
60
|
+
return attributeSymbolOwnership(1, maxLine, fileBlame);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=line-overlap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"line-overlap.js","sourceRoot":"","sources":["../../../src/pipeline/ownership-helpers/line-overlap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgBH;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAAiB,EACjB,OAAe,EACf,SAA+B,EAC/B,OAA2B,EAAE;IAE7B,IAAI,OAAO,GAAG,SAAS;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG,OAAO,GAAG,SAAS,GAAG,CAAC,CAAC;IACrC,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,IAAI,GAAG,SAAS,IAAI,KAAK,CAAC,IAAI,GAAG,OAAO;YAAE,SAAS;QAC7D,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACpC,MAAM,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;QAC5B,IAAI,MAAM,GAAG,SAAS;YAAE,SAAS;QACjC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,wEAAwE;IACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpB,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;QACtD,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,sBAAsB,CACpC,SAA+B;IAE/B,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,IAAI,GAAG,OAAO;YAAE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC;IACjD,CAAC;IACD,OAAO,wBAAwB,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orphan detection.
|
|
3
|
+
*
|
|
4
|
+
* Classifies each File into one of four lifecycle buckets, driven by
|
|
5
|
+
* three inputs per file:
|
|
6
|
+
*
|
|
7
|
+
* - `topContributorLastSeenDays` from temporal signal 11.
|
|
8
|
+
* - `coauthors365d`: count of distinct Co-authored-by: emails across the
|
|
9
|
+
* past 365 days of commits touching this file.
|
|
10
|
+
* - `decayedChurn` from temporal signal 6.
|
|
11
|
+
*
|
|
12
|
+
* Grades:
|
|
13
|
+
* - `active` — none of the lifecycle conditions fire.
|
|
14
|
+
* - `orphaned` — top contributor inactive for >180 days, no recent
|
|
15
|
+
* coauthors, but the file still shows non-trivial churn.
|
|
16
|
+
* - `abandoned` — top contributor inactive for >365 days with non-trivial
|
|
17
|
+
* churn remaining.
|
|
18
|
+
* - `fossilized` — top contributor inactive for >730 days and no churn
|
|
19
|
+
* above epsilon; old code that nobody touches.
|
|
20
|
+
*
|
|
21
|
+
* `epsilon` is 1% of the repo-median `decayedChurn` so the threshold scales
|
|
22
|
+
* with repo activity — a high-churn monorepo demands a higher bar than a
|
|
23
|
+
* handful of scripts.
|
|
24
|
+
*/
|
|
25
|
+
export type OrphanGrade = "active" | "orphaned" | "abandoned" | "fossilized";
|
|
26
|
+
export interface OrphanFileInput {
|
|
27
|
+
/** Days since the file's top contributor last appeared anywhere in the repo. */
|
|
28
|
+
readonly topContributorLastSeenDays: number | undefined;
|
|
29
|
+
/** Distinct Co-authored-by: emails in the past 365 days. */
|
|
30
|
+
readonly coauthors365d: number;
|
|
31
|
+
/** Sum of exponential-decay churn weights for the file. */
|
|
32
|
+
readonly decayedChurn: number;
|
|
33
|
+
}
|
|
34
|
+
export interface OrphanClassificationInput {
|
|
35
|
+
/** Optional override of the epsilon threshold; default = 1% of repo median. */
|
|
36
|
+
readonly epsilonOverride?: number;
|
|
37
|
+
/** Whether enough history exists; when `false`, all files return `"active"`. */
|
|
38
|
+
readonly hasEnoughHistory: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Compute the orphan epsilon threshold from a repo's decayed-churn vector.
|
|
42
|
+
* Zero-length input yields 0 (everything passes the churn filter vacuously).
|
|
43
|
+
*/
|
|
44
|
+
export declare function computeOrphanEpsilon(decayedChurnValues: readonly number[], percentOfMedian?: number): number;
|
|
45
|
+
/**
|
|
46
|
+
* Classify a single file. Rule precedence (first match wins):
|
|
47
|
+
* 1. `fossilized` — oldest top contributor, churn at-or-below epsilon.
|
|
48
|
+
* 2. `abandoned` — top contributor inactive >365d, churn above epsilon.
|
|
49
|
+
* 3. `orphaned` — top contributor inactive >180d, zero coauthors in the
|
|
50
|
+
* past year, churn above epsilon.
|
|
51
|
+
* 4. `active` — fallthrough.
|
|
52
|
+
*/
|
|
53
|
+
export declare function classifyOrphan(file: OrphanFileInput, ctx: {
|
|
54
|
+
readonly epsilon: number;
|
|
55
|
+
readonly hasEnoughHistory: boolean;
|
|
56
|
+
}): OrphanGrade;
|
|
57
|
+
/**
|
|
58
|
+
* Batch-classify every file in one pass. Returns a Map keyed by the original
|
|
59
|
+
* file key (caller chooses semantics).
|
|
60
|
+
*/
|
|
61
|
+
export declare function classifyOrphans<K>(files: ReadonlyMap<K, OrphanFileInput>, ctxIn: OrphanClassificationInput): Map<K, OrphanGrade>;
|
|
62
|
+
/**
|
|
63
|
+
* Impact multiplier per grade.
|
|
64
|
+
*
|
|
65
|
+
* Scale (active / orphaned / abandoned / fossilized) = (1.0 / 1.3 / 1.6 / 1.6).
|
|
66
|
+
* Fossilized ties with abandoned at the top because dormant-old code often
|
|
67
|
+
* carries the most hidden complexity (the top contributor is long gone and
|
|
68
|
+
* no one has touched it, so nobody has warmed the file into working memory
|
|
69
|
+
* recently). Orphaned sits in the middle: the code still churns, just
|
|
70
|
+
* without the original author.
|
|
71
|
+
*/
|
|
72
|
+
export declare function orphanImpactMultiplier(grade: OrphanGrade | undefined): number;
|
|
73
|
+
//# sourceMappingURL=orphan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orphan.d.ts","sourceRoot":"","sources":["../../../src/pipeline/ownership-helpers/orphan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,YAAY,CAAC;AAE7E,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,0BAA0B,EAAE,MAAM,GAAG,SAAS,CAAC;IACxD,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,yBAAyB;IACxC,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC;AAMD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,kBAAkB,EAAE,SAAS,MAAM,EAAE,EACrC,eAAe,SAAO,GACrB,MAAM,CASR;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,GACpE,WAAW,CAYb;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,KAAK,EAAE,WAAW,CAAC,CAAC,EAAE,eAAe,CAAC,EACtC,KAAK,EAAE,yBAAyB,GAC/B,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAarB;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAmB7E"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orphan detection.
|
|
3
|
+
*
|
|
4
|
+
* Classifies each File into one of four lifecycle buckets, driven by
|
|
5
|
+
* three inputs per file:
|
|
6
|
+
*
|
|
7
|
+
* - `topContributorLastSeenDays` from temporal signal 11.
|
|
8
|
+
* - `coauthors365d`: count of distinct Co-authored-by: emails across the
|
|
9
|
+
* past 365 days of commits touching this file.
|
|
10
|
+
* - `decayedChurn` from temporal signal 6.
|
|
11
|
+
*
|
|
12
|
+
* Grades:
|
|
13
|
+
* - `active` — none of the lifecycle conditions fire.
|
|
14
|
+
* - `orphaned` — top contributor inactive for >180 days, no recent
|
|
15
|
+
* coauthors, but the file still shows non-trivial churn.
|
|
16
|
+
* - `abandoned` — top contributor inactive for >365 days with non-trivial
|
|
17
|
+
* churn remaining.
|
|
18
|
+
* - `fossilized` — top contributor inactive for >730 days and no churn
|
|
19
|
+
* above epsilon; old code that nobody touches.
|
|
20
|
+
*
|
|
21
|
+
* `epsilon` is 1% of the repo-median `decayedChurn` so the threshold scales
|
|
22
|
+
* with repo activity — a high-churn monorepo demands a higher bar than a
|
|
23
|
+
* handful of scripts.
|
|
24
|
+
*/
|
|
25
|
+
const ORPHANED_DAYS = 180;
|
|
26
|
+
const ABANDONED_DAYS = 365;
|
|
27
|
+
const FOSSILIZED_DAYS = 730;
|
|
28
|
+
/**
|
|
29
|
+
* Compute the orphan epsilon threshold from a repo's decayed-churn vector.
|
|
30
|
+
* Zero-length input yields 0 (everything passes the churn filter vacuously).
|
|
31
|
+
*/
|
|
32
|
+
export function computeOrphanEpsilon(decayedChurnValues, percentOfMedian = 0.01) {
|
|
33
|
+
if (decayedChurnValues.length === 0)
|
|
34
|
+
return 0;
|
|
35
|
+
const sorted = [...decayedChurnValues].sort((a, b) => a - b);
|
|
36
|
+
const mid = Math.floor(sorted.length / 2);
|
|
37
|
+
const median = sorted.length % 2 === 1
|
|
38
|
+
? (sorted[mid] ?? 0)
|
|
39
|
+
: ((sorted[mid - 1] ?? 0) + (sorted[mid] ?? 0)) / 2;
|
|
40
|
+
return median * percentOfMedian;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Classify a single file. Rule precedence (first match wins):
|
|
44
|
+
* 1. `fossilized` — oldest top contributor, churn at-or-below epsilon.
|
|
45
|
+
* 2. `abandoned` — top contributor inactive >365d, churn above epsilon.
|
|
46
|
+
* 3. `orphaned` — top contributor inactive >180d, zero coauthors in the
|
|
47
|
+
* past year, churn above epsilon.
|
|
48
|
+
* 4. `active` — fallthrough.
|
|
49
|
+
*/
|
|
50
|
+
export function classifyOrphan(file, ctx) {
|
|
51
|
+
if (!ctx.hasEnoughHistory)
|
|
52
|
+
return "active";
|
|
53
|
+
const lastSeen = file.topContributorLastSeenDays;
|
|
54
|
+
if (lastSeen === undefined)
|
|
55
|
+
return "active";
|
|
56
|
+
const epsilon = ctx.epsilon;
|
|
57
|
+
const hasMeaningfulChurn = file.decayedChurn > epsilon;
|
|
58
|
+
if (lastSeen > FOSSILIZED_DAYS && !hasMeaningfulChurn)
|
|
59
|
+
return "fossilized";
|
|
60
|
+
if (lastSeen > ABANDONED_DAYS && hasMeaningfulChurn)
|
|
61
|
+
return "abandoned";
|
|
62
|
+
if (lastSeen > ORPHANED_DAYS && hasMeaningfulChurn && file.coauthors365d === 0) {
|
|
63
|
+
return "orphaned";
|
|
64
|
+
}
|
|
65
|
+
return "active";
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Batch-classify every file in one pass. Returns a Map keyed by the original
|
|
69
|
+
* file key (caller chooses semantics).
|
|
70
|
+
*/
|
|
71
|
+
export function classifyOrphans(files, ctxIn) {
|
|
72
|
+
const out = new Map();
|
|
73
|
+
if (!ctxIn.hasEnoughHistory) {
|
|
74
|
+
for (const key of files.keys())
|
|
75
|
+
out.set(key, "active");
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
const decayedChurnValues = [];
|
|
79
|
+
for (const f of files.values())
|
|
80
|
+
decayedChurnValues.push(f.decayedChurn);
|
|
81
|
+
const epsilon = ctxIn.epsilonOverride ?? computeOrphanEpsilon(decayedChurnValues);
|
|
82
|
+
for (const [key, f] of files) {
|
|
83
|
+
out.set(key, classifyOrphan(f, { epsilon, hasEnoughHistory: true }));
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Impact multiplier per grade.
|
|
89
|
+
*
|
|
90
|
+
* Scale (active / orphaned / abandoned / fossilized) = (1.0 / 1.3 / 1.6 / 1.6).
|
|
91
|
+
* Fossilized ties with abandoned at the top because dormant-old code often
|
|
92
|
+
* carries the most hidden complexity (the top contributor is long gone and
|
|
93
|
+
* no one has touched it, so nobody has warmed the file into working memory
|
|
94
|
+
* recently). Orphaned sits in the middle: the code still churns, just
|
|
95
|
+
* without the original author.
|
|
96
|
+
*/
|
|
97
|
+
export function orphanImpactMultiplier(grade) {
|
|
98
|
+
switch (grade) {
|
|
99
|
+
case "orphaned":
|
|
100
|
+
return 1.3;
|
|
101
|
+
case "abandoned":
|
|
102
|
+
return 1.6;
|
|
103
|
+
case "fossilized":
|
|
104
|
+
return 1.6;
|
|
105
|
+
case "active":
|
|
106
|
+
case undefined:
|
|
107
|
+
return 1.0;
|
|
108
|
+
default: {
|
|
109
|
+
// Exhaustiveness — new grades added to the union without updating this
|
|
110
|
+
// switch will fail TypeScript's checks at build time.
|
|
111
|
+
const _exhaust = grade;
|
|
112
|
+
void _exhaust;
|
|
113
|
+
return 1.0;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=orphan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orphan.js","sourceRoot":"","sources":["../../../src/pipeline/ownership-helpers/orphan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accesses phase — emits ACCESSES edges from Function/Method/Constructor
|
|
3
|
+
* nodes to Property nodes, tagged `read` or `write`.
|
|
4
|
+
*
|
|
5
|
+
* Scope (v2): providers that opt in (TS, TSX, JS, Python) supply an
|
|
6
|
+
* {@link LanguageProvider.extractPropertyAccesses} hook; everyone else is a
|
|
7
|
+
* silent no-op. The hook receives per-file `definitions`, `captures`,
|
|
8
|
+
* `sourceText`, and `filePath` (mirroring the parse-phase hand-off) and
|
|
9
|
+
* returns {@link PropertyAccess} records keyed by the enclosing symbol's
|
|
10
|
+
* `NodeId`.
|
|
11
|
+
*
|
|
12
|
+
* Resolution: property names are FLAT. For every access we look up a matching
|
|
13
|
+
* `Property` node in order:
|
|
14
|
+
* 1. Same-file property with identical `name`. Matches by name only; a
|
|
15
|
+
* future pass will tighten to (owner, name) pairs once TS classes
|
|
16
|
+
* reliably surface field members.
|
|
17
|
+
* 2. Any other `Property` node with the same name (deterministically the
|
|
18
|
+
* one with the smallest NodeId).
|
|
19
|
+
* 3. If neither hits, we synthesise a `Property:unresolved:<name>` stub
|
|
20
|
+
* node. The stub serves as a stable anchor so a later re-run that
|
|
21
|
+
* introduces the real field produces a CLEAN graph-hash delta instead
|
|
22
|
+
* of orphaned accesses being silently dropped.
|
|
23
|
+
*
|
|
24
|
+
* Determinism:
|
|
25
|
+
* - Files are iterated in sorted order.
|
|
26
|
+
* - Providers sort their accesses before returning.
|
|
27
|
+
* - The phase re-sorts by (fromId, toId, startLine) before calling
|
|
28
|
+
* `graph.addEdge` so the final emit order is independent of provider
|
|
29
|
+
* output order.
|
|
30
|
+
* - A 50,000 edges-per-file cap guards against pathological generated
|
|
31
|
+
* files; overage is dropped with a `warn` event.
|
|
32
|
+
*/
|
|
33
|
+
import type { PipelinePhase } from "../types.js";
|
|
34
|
+
export declare const ACCESSES_PHASE_NAME = "accesses";
|
|
35
|
+
export interface AccessesOutput {
|
|
36
|
+
/** Count of ACCESSES edges actually emitted across all files. */
|
|
37
|
+
readonly edgeCount: number;
|
|
38
|
+
/** Files whose accesses were truncated at {@link MAX_ACCESSES_PER_FILE}. */
|
|
39
|
+
readonly truncatedFiles: readonly string[];
|
|
40
|
+
/** Synthesised `Property:unresolved:<name>` anchors added to the graph. */
|
|
41
|
+
readonly unresolvedCount: number;
|
|
42
|
+
}
|
|
43
|
+
export declare const accessesPhase: PipelinePhase<AccessesOutput>;
|
|
44
|
+
//# sourceMappingURL=accesses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accesses.d.ts","sourceRoot":"","sources":["../../../src/pipeline/phases/accesses.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAKH,OAAO,KAAK,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAIlE,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAK9C,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,2EAA2E;IAC3E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,cAAc,CAUvD,CAAC"}
|