@monoes/monograph 1.5.3 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. package/.monodesign/hook.cache.json +1 -1
  2. package/__tests__/integration/call-attribution.test.ts +116 -0
  3. package/coverage/base.css +224 -0
  4. package/coverage/block-navigation.js +87 -0
  5. package/coverage/coverage-summary.json +399 -0
  6. package/coverage/favicon.png +0 -0
  7. package/coverage/index.html +881 -0
  8. package/coverage/prettify.css +1 -0
  9. package/coverage/prettify.js +2 -0
  10. package/coverage/sort-arrow-sprite.png +0 -0
  11. package/coverage/sorter.js +210 -0
  12. package/coverage/src/analysis/benchmark.ts.html +481 -0
  13. package/coverage/src/analysis/changed-files.ts.html +304 -0
  14. package/coverage/src/analysis/changed-workspaces.ts.html +367 -0
  15. package/coverage/src/analysis/churn-cache.ts.html +622 -0
  16. package/coverage/src/analysis/churn-trend.ts.html +256 -0
  17. package/coverage/src/analysis/churn.ts.html +874 -0
  18. package/coverage/src/analysis/cluster-quality.ts.html +511 -0
  19. package/coverage/src/analysis/combined.ts.html +208 -0
  20. package/coverage/src/analysis/corpus-health.ts.html +208 -0
  21. package/coverage/src/analysis/coverage-gaps.ts.html +823 -0
  22. package/coverage/src/analysis/dep-classification.ts.html +586 -0
  23. package/coverage/src/analysis/dependency-health.ts.html +523 -0
  24. package/coverage/src/analysis/duplicate-exports.ts.html +415 -0
  25. package/coverage/src/analysis/fallow-suppression.ts.html +379 -0
  26. package/coverage/src/analysis/feature-flags-config.ts.html +226 -0
  27. package/coverage/src/analysis/feature-flags.ts.html +754 -0
  28. package/coverage/src/analysis/file-classifier.ts.html +346 -0
  29. package/coverage/src/analysis/git-changed-files.ts.html +271 -0
  30. package/coverage/src/analysis/health-baseline.ts.html +325 -0
  31. package/coverage/src/analysis/index.html +641 -0
  32. package/coverage/src/analysis/issue-filters.ts.html +253 -0
  33. package/coverage/src/analysis/list.ts.html +307 -0
  34. package/coverage/src/analysis/node-similarity.ts.html +430 -0
  35. package/coverage/src/analysis/private-type-leaks.ts.html +442 -0
  36. package/coverage/src/analysis/progress.ts.html +214 -0
  37. package/coverage/src/analysis/project-state.ts.html +370 -0
  38. package/coverage/src/analysis/regression-config.ts.html +193 -0
  39. package/coverage/src/analysis/rule-overrides.ts.html +328 -0
  40. package/coverage/src/analysis/scripts.ts.html +370 -0
  41. package/coverage/src/analysis/shape-extractor.ts.html +691 -0
  42. package/coverage/src/analysis/since-duration.ts.html +211 -0
  43. package/coverage/src/analysis/suppression-context.ts.html +370 -0
  44. package/coverage/src/analysis/suppressions.ts.html +325 -0
  45. package/coverage/src/analysis/surprise-scorer.ts.html +307 -0
  46. package/coverage/src/analysis/targets.ts.html +796 -0
  47. package/coverage/src/analysis/unused-class-members.ts.html +322 -0
  48. package/coverage/src/analysis/workspace-filter.ts.html +352 -0
  49. package/coverage/src/analyze/boundary-analysis.ts.html +472 -0
  50. package/coverage/src/analyze/index.html +161 -0
  51. package/coverage/src/analyze/predicates/file.ts.html +343 -0
  52. package/coverage/src/analyze/predicates/import.ts.html +355 -0
  53. package/coverage/src/analyze/predicates/index.html +146 -0
  54. package/coverage/src/analyze/predicates/lifecycle.ts.html +250 -0
  55. package/coverage/src/analyze/unused-deps.ts.html +295 -0
  56. package/coverage/src/analyze/unused-exports.ts.html +520 -0
  57. package/coverage/src/analyze/unused-files.ts.html +223 -0
  58. package/coverage/src/api/index.html +131 -0
  59. package/coverage/src/api/production-override.ts.html +274 -0
  60. package/coverage/src/api/programmatic.ts.html +439 -0
  61. package/coverage/src/audit.ts.html +787 -0
  62. package/coverage/src/cache/augment-cache.ts.html +274 -0
  63. package/coverage/src/cache/extraction-cache.ts.html +508 -0
  64. package/coverage/src/cache/index.html +131 -0
  65. package/coverage/src/check/filtering.ts.html +319 -0
  66. package/coverage/src/check/index.html +161 -0
  67. package/coverage/src/check/index.ts.html +382 -0
  68. package/coverage/src/check/output.ts.html +322 -0
  69. package/coverage/src/check/rules.ts.html +268 -0
  70. package/coverage/src/ci-template.ts.html +337 -0
  71. package/coverage/src/claude-cli.ts.html +262 -0
  72. package/coverage/src/cli/ai-context.ts.html +664 -0
  73. package/coverage/src/cli/augment.ts.html +427 -0
  74. package/coverage/src/cli/check-update.ts.html +205 -0
  75. package/coverage/src/cli/doctor.ts.html +631 -0
  76. package/coverage/src/cli/eval-server.ts.html +463 -0
  77. package/coverage/src/cli/hooks-install.ts.html +691 -0
  78. package/coverage/src/cli/index.html +221 -0
  79. package/coverage/src/cli/setup.ts.html +676 -0
  80. package/coverage/src/cli/skill-gen.ts.html +1126 -0
  81. package/coverage/src/commands/flags.ts.html +301 -0
  82. package/coverage/src/commands/index.html +116 -0
  83. package/coverage/src/config/boundary-config.ts.html +634 -0
  84. package/coverage/src/config/cli-schema.ts.html +328 -0
  85. package/coverage/src/config/config-parsing.ts.html +391 -0
  86. package/coverage/src/config/duplicates-config.ts.html +271 -0
  87. package/coverage/src/config/external-plugin.ts.html +316 -0
  88. package/coverage/src/config/health-config.ts.html +211 -0
  89. package/coverage/src/config/ignore-exports-used-in-file.ts.html +223 -0
  90. package/coverage/src/config/index.html +341 -0
  91. package/coverage/src/config/migration-types.ts.html +304 -0
  92. package/coverage/src/config/output-format.ts.html +157 -0
  93. package/coverage/src/config/plugins/builtin.ts.html +1318 -0
  94. package/coverage/src/config/plugins/index.html +146 -0
  95. package/coverage/src/config/plugins/registry.ts.html +316 -0
  96. package/coverage/src/config/plugins/types.ts.html +127 -0
  97. package/coverage/src/config/resolution.ts.html +391 -0
  98. package/coverage/src/config/rules.ts.html +295 -0
  99. package/coverage/src/config/schema-gen.ts.html +430 -0
  100. package/coverage/src/config/types.ts.html +532 -0
  101. package/coverage/src/config/used-class-members.ts.html +244 -0
  102. package/coverage/src/config/validate.ts.html +409 -0
  103. package/coverage/src/config/workspace.ts.html +496 -0
  104. package/coverage/src/coverage/cloud-client.ts.html +418 -0
  105. package/coverage/src/coverage/index.html +146 -0
  106. package/coverage/src/coverage/upload-inventory.ts.html +337 -0
  107. package/coverage/src/coverage/upload-source-maps.ts.html +376 -0
  108. package/coverage/src/discover/entry-points.ts.html +238 -0
  109. package/coverage/src/discover/index.html +131 -0
  110. package/coverage/src/discover/infrastructure-entries.ts.html +610 -0
  111. package/coverage/src/duplicates/detect/concatenation.ts.html +196 -0
  112. package/coverage/src/duplicates/detect/extraction.ts.html +406 -0
  113. package/coverage/src/duplicates/detect/filtering.ts.html +421 -0
  114. package/coverage/src/duplicates/detect/index.html +206 -0
  115. package/coverage/src/duplicates/detect/lcp.ts.html +166 -0
  116. package/coverage/src/duplicates/detect/ranking.ts.html +133 -0
  117. package/coverage/src/duplicates/detect/statistics.ts.html +292 -0
  118. package/coverage/src/duplicates/detect/suffix-array.ts.html +349 -0
  119. package/coverage/src/duplicates/families.ts.html +370 -0
  120. package/coverage/src/duplicates/index.html +161 -0
  121. package/coverage/src/duplicates/normalize.ts.html +259 -0
  122. package/coverage/src/duplicates/shingle-filter.ts.html +196 -0
  123. package/coverage/src/duplicates/token-types.ts.html +271 -0
  124. package/coverage/src/duplicates/tokenize/index.html +116 -0
  125. package/coverage/src/duplicates/tokenize/index.ts.html +397 -0
  126. package/coverage/src/error/fallow-error.ts.html +367 -0
  127. package/coverage/src/error/index.html +116 -0
  128. package/coverage/src/error.ts.html +226 -0
  129. package/coverage/src/export/adjacency-matrix.ts.html +466 -0
  130. package/coverage/src/export/analysis-json.ts.html +346 -0
  131. package/coverage/src/export/badge.ts.html +400 -0
  132. package/coverage/src/export/canvas.ts.html +211 -0
  133. package/coverage/src/export/codeclimate.ts.html +688 -0
  134. package/coverage/src/export/compact-health.ts.html +442 -0
  135. package/coverage/src/export/compact.ts.html +334 -0
  136. package/coverage/src/export/csv.ts.html +184 -0
  137. package/coverage/src/export/cypher.ts.html +184 -0
  138. package/coverage/src/export/dot.ts.html +241 -0
  139. package/coverage/src/export/gexf.ts.html +262 -0
  140. package/coverage/src/export/graphml.ts.html +235 -0
  141. package/coverage/src/export/html.ts.html +1729 -0
  142. package/coverage/src/export/index.html +401 -0
  143. package/coverage/src/export/index.ts.html +112 -0
  144. package/coverage/src/export/json.ts.html +193 -0
  145. package/coverage/src/export/markdown.ts.html +955 -0
  146. package/coverage/src/export/mermaid.ts.html +385 -0
  147. package/coverage/src/export/obsidian.ts.html +217 -0
  148. package/coverage/src/export/sarif.ts.html +820 -0
  149. package/coverage/src/export/svg.ts.html +289 -0
  150. package/coverage/src/fix/deps.ts.html +295 -0
  151. package/coverage/src/fix/enum-members.ts.html +394 -0
  152. package/coverage/src/fix/export-surgery.ts.html +676 -0
  153. package/coverage/src/fix/exports.ts.html +364 -0
  154. package/coverage/src/fix/index.html +176 -0
  155. package/coverage/src/fix/orchestrator.ts.html +286 -0
  156. package/coverage/src/graph/analyzer.ts.html +292 -0
  157. package/coverage/src/graph/author-analytics.ts.html +736 -0
  158. package/coverage/src/graph/baseline.ts.html +1381 -0
  159. package/coverage/src/graph/clone-families.ts.html +481 -0
  160. package/coverage/src/graph/codeowners-extended.ts.html +427 -0
  161. package/coverage/src/graph/codeowners-gitlab.ts.html +535 -0
  162. package/coverage/src/graph/codeowners.ts.html +736 -0
  163. package/coverage/src/graph/complexity.ts.html +685 -0
  164. package/coverage/src/graph/cross-reference-findings.ts.html +340 -0
  165. package/coverage/src/graph/cross-reference.ts.html +502 -0
  166. package/coverage/src/graph/cycle-detection.ts.html +1018 -0
  167. package/coverage/src/graph/cycles.ts.html +751 -0
  168. package/coverage/src/graph/dead-code.ts.html +469 -0
  169. package/coverage/src/graph/dependency-closure.ts.html +463 -0
  170. package/coverage/src/graph/dfs.ts.html +439 -0
  171. package/coverage/src/graph/diff.ts.html +361 -0
  172. package/coverage/src/graph/duplication-stats.ts.html +322 -0
  173. package/coverage/src/graph/edge-filter.ts.html +436 -0
  174. package/coverage/src/graph/explain.ts.html +484 -0
  175. package/coverage/src/graph/external-style-usage.ts.html +328 -0
  176. package/coverage/src/graph/health-score.ts.html +622 -0
  177. package/coverage/src/graph/hotspots.ts.html +742 -0
  178. package/coverage/src/graph/import-chain.ts.html +529 -0
  179. package/coverage/src/graph/index.html +746 -0
  180. package/coverage/src/graph/loader.ts.html +217 -0
  181. package/coverage/src/graph/maintainability.ts.html +553 -0
  182. package/coverage/src/graph/merge.ts.html +607 -0
  183. package/coverage/src/graph/mirrored-dirs.ts.html +691 -0
  184. package/coverage/src/graph/narrowing.ts.html +361 -0
  185. package/coverage/src/graph/node-search.ts.html +688 -0
  186. package/coverage/src/graph/node-types.ts.html +286 -0
  187. package/coverage/src/graph/normalize-id.ts.html +499 -0
  188. package/coverage/src/graph/pagerank.ts.html +580 -0
  189. package/coverage/src/graph/prune.ts.html +370 -0
  190. package/coverage/src/graph/re-exports/index.html +116 -0
  191. package/coverage/src/graph/re-exports/propagate.ts.html +370 -0
  192. package/coverage/src/graph/reachability.ts.html +382 -0
  193. package/coverage/src/graph/regex-search.ts.html +781 -0
  194. package/coverage/src/graph/regression.ts.html +682 -0
  195. package/coverage/src/graph/resolve/discover-types.ts.html +220 -0
  196. package/coverage/src/graph/resolve/dynamic-imports.ts.html +391 -0
  197. package/coverage/src/graph/resolve/fallbacks.ts.html +322 -0
  198. package/coverage/src/graph/resolve/index.html +281 -0
  199. package/coverage/src/graph/resolve/index.ts.html +289 -0
  200. package/coverage/src/graph/resolve/path-info.ts.html +208 -0
  201. package/coverage/src/graph/resolve/re-exports.ts.html +127 -0
  202. package/coverage/src/graph/resolve/react-native.ts.html +166 -0
  203. package/coverage/src/graph/resolve/require-imports.ts.html +139 -0
  204. package/coverage/src/graph/resolve/specifier.ts.html +445 -0
  205. package/coverage/src/graph/resolve/static-imports.ts.html +127 -0
  206. package/coverage/src/graph/resolve/types.ts.html +409 -0
  207. package/coverage/src/graph/resolve/upgrades.ts.html +181 -0
  208. package/coverage/src/graph/ripple-impact.ts.html +478 -0
  209. package/coverage/src/graph/risk-profile.ts.html +622 -0
  210. package/coverage/src/graph/statistics.ts.html +580 -0
  211. package/coverage/src/graph/stats.ts.html +556 -0
  212. package/coverage/src/graph/subgraph.ts.html +571 -0
  213. package/coverage/src/graph/topo-sort.ts.html +598 -0
  214. package/coverage/src/graph/wcc.ts.html +646 -0
  215. package/coverage/src/groups/contract-bridge.ts.html +394 -0
  216. package/coverage/src/groups/contract-registry.ts.html +874 -0
  217. package/coverage/src/groups/group-config.ts.html +409 -0
  218. package/coverage/src/groups/group-search.ts.html +502 -0
  219. package/coverage/src/groups/group-sync.ts.html +331 -0
  220. package/coverage/src/groups/grpc-extractor.ts.html +277 -0
  221. package/coverage/src/groups/index.html +221 -0
  222. package/coverage/src/groups/service-boundary.ts.html +442 -0
  223. package/coverage/src/groups/topic-extractor.ts.html +355 -0
  224. package/coverage/src/health/analysis-counts-snapshot.ts.html +256 -0
  225. package/coverage/src/health/analysis-counts.ts.html +295 -0
  226. package/coverage/src/health/complexity-findings.ts.html +430 -0
  227. package/coverage/src/health/distribution-thresholds.ts.html +247 -0
  228. package/coverage/src/health/grouping.ts.html +499 -0
  229. package/coverage/src/health/health-grouping.ts.html +343 -0
  230. package/coverage/src/health/health-report-types.ts.html +580 -0
  231. package/coverage/src/health/health-report.ts.html +328 -0
  232. package/coverage/src/health/health-score.ts.html +280 -0
  233. package/coverage/src/health/hotspot-utils.ts.html +250 -0
  234. package/coverage/src/health/hotspots.ts.html +397 -0
  235. package/coverage/src/health/index.html +551 -0
  236. package/coverage/src/health/large-functions.ts.html +187 -0
  237. package/coverage/src/health/ownership-metrics.ts.html +268 -0
  238. package/coverage/src/health/ownership-risk.ts.html +379 -0
  239. package/coverage/src/health/ownership.ts.html +607 -0
  240. package/coverage/src/health/quality-gate.ts.html +256 -0
  241. package/coverage/src/health/risk-profile.ts.html +202 -0
  242. package/coverage/src/health/runtime-coverage-report.ts.html +388 -0
  243. package/coverage/src/health/runtime-coverage.ts.html +298 -0
  244. package/coverage/src/health/scores.ts.html +301 -0
  245. package/coverage/src/health/scoring-types.ts.html +229 -0
  246. package/coverage/src/health/target-thresholds.ts.html +361 -0
  247. package/coverage/src/health/target-types.ts.html +247 -0
  248. package/coverage/src/health/targets.ts.html +538 -0
  249. package/coverage/src/health/timings.ts.html +343 -0
  250. package/coverage/src/health/trend-types.ts.html +256 -0
  251. package/coverage/src/health/trends.ts.html +343 -0
  252. package/coverage/src/health/vital-signs-compute.ts.html +409 -0
  253. package/coverage/src/health/vital-signs-snapshot.ts.html +301 -0
  254. package/coverage/src/health/vital-signs.ts.html +388 -0
  255. package/coverage/src/index.html +191 -0
  256. package/coverage/src/index.ts.html +418 -0
  257. package/coverage/src/ingest/git-clone.ts.html +823 -0
  258. package/coverage/src/ingest/index.html +161 -0
  259. package/coverage/src/ingest/query-memory.ts.html +481 -0
  260. package/coverage/src/ingest/transcribe.ts.html +847 -0
  261. package/coverage/src/ingest/url-ingest.ts.html +346 -0
  262. package/coverage/src/init/agent-hooks.ts.html +343 -0
  263. package/coverage/src/init/git-hooks.ts.html +298 -0
  264. package/coverage/src/init/index.html +146 -0
  265. package/coverage/src/init/project-detection.ts.html +400 -0
  266. package/coverage/src/license/index.html +116 -0
  267. package/coverage/src/license/manager.ts.html +445 -0
  268. package/coverage/src/lsp/code-actions.ts.html +466 -0
  269. package/coverage/src/lsp/code-lens.ts.html +253 -0
  270. package/coverage/src/lsp/diagnostics-ext.ts.html +535 -0
  271. package/coverage/src/lsp/diagnostics-push.ts.html +394 -0
  272. package/coverage/src/lsp/diagnostics.ts.html +379 -0
  273. package/coverage/src/lsp/hover.ts.html +277 -0
  274. package/coverage/src/lsp/index.html +206 -0
  275. package/coverage/src/lsp/server.ts.html +847 -0
  276. package/coverage/src/mcp/index.html +146 -0
  277. package/coverage/src/mcp/params.ts.html +688 -0
  278. package/coverage/src/mcp/resources.ts.html +457 -0
  279. package/coverage/src/mcp/tool-builders.ts.html +694 -0
  280. package/coverage/src/mcp-resources/communities-resource.ts.html +301 -0
  281. package/coverage/src/mcp-resources/graph-resource.ts.html +127 -0
  282. package/coverage/src/mcp-resources/index.html +251 -0
  283. package/coverage/src/mcp-resources/index.ts.html +112 -0
  284. package/coverage/src/mcp-resources/named-cluster-resource.ts.html +190 -0
  285. package/coverage/src/mcp-resources/named-process-resource.ts.html +163 -0
  286. package/coverage/src/mcp-resources/processes-resource.ts.html +286 -0
  287. package/coverage/src/mcp-resources/repo-context-resource.ts.html +193 -0
  288. package/coverage/src/mcp-resources/repos-resource.ts.html +148 -0
  289. package/coverage/src/mcp-resources/schema-resource.ts.html +223 -0
  290. package/coverage/src/mcp-resources/wiki-resource.ts.html +154 -0
  291. package/coverage/src/mcp-tools/api-impact.ts.html +628 -0
  292. package/coverage/src/mcp-tools/context.ts.html +418 -0
  293. package/coverage/src/mcp-tools/cypher.ts.html +172 -0
  294. package/coverage/src/mcp-tools/detect-changes.ts.html +433 -0
  295. package/coverage/src/mcp-tools/explain.ts.html +280 -0
  296. package/coverage/src/mcp-tools/graph-query.ts.html +469 -0
  297. package/coverage/src/mcp-tools/group-list.ts.html +349 -0
  298. package/coverage/src/mcp-tools/group-query.ts.html +163 -0
  299. package/coverage/src/mcp-tools/group-sync.ts.html +181 -0
  300. package/coverage/src/mcp-tools/impact.ts.html +691 -0
  301. package/coverage/src/mcp-tools/index.html +431 -0
  302. package/coverage/src/mcp-tools/index.ts.html +148 -0
  303. package/coverage/src/mcp-tools/list-repos.ts.html +199 -0
  304. package/coverage/src/mcp-tools/neighbors.ts.html +325 -0
  305. package/coverage/src/mcp-tools/query.ts.html +343 -0
  306. package/coverage/src/mcp-tools/rename.ts.html +439 -0
  307. package/coverage/src/mcp-tools/route-map.ts.html +379 -0
  308. package/coverage/src/mcp-tools/serve.ts.html +208 -0
  309. package/coverage/src/mcp-tools/shape-check.ts.html +631 -0
  310. package/coverage/src/mcp-tools/staleness.ts.html +124 -0
  311. package/coverage/src/mcp-tools/tool-map.ts.html +283 -0
  312. package/coverage/src/mcp-tools/wiki-build.ts.html +196 -0
  313. package/coverage/src/mcp-tools/wiki.ts.html +169 -0
  314. package/coverage/src/migrate/index.html +161 -0
  315. package/coverage/src/migrate/jscpd.ts.html +319 -0
  316. package/coverage/src/migrate/jsonc-gen.ts.html +199 -0
  317. package/coverage/src/migrate/knip.ts.html +463 -0
  318. package/coverage/src/migrate/toml-gen.ts.html +229 -0
  319. package/coverage/src/parsers/c.ts.html +178 -0
  320. package/coverage/src/parsers/cpp.ts.html +172 -0
  321. package/coverage/src/parsers/csharp.ts.html +214 -0
  322. package/coverage/src/parsers/dart.ts.html +202 -0
  323. package/coverage/src/parsers/extractor.ts.html +691 -0
  324. package/coverage/src/parsers/go.ts.html +166 -0
  325. package/coverage/src/parsers/index.html +386 -0
  326. package/coverage/src/parsers/java.ts.html +166 -0
  327. package/coverage/src/parsers/kotlin.ts.html +193 -0
  328. package/coverage/src/parsers/language-config.ts.html +169 -0
  329. package/coverage/src/parsers/language-parsers.ts.html +445 -0
  330. package/coverage/src/parsers/loader.ts.html +532 -0
  331. package/coverage/src/parsers/named-bindings.ts.html +274 -0
  332. package/coverage/src/parsers/php.ts.html +196 -0
  333. package/coverage/src/parsers/python.ts.html +163 -0
  334. package/coverage/src/parsers/ruby.ts.html +202 -0
  335. package/coverage/src/parsers/rust.ts.html +160 -0
  336. package/coverage/src/parsers/swift.ts.html +169 -0
  337. package/coverage/src/parsers/typescript.ts.html +208 -0
  338. package/coverage/src/parsers/vue.ts.html +322 -0
  339. package/coverage/src/pipeline/cluster-only.ts.html +277 -0
  340. package/coverage/src/pipeline/effort.ts.html +235 -0
  341. package/coverage/src/pipeline/index.html +191 -0
  342. package/coverage/src/pipeline/orchestrator.ts.html +844 -0
  343. package/coverage/src/pipeline/phases/boundary.ts.html +538 -0
  344. package/coverage/src/pipeline/phases/bridge-adapters/electron-ipc.ts.html +358 -0
  345. package/coverage/src/pipeline/phases/bridge-adapters/index.html +176 -0
  346. package/coverage/src/pipeline/phases/bridge-adapters/registry.ts.html +127 -0
  347. package/coverage/src/pipeline/phases/bridge-adapters/tauri.ts.html +394 -0
  348. package/coverage/src/pipeline/phases/bridge-adapters/types.ts.html +178 -0
  349. package/coverage/src/pipeline/phases/bridge-adapters/wails.ts.html +184 -0
  350. package/coverage/src/pipeline/phases/bridge-resolver.ts.html +316 -0
  351. package/coverage/src/pipeline/phases/call-site-extractors.ts.html +592 -0
  352. package/coverage/src/pipeline/phases/communities.ts.html +634 -0
  353. package/coverage/src/pipeline/phases/contextual-proximity.ts.html +349 -0
  354. package/coverage/src/pipeline/phases/cross-file.ts.html +433 -0
  355. package/coverage/src/pipeline/phases/docs-parse.ts.html +1006 -0
  356. package/coverage/src/pipeline/phases/evidence.ts.html +112 -0
  357. package/coverage/src/pipeline/phases/field-access.ts.html +232 -0
  358. package/coverage/src/pipeline/phases/framework-detect.ts.html +412 -0
  359. package/coverage/src/pipeline/phases/god-nodes.ts.html +574 -0
  360. package/coverage/src/pipeline/phases/import-resolver.ts.html +427 -0
  361. package/coverage/src/pipeline/phases/index.html +626 -0
  362. package/coverage/src/pipeline/phases/leiden.ts.html +316 -0
  363. package/coverage/src/pipeline/phases/llm-extract.ts.html +577 -0
  364. package/coverage/src/pipeline/phases/markdown.ts.html +448 -0
  365. package/coverage/src/pipeline/phases/middleware-extractor.ts.html +466 -0
  366. package/coverage/src/pipeline/phases/module-resolution.ts.html +967 -0
  367. package/coverage/src/pipeline/phases/mro.ts.html +253 -0
  368. package/coverage/src/pipeline/phases/orm.ts.html +1594 -0
  369. package/coverage/src/pipeline/phases/parse.ts.html +751 -0
  370. package/coverage/src/pipeline/phases/pdf-parse.ts.html +484 -0
  371. package/coverage/src/pipeline/phases/processes.ts.html +832 -0
  372. package/coverage/src/pipeline/phases/re-export-propagation.ts.html +565 -0
  373. package/coverage/src/pipeline/phases/reachability.ts.html +553 -0
  374. package/coverage/src/pipeline/phases/routes.ts.html +1135 -0
  375. package/coverage/src/pipeline/phases/scan.ts.html +484 -0
  376. package/coverage/src/pipeline/phases/scope-resolution.ts.html +1147 -0
  377. package/coverage/src/pipeline/phases/structure.ts.html +289 -0
  378. package/coverage/src/pipeline/phases/suggest.ts.html +361 -0
  379. package/coverage/src/pipeline/phases/surprises.ts.html +334 -0
  380. package/coverage/src/pipeline/phases/tools.ts.html +625 -0
  381. package/coverage/src/pipeline/phases/variables-phase.ts.html +196 -0
  382. package/coverage/src/pipeline/phases/variables.ts.html +286 -0
  383. package/coverage/src/pipeline/phases/wildcard-phase.ts.html +235 -0
  384. package/coverage/src/pipeline/phases/wildcard-synthesis.ts.html +727 -0
  385. package/coverage/src/pipeline/progress.ts.html +259 -0
  386. package/coverage/src/pipeline/runner.ts.html +469 -0
  387. package/coverage/src/pipeline/types.ts.html +208 -0
  388. package/coverage/src/query/cypher-parser.ts.html +1435 -0
  389. package/coverage/src/query/index.html +116 -0
  390. package/coverage/src/registry/index.html +116 -0
  391. package/coverage/src/registry/repo-registry.ts.html +460 -0
  392. package/coverage/src/regression/baseline-deltas.ts.html +730 -0
  393. package/coverage/src/regression/baseline.ts.html +313 -0
  394. package/coverage/src/regression/counts.ts.html +346 -0
  395. package/coverage/src/regression/index.html +176 -0
  396. package/coverage/src/regression/outcome.ts.html +319 -0
  397. package/coverage/src/regression/tolerance.ts.html +190 -0
  398. package/coverage/src/report/attributed-duplication.ts.html +421 -0
  399. package/coverage/src/report/badge-svg.ts.html +385 -0
  400. package/coverage/src/report/cross-ref-human.ts.html +235 -0
  401. package/coverage/src/report/duplication-grouping.ts.html +307 -0
  402. package/coverage/src/report/grouping.ts.html +496 -0
  403. package/coverage/src/report/human-check.ts.html +958 -0
  404. package/coverage/src/report/human-dupes.ts.html +511 -0
  405. package/coverage/src/report/human-health.ts.html +670 -0
  406. package/coverage/src/report/human.ts.html +445 -0
  407. package/coverage/src/report/index.html +341 -0
  408. package/coverage/src/report/json-actions.ts.html +358 -0
  409. package/coverage/src/report/json-builders.ts.html +295 -0
  410. package/coverage/src/report/json-schema.ts.html +310 -0
  411. package/coverage/src/report/number-format.ts.html +358 -0
  412. package/coverage/src/report/output-grouped.ts.html +391 -0
  413. package/coverage/src/report/pipeline-perf.ts.html +253 -0
  414. package/coverage/src/report/trace-human.ts.html +466 -0
  415. package/coverage/src/reporting/graph-report.ts.html +1378 -0
  416. package/coverage/src/reporting/index.html +116 -0
  417. package/coverage/src/results/fallow-results.ts.html +541 -0
  418. package/coverage/src/results/index.html +131 -0
  419. package/coverage/src/results/types.ts.html +532 -0
  420. package/coverage/src/scope-resolution/evidence-weights.ts.html +208 -0
  421. package/coverage/src/scope-resolution/index.html +116 -0
  422. package/coverage/src/search/ast-chunker.ts.html +703 -0
  423. package/coverage/src/search/diacritic.ts.html +106 -0
  424. package/coverage/src/search/hybrid-query.ts.html +280 -0
  425. package/coverage/src/search/index.html +161 -0
  426. package/coverage/src/search/rrf.ts.html +238 -0
  427. package/coverage/src/security/index.html +131 -0
  428. package/coverage/src/security/safe-fetch.ts.html +424 -0
  429. package/coverage/src/security/sensitive-files.ts.html +157 -0
  430. package/coverage/src/skills/index.html +116 -0
  431. package/coverage/src/skills/platform-skills.ts.html +784 -0
  432. package/coverage/src/staleness/git-staleness.ts.html +283 -0
  433. package/coverage/src/staleness/index.html +116 -0
  434. package/coverage/src/storage/db.ts.html +415 -0
  435. package/coverage/src/storage/edge-store.ts.html +400 -0
  436. package/coverage/src/storage/file-cache.ts.html +319 -0
  437. package/coverage/src/storage/fts-store.ts.html +1240 -0
  438. package/coverage/src/storage/index.html +221 -0
  439. package/coverage/src/storage/node-store.ts.html +712 -0
  440. package/coverage/src/storage/schema.ts.html +598 -0
  441. package/coverage/src/storage/suppressions.ts.html +520 -0
  442. package/coverage/src/storage/unlinked-refs.ts.html +436 -0
  443. package/coverage/src/types.ts.html +676 -0
  444. package/coverage/src/validation/extraction-validator.ts.html +247 -0
  445. package/coverage/src/validation/index.html +116 -0
  446. package/coverage/src/watch/index.html +116 -0
  447. package/coverage/src/watch/watcher.ts.html +499 -0
  448. package/coverage/src/web/analyze-api.ts.html +523 -0
  449. package/coverage/src/web/api.ts.html +1837 -0
  450. package/coverage/src/web/async-jobs.ts.html +412 -0
  451. package/coverage/src/web/index.html +191 -0
  452. package/coverage/src/web/mcp-http.ts.html +766 -0
  453. package/coverage/src/web/react-ui.ts.html +319 -0
  454. package/coverage/src/web/server.ts.html +355 -0
  455. package/coverage/src/wiki/gist-publisher.ts.html +313 -0
  456. package/coverage/src/wiki/index.html +176 -0
  457. package/coverage/src/wiki/prompt-builder.ts.html +190 -0
  458. package/coverage/src/wiki/providers.ts.html +487 -0
  459. package/coverage/src/wiki/wiki-generator.ts.html +736 -0
  460. package/coverage/src/wiki/wiki-store.ts.html +232 -0
  461. package/dist/src/cli/eval-server.d.ts.map +1 -1
  462. package/dist/src/cli/eval-server.js +8 -1
  463. package/dist/src/cli/eval-server.js.map +1 -1
  464. package/dist/src/cli/skill-gen.js.map +1 -1
  465. package/dist/src/graph/regex-search.d.ts.map +1 -1
  466. package/dist/src/graph/regex-search.js +13 -13
  467. package/dist/src/graph/regex-search.js.map +1 -1
  468. package/dist/src/graph/statistics.d.ts +0 -4
  469. package/dist/src/graph/statistics.d.ts.map +1 -1
  470. package/dist/src/graph/statistics.js +0 -7
  471. package/dist/src/graph/statistics.js.map +1 -1
  472. package/dist/src/pipeline/phases/call-site-extractors.d.ts +8 -0
  473. package/dist/src/pipeline/phases/call-site-extractors.d.ts.map +1 -1
  474. package/dist/src/pipeline/phases/call-site-extractors.js +9 -9
  475. package/dist/src/pipeline/phases/call-site-extractors.js.map +1 -1
  476. package/dist/src/pipeline/phases/module-resolution.js +2 -2
  477. package/dist/src/pipeline/phases/module-resolution.js.map +1 -1
  478. package/dist/src/pipeline/phases/scope-resolution.d.ts.map +1 -1
  479. package/dist/src/pipeline/phases/scope-resolution.js +76 -1
  480. package/dist/src/pipeline/phases/scope-resolution.js.map +1 -1
  481. package/dist/src/registry/repo-registry.d.ts.map +1 -1
  482. package/dist/src/registry/repo-registry.js +1 -2
  483. package/dist/src/registry/repo-registry.js.map +1 -1
  484. package/dist/tsconfig.tsbuildinfo +1 -1
  485. package/package.json +4 -3
  486. package/src/cli/eval-server.ts +8 -1
  487. package/src/cli/skill-gen.ts +16 -16
  488. package/src/graph/regex-search.ts +13 -14
  489. package/src/graph/statistics.ts +0 -8
  490. package/src/pipeline/phases/call-site-extractors.ts +17 -9
  491. package/src/pipeline/phases/module-resolution.ts +2 -2
  492. package/src/pipeline/phases/scope-resolution.ts +89 -1
  493. package/src/registry/repo-registry.ts +1 -2
  494. package/vitest.config.ts +7 -0
  495. package/src/analysis/cycles.ts +0 -268
  496. package/src/analysis/trace.ts +0 -300
  497. package/src/analysis/worker-pool.ts +0 -81
  498. package/src/graph/clone-detector.ts +0 -163
  499. package/src/graph/shingle-filter.ts +0 -149
  500. package/src/watch/watch-runner.ts +0 -64
@@ -0,0 +1,691 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for src/graph/mirrored-dirs.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/graph</a> mirrored-dirs.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">0% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>0/103</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">0% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/46</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">0% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>0/8</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">0% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>0/82</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line low'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
269
+ <span class="cline-any cline-neutral">&nbsp;</span>
270
+ <span class="cline-any cline-neutral">&nbsp;</span>
271
+ <span class="cline-any cline-neutral">&nbsp;</span>
272
+ <span class="cline-any cline-neutral">&nbsp;</span>
273
+ <span class="cline-any cline-neutral">&nbsp;</span>
274
+ <span class="cline-any cline-neutral">&nbsp;</span>
275
+ <span class="cline-any cline-neutral">&nbsp;</span>
276
+ <span class="cline-any cline-neutral">&nbsp;</span>
277
+ <span class="cline-any cline-neutral">&nbsp;</span>
278
+ <span class="cline-any cline-neutral">&nbsp;</span>
279
+ <span class="cline-any cline-neutral">&nbsp;</span>
280
+ <span class="cline-any cline-neutral">&nbsp;</span>
281
+ <span class="cline-any cline-neutral">&nbsp;</span>
282
+ <span class="cline-any cline-neutral">&nbsp;</span>
283
+ <span class="cline-any cline-neutral">&nbsp;</span>
284
+ <span class="cline-any cline-neutral">&nbsp;</span>
285
+ <span class="cline-any cline-neutral">&nbsp;</span>
286
+ <span class="cline-any cline-neutral">&nbsp;</span>
287
+ <span class="cline-any cline-neutral">&nbsp;</span>
288
+ <span class="cline-any cline-neutral">&nbsp;</span>
289
+ <span class="cline-any cline-neutral">&nbsp;</span>
290
+ <span class="cline-any cline-neutral">&nbsp;</span>
291
+ <span class="cline-any cline-neutral">&nbsp;</span>
292
+ <span class="cline-any cline-neutral">&nbsp;</span>
293
+ <span class="cline-any cline-neutral">&nbsp;</span>
294
+ <span class="cline-any cline-no">&nbsp;</span>
295
+ <span class="cline-any cline-neutral">&nbsp;</span>
296
+ <span class="cline-any cline-neutral">&nbsp;</span>
297
+ <span class="cline-any cline-neutral">&nbsp;</span>
298
+ <span class="cline-any cline-neutral">&nbsp;</span>
299
+ <span class="cline-any cline-no">&nbsp;</span>
300
+ <span class="cline-any cline-no">&nbsp;</span>
301
+ <span class="cline-any cline-no">&nbsp;</span>
302
+ <span class="cline-any cline-no">&nbsp;</span>
303
+ <span class="cline-any cline-no">&nbsp;</span>
304
+ <span class="cline-any cline-no">&nbsp;</span>
305
+ <span class="cline-any cline-no">&nbsp;</span>
306
+ <span class="cline-any cline-no">&nbsp;</span>
307
+ <span class="cline-any cline-neutral">&nbsp;</span>
308
+ <span class="cline-any cline-neutral">&nbsp;</span>
309
+ <span class="cline-any cline-no">&nbsp;</span>
310
+ <span class="cline-any cline-no">&nbsp;</span>
311
+ <span class="cline-any cline-neutral">&nbsp;</span>
312
+ <span class="cline-any cline-neutral">&nbsp;</span>
313
+ <span class="cline-any cline-no">&nbsp;</span>
314
+ <span class="cline-any cline-no">&nbsp;</span>
315
+ <span class="cline-any cline-no">&nbsp;</span>
316
+ <span class="cline-any cline-no">&nbsp;</span>
317
+ <span class="cline-any cline-no">&nbsp;</span>
318
+ <span class="cline-any cline-no">&nbsp;</span>
319
+ <span class="cline-any cline-neutral">&nbsp;</span>
320
+ <span class="cline-any cline-neutral">&nbsp;</span>
321
+ <span class="cline-any cline-no">&nbsp;</span>
322
+ <span class="cline-any cline-no">&nbsp;</span>
323
+ <span class="cline-any cline-no">&nbsp;</span>
324
+ <span class="cline-any cline-neutral">&nbsp;</span>
325
+ <span class="cline-any cline-neutral">&nbsp;</span>
326
+ <span class="cline-any cline-neutral">&nbsp;</span>
327
+ <span class="cline-any cline-neutral">&nbsp;</span>
328
+ <span class="cline-any cline-no">&nbsp;</span>
329
+ <span class="cline-any cline-neutral">&nbsp;</span>
330
+ <span class="cline-any cline-neutral">&nbsp;</span>
331
+ <span class="cline-any cline-no">&nbsp;</span>
332
+ <span class="cline-any cline-no">&nbsp;</span>
333
+ <span class="cline-any cline-no">&nbsp;</span>
334
+ <span class="cline-any cline-neutral">&nbsp;</span>
335
+ <span class="cline-any cline-no">&nbsp;</span>
336
+ <span class="cline-any cline-no">&nbsp;</span>
337
+ <span class="cline-any cline-no">&nbsp;</span>
338
+ <span class="cline-any cline-neutral">&nbsp;</span>
339
+ <span class="cline-any cline-no">&nbsp;</span>
340
+ <span class="cline-any cline-no">&nbsp;</span>
341
+ <span class="cline-any cline-neutral">&nbsp;</span>
342
+ <span class="cline-any cline-neutral">&nbsp;</span>
343
+ <span class="cline-any cline-neutral">&nbsp;</span>
344
+ <span class="cline-any cline-neutral">&nbsp;</span>
345
+ <span class="cline-any cline-neutral">&nbsp;</span>
346
+ <span class="cline-any cline-neutral">&nbsp;</span>
347
+ <span class="cline-any cline-neutral">&nbsp;</span>
348
+ <span class="cline-any cline-neutral">&nbsp;</span>
349
+ <span class="cline-any cline-neutral">&nbsp;</span>
350
+ <span class="cline-any cline-neutral">&nbsp;</span>
351
+ <span class="cline-any cline-neutral">&nbsp;</span>
352
+ <span class="cline-any cline-neutral">&nbsp;</span>
353
+ <span class="cline-any cline-no">&nbsp;</span>
354
+ <span class="cline-any cline-neutral">&nbsp;</span>
355
+ <span class="cline-any cline-no">&nbsp;</span>
356
+ <span class="cline-any cline-neutral">&nbsp;</span>
357
+ <span class="cline-any cline-neutral">&nbsp;</span>
358
+ <span class="cline-any cline-neutral">&nbsp;</span>
359
+ <span class="cline-any cline-neutral">&nbsp;</span>
360
+ <span class="cline-any cline-neutral">&nbsp;</span>
361
+ <span class="cline-any cline-neutral">&nbsp;</span>
362
+ <span class="cline-any cline-neutral">&nbsp;</span>
363
+ <span class="cline-any cline-neutral">&nbsp;</span>
364
+ <span class="cline-any cline-neutral">&nbsp;</span>
365
+ <span class="cline-any cline-neutral">&nbsp;</span>
366
+ <span class="cline-any cline-neutral">&nbsp;</span>
367
+ <span class="cline-any cline-neutral">&nbsp;</span>
368
+ <span class="cline-any cline-neutral">&nbsp;</span>
369
+ <span class="cline-any cline-neutral">&nbsp;</span>
370
+ <span class="cline-any cline-no">&nbsp;</span>
371
+ <span class="cline-any cline-neutral">&nbsp;</span>
372
+ <span class="cline-any cline-neutral">&nbsp;</span>
373
+ <span class="cline-any cline-no">&nbsp;</span>
374
+ <span class="cline-any cline-no">&nbsp;</span>
375
+ <span class="cline-any cline-neutral">&nbsp;</span>
376
+ <span class="cline-any cline-neutral">&nbsp;</span>
377
+ <span class="cline-any cline-no">&nbsp;</span>
378
+ <span class="cline-any cline-no">&nbsp;</span>
379
+ <span class="cline-any cline-neutral">&nbsp;</span>
380
+ <span class="cline-any cline-neutral">&nbsp;</span>
381
+ <span class="cline-any cline-neutral">&nbsp;</span>
382
+ <span class="cline-any cline-no">&nbsp;</span>
383
+ <span class="cline-any cline-no">&nbsp;</span>
384
+ <span class="cline-any cline-neutral">&nbsp;</span>
385
+ <span class="cline-any cline-neutral">&nbsp;</span>
386
+ <span class="cline-any cline-no">&nbsp;</span>
387
+ <span class="cline-any cline-no">&nbsp;</span>
388
+ <span class="cline-any cline-neutral">&nbsp;</span>
389
+ <span class="cline-any cline-no">&nbsp;</span>
390
+ <span class="cline-any cline-no">&nbsp;</span>
391
+ <span class="cline-any cline-no">&nbsp;</span>
392
+ <span class="cline-any cline-neutral">&nbsp;</span>
393
+ <span class="cline-any cline-no">&nbsp;</span>
394
+ <span class="cline-any cline-no">&nbsp;</span>
395
+ <span class="cline-any cline-neutral">&nbsp;</span>
396
+ <span class="cline-any cline-neutral">&nbsp;</span>
397
+ <span class="cline-any cline-neutral">&nbsp;</span>
398
+ <span class="cline-any cline-no">&nbsp;</span>
399
+ <span class="cline-any cline-neutral">&nbsp;</span>
400
+ <span class="cline-any cline-no">&nbsp;</span>
401
+ <span class="cline-any cline-no">&nbsp;</span>
402
+ <span class="cline-any cline-no">&nbsp;</span>
403
+ <span class="cline-any cline-no">&nbsp;</span>
404
+ <span class="cline-any cline-no">&nbsp;</span>
405
+ <span class="cline-any cline-no">&nbsp;</span>
406
+ <span class="cline-any cline-no">&nbsp;</span>
407
+ <span class="cline-any cline-no">&nbsp;</span>
408
+ <span class="cline-any cline-neutral">&nbsp;</span>
409
+ <span class="cline-any cline-no">&nbsp;</span>
410
+ <span class="cline-any cline-no">&nbsp;</span>
411
+ <span class="cline-any cline-no">&nbsp;</span>
412
+ <span class="cline-any cline-no">&nbsp;</span>
413
+ <span class="cline-any cline-no">&nbsp;</span>
414
+ <span class="cline-any cline-neutral">&nbsp;</span>
415
+ <span class="cline-any cline-neutral">&nbsp;</span>
416
+ <span class="cline-any cline-no">&nbsp;</span>
417
+ <span class="cline-any cline-neutral">&nbsp;</span>
418
+ <span class="cline-any cline-no">&nbsp;</span>
419
+ <span class="cline-any cline-no">&nbsp;</span>
420
+ <span class="cline-any cline-neutral">&nbsp;</span>
421
+ <span class="cline-any cline-no">&nbsp;</span>
422
+ <span class="cline-any cline-no">&nbsp;</span>
423
+ <span class="cline-any cline-no">&nbsp;</span>
424
+ <span class="cline-any cline-neutral">&nbsp;</span>
425
+ <span class="cline-any cline-no">&nbsp;</span>
426
+ <span class="cline-any cline-no">&nbsp;</span>
427
+ <span class="cline-any cline-no">&nbsp;</span>
428
+ <span class="cline-any cline-neutral">&nbsp;</span>
429
+ <span class="cline-any cline-no">&nbsp;</span>
430
+ <span class="cline-any cline-no">&nbsp;</span>
431
+ <span class="cline-any cline-neutral">&nbsp;</span>
432
+ <span class="cline-any cline-neutral">&nbsp;</span>
433
+ <span class="cline-any cline-neutral">&nbsp;</span>
434
+ <span class="cline-any cline-neutral">&nbsp;</span>
435
+ <span class="cline-any cline-neutral">&nbsp;</span>
436
+ <span class="cline-any cline-neutral">&nbsp;</span>
437
+ <span class="cline-any cline-neutral">&nbsp;</span>
438
+ <span class="cline-any cline-no">&nbsp;</span>
439
+ <span class="cline-any cline-no">&nbsp;</span>
440
+ <span class="cline-any cline-neutral">&nbsp;</span>
441
+ <span class="cline-any cline-neutral">&nbsp;</span>
442
+ <span class="cline-any cline-neutral">&nbsp;</span>
443
+ <span class="cline-any cline-neutral">&nbsp;</span>
444
+ <span class="cline-any cline-no">&nbsp;</span>
445
+ <span class="cline-any cline-neutral">&nbsp;</span>
446
+ <span class="cline-any cline-no">&nbsp;</span>
447
+ <span class="cline-any cline-no">&nbsp;</span>
448
+ <span class="cline-any cline-neutral">&nbsp;</span>
449
+ <span class="cline-any cline-no">&nbsp;</span>
450
+ <span class="cline-any cline-neutral">&nbsp;</span>
451
+ <span class="cline-any cline-neutral">&nbsp;</span>
452
+ <span class="cline-any cline-neutral">&nbsp;</span>
453
+ <span class="cline-any cline-neutral">&nbsp;</span>
454
+ <span class="cline-any cline-neutral">&nbsp;</span>
455
+ <span class="cline-any cline-neutral">&nbsp;</span>
456
+ <span class="cline-any cline-no">&nbsp;</span>
457
+ <span class="cline-any cline-no">&nbsp;</span>
458
+ <span class="cline-any cline-neutral">&nbsp;</span>
459
+ <span class="cline-any cline-no">&nbsp;</span>
460
+ <span class="cline-any cline-neutral">&nbsp;</span>
461
+ <span class="cline-any cline-neutral">&nbsp;</span>
462
+ <span class="cline-any cline-neutral">&nbsp;</span>
463
+ <span class="cline-any cline-no">&nbsp;</span>
464
+ <span class="cline-any cline-no">&nbsp;</span>
465
+ <span class="cline-any cline-neutral">&nbsp;</span>
466
+ <span class="cline-any cline-neutral">&nbsp;</span>
467
+ <span class="cline-any cline-neutral">&nbsp;</span>
468
+ <span class="cline-any cline-no">&nbsp;</span>
469
+ <span class="cline-any cline-neutral">&nbsp;</span>
470
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import type { MonographDb } from '../storage/db.js';
471
+ import type { CloneFamily } from '../graph/clone-families.js';
472
+ &nbsp;
473
+ export interface MirroredDirPair {
474
+ dirA: string;
475
+ dirB: string;
476
+ similarity: number; // 0-1, file name overlap ratio
477
+ sharedFileNames: string[]; // basenames that appear in both
478
+ uniqueToA: number;
479
+ uniqueToB: number;
480
+ }
481
+ &nbsp;
482
+ export interface MirroredDirsReport {
483
+ pairs: MirroredDirPair[];
484
+ totalDirsAnalyzed: number;
485
+ }
486
+ &nbsp;
487
+ /**
488
+ * Detect directory subtrees that are structural mirrors of each other.
489
+ * Uses Jaccard similarity of file basenames within each directory.
490
+ *
491
+ * @param db - monograph database
492
+ * @param minSimilarity - minimum Jaccard similarity threshold (default 0.7)
493
+ */
494
+ export function <span class="fstat-no" title="function not covered" >detectMirroredDirs(d</span>b: MonographDb, minSimilarity = <span class="branch-0 cbranch-no" title="branch not covered" >0.7): MirroredDirsReport {</span>
495
+ // Query all File nodes with a file_path
496
+ const rows = <span class="cstat-no" title="statement not covered" >db.prepare(</span>
497
+ `SELECT file_path FROM nodes WHERE label = 'File' AND file_path IS NOT NULL`,
498
+ ).all() as { file_path: string }[];
499
+ &nbsp;
500
+ // Build map: dirPath → Set&lt;basename&gt;
501
+ const dirMap = <span class="cstat-no" title="statement not covered" >new Map&lt;string, Set&lt;string&gt;&gt;();</span>
502
+ <span class="cstat-no" title="statement not covered" > for (const { file_path } of rows) {</span>
503
+ const lastSlash = <span class="cstat-no" title="statement not covered" >Math.max(file_path.lastIndexOf('/'), file_path.lastIndexOf('\\'));</span>
504
+ <span class="cstat-no" title="statement not covered" > if (lastSlash === -1) <span class="cstat-no" title="statement not covered" >continue;</span></span>
505
+ const dir = <span class="cstat-no" title="statement not covered" >file_path.slice(0, lastSlash);</span>
506
+ const base = <span class="cstat-no" title="statement not covered" >file_path.slice(lastSlash + 1);</span>
507
+ <span class="cstat-no" title="statement not covered" > if (!dirMap.has(dir)) <span class="cstat-no" title="statement not covered" >dirMap.set(dir, new Set());</span></span>
508
+ <span class="cstat-no" title="statement not covered" > dirMap.get(dir)!.add(base);</span>
509
+ }
510
+ &nbsp;
511
+ const dirs = <span class="cstat-no" title="statement not covered" >[...dirMap.keys()];</span>
512
+ const pairs: MirroredDirPair[] = <span class="cstat-no" title="statement not covered" >[];</span>
513
+ &nbsp;
514
+ // Compare each pair of directories
515
+ <span class="cstat-no" title="statement not covered" > for (let i = <span class="cstat-no" title="statement not covered" >0; i</span> &lt; dirs.length; i++) {</span>
516
+ <span class="cstat-no" title="statement not covered" > for (let j = <span class="cstat-no" title="statement not covered" >i + 1; j</span> &lt; dirs.length; j++) {</span>
517
+ const dirA = <span class="cstat-no" title="statement not covered" >dirs[i];</span>
518
+ const dirB = <span class="cstat-no" title="statement not covered" >dirs[j];</span>
519
+ const setA = <span class="cstat-no" title="statement not covered" >dirMap.get(dirA)!;</span>
520
+ const setB = <span class="cstat-no" title="statement not covered" >dirMap.get(dirB)!;</span>
521
+ &nbsp;
522
+ // Only compare directories that share a parent OR one is a suffix of the other
523
+ const parentA = <span class="cstat-no" title="statement not covered" >dirA.slice(0, Math.max(dirA.lastIndexOf('/'), dirA.lastIndexOf('\\')));</span>
524
+ const parentB = <span class="cstat-no" title="statement not covered" >dirB.slice(0, Math.max(dirB.lastIndexOf('/'), dirB.lastIndexOf('\\')));</span>
525
+ const relatedDirs = <span class="cstat-no" title="statement not covered" >parentA === parentB</span>
526
+ || dirA.endsWith(dirB)
527
+ || dirB.endsWith(dirA)
528
+ || dirA.includes(dirB)
529
+ || dirB.includes(dirA);
530
+ <span class="cstat-no" title="statement not covered" > if (!relatedDirs) <span class="cstat-no" title="statement not covered" >continue;</span></span>
531
+ &nbsp;
532
+ // Compute Jaccard similarity
533
+ const shared: string[] = <span class="cstat-no" title="statement not covered" >[];</span>
534
+ <span class="cstat-no" title="statement not covered" > for (const name of setA) {</span>
535
+ <span class="cstat-no" title="statement not covered" > if (setB.has(name)) <span class="cstat-no" title="statement not covered" >shared.push(name);</span></span>
536
+ }
537
+ const union = <span class="cstat-no" title="statement not covered" >setA.size + setB.size - shared.length;</span>
538
+ <span class="cstat-no" title="statement not covered" > if (union === 0) <span class="cstat-no" title="statement not covered" >continue;</span></span>
539
+ const similarity = <span class="cstat-no" title="statement not covered" >shared.length / union;</span>
540
+ &nbsp;
541
+ <span class="cstat-no" title="statement not covered" > if (similarity &gt;= minSimilarity) {</span>
542
+ <span class="cstat-no" title="statement not covered" > pairs.push({</span>
543
+ dirA,
544
+ dirB,
545
+ similarity,
546
+ sharedFileNames: shared.sort(),
547
+ uniqueToA: setA.size - shared.length,
548
+ uniqueToB: setB.size - shared.length,
549
+ });
550
+ }
551
+ }
552
+ }
553
+ &nbsp;
554
+ // Sort by similarity descending
555
+ <span class="cstat-no" title="statement not covered" > pairs.<span class="fstat-no" title="function not covered" >sort((a</span>, b) =&gt; <span class="cstat-no" title="statement not covered" >b.similarity - a.similarity)</span>;</span>
556
+ &nbsp;
557
+ <span class="cstat-no" title="statement not covered" > return {</span>
558
+ pairs,
559
+ totalDirsAnalyzed: dirs.length,
560
+ };
561
+ }
562
+ &nbsp;
563
+ export interface MirroredDirResult {
564
+ mirrored: MirroredDirPair[];
565
+ remaining: CloneFamily[];
566
+ }
567
+ &nbsp;
568
+ export function <span class="fstat-no" title="function not covered" >detectMirroredFamilies(</span>
569
+ families: CloneFamily[],
570
+ root: string,
571
+ ): MirroredDirResult {
572
+ const normalizedRoot = <span class="cstat-no" title="statement not covered" >root.replace(/\\/g, '/').replace(/\/$/, '');</span>
573
+ &nbsp;
574
+ function <span class="fstat-no" title="function not covered" >dirOf(f</span>ilePath: string): string {
575
+ const normalized = <span class="cstat-no" title="statement not covered" >filePath.replace(/\\/g, '/');</span>
576
+ const rel = <span class="cstat-no" title="statement not covered" >normalized.startsWith(normalizedRoot + '/')</span>
577
+ ? normalized.slice(normalizedRoot.length + 1)
578
+ : normalized;
579
+ const lastSlash = <span class="cstat-no" title="statement not covered" >rel.lastIndexOf('/');</span>
580
+ <span class="cstat-no" title="statement not covered" > return lastSlash === -1 ? '' : rel.slice(0, lastSlash);</span>
581
+ }
582
+ &nbsp;
583
+ function <span class="fstat-no" title="function not covered" >baseName(f</span>ilePath: string): string {
584
+ const normalized = <span class="cstat-no" title="statement not covered" >filePath.replace(/\\/g, '/');</span>
585
+ <span class="cstat-no" title="statement not covered" > return normalized.slice(normalized.lastIndexOf('/') + 1);</span>
586
+ }
587
+ &nbsp;
588
+ const mirrored: MirroredDirPair[] = <span class="cstat-no" title="statement not covered" >[];</span>
589
+ const remainingIndices = <span class="cstat-no" title="statement not covered" >new Set&lt;number&gt;(families.<span class="fstat-no" title="function not covered" >map((_</span>, i) =&gt; <span class="cstat-no" title="statement not covered" >i)</span>);</span>
590
+ &nbsp;
591
+ <span class="cstat-no" title="statement not covered" > for (let i = <span class="cstat-no" title="statement not covered" >0; i</span> &lt; families.length; i++) {</span>
592
+ <span class="cstat-no" title="statement not covered" > for (let j = <span class="cstat-no" title="statement not covered" >i + 1; j</span> &lt; families.length; j++) {</span>
593
+ <span class="cstat-no" title="statement not covered" > if (!remainingIndices.has(i) || !remainingIndices.has(j)) <span class="cstat-no" title="statement not covered" >continue;</span></span>
594
+ &nbsp;
595
+ const fa = <span class="cstat-no" title="statement not covered" >families[i];</span>
596
+ const fb = <span class="cstat-no" title="statement not covered" >families[j];</span>
597
+ &nbsp;
598
+ // Single pass: extract dir and basename together to avoid two separate .map() iterations
599
+ let firstDirA: string | undefined;
600
+ let singleDirA = <span class="cstat-no" title="statement not covered" >true;</span>
601
+ let firstDirB: string | undefined;
602
+ let singleDirB = <span class="cstat-no" title="statement not covered" >true;</span>
603
+ const namesA = <span class="cstat-no" title="statement not covered" >new Set&lt;string&gt;();</span>
604
+ const namesB = <span class="cstat-no" title="statement not covered" >new Set&lt;string&gt;();</span>
605
+ <span class="cstat-no" title="statement not covered" > for (const f of fa.files) {</span>
606
+ const d = <span class="cstat-no" title="statement not covered" >dirOf(f);</span>
607
+ <span class="cstat-no" title="statement not covered" > if (firstDirA === undefined) <span class="cstat-no" title="statement not covered" >firstDirA = d;</span></span>
608
+ else <span class="cstat-no" title="statement not covered" >if (d !== firstDirA) { <span class="cstat-no" title="statement not covered" >singleDirA = false; }</span></span>
609
+ <span class="cstat-no" title="statement not covered" > namesA.add(baseName(f));</span>
610
+ }
611
+ <span class="cstat-no" title="statement not covered" > for (const f of fb.files) {</span>
612
+ const d = <span class="cstat-no" title="statement not covered" >dirOf(f);</span>
613
+ <span class="cstat-no" title="statement not covered" > if (firstDirB === undefined) <span class="cstat-no" title="statement not covered" >firstDirB = d;</span></span>
614
+ else <span class="cstat-no" title="statement not covered" >if (d !== firstDirB) { <span class="cstat-no" title="statement not covered" >singleDirB = false; }</span></span>
615
+ <span class="cstat-no" title="statement not covered" > namesB.add(baseName(f));</span>
616
+ }
617
+ &nbsp;
618
+ <span class="cstat-no" title="statement not covered" > if (!singleDirA || !singleDirB) <span class="cstat-no" title="statement not covered" >continue;</span></span>
619
+ &nbsp;
620
+ const dirA = <span class="cstat-no" title="statement not covered" >firstDirA!;</span>
621
+ const dirB = <span class="cstat-no" title="statement not covered" >firstDirB!;</span>
622
+ &nbsp;
623
+ const shared: string[] = <span class="cstat-no" title="statement not covered" >[];</span>
624
+ <span class="cstat-no" title="statement not covered" > for (const n of namesA) {</span>
625
+ <span class="cstat-no" title="statement not covered" > if (namesB.has(n)) <span class="cstat-no" title="statement not covered" >shared.push(n);</span></span>
626
+ }
627
+ const union = <span class="cstat-no" title="statement not covered" >namesA.size + namesB.size - shared.length;</span>
628
+ <span class="cstat-no" title="statement not covered" > if (union === 0) <span class="cstat-no" title="statement not covered" >continue;</span></span>
629
+ const similarity = <span class="cstat-no" title="statement not covered" >shared.length / union;</span>
630
+ &nbsp;
631
+ <span class="cstat-no" title="statement not covered" > if (similarity &gt;= 0.5) {</span>
632
+ <span class="cstat-no" title="statement not covered" > mirrored.push({</span>
633
+ dirA,
634
+ dirB,
635
+ similarity,
636
+ sharedFileNames: shared.sort(),
637
+ uniqueToA: namesA.size - shared.length,
638
+ uniqueToB: namesB.size - shared.length,
639
+ });
640
+ <span class="cstat-no" title="statement not covered" > remainingIndices.delete(i);</span>
641
+ <span class="cstat-no" title="statement not covered" > remainingIndices.delete(j);</span>
642
+ }
643
+ }
644
+ }
645
+ &nbsp;
646
+ <span class="cstat-no" title="statement not covered" > mirrored.<span class="fstat-no" title="function not covered" >sort((a</span>, b) =&gt; <span class="cstat-no" title="statement not covered" >b.similarity - a.similarity)</span>;</span>
647
+ &nbsp;
648
+ const remaining: CloneFamily[] = <span class="cstat-no" title="statement not covered" >[];</span>
649
+ <span class="cstat-no" title="statement not covered" > for (const i of remainingIndices) <span class="cstat-no" title="statement not covered" >remaining.push(families[i]);</span></span>
650
+ &nbsp;
651
+ <span class="cstat-no" title="statement not covered" > return { mirrored, remaining };</span>
652
+ }
653
+ &nbsp;
654
+ /**
655
+ * Format a MirroredDirsReport as structured text for LLM consumption.
656
+ */
657
+ export function <span class="fstat-no" title="function not covered" >formatMirroredDirs(r</span>eport: MirroredDirsReport): string {
658
+ <span class="cstat-no" title="statement not covered" > if (report.pairs.length === 0) {</span>
659
+ <span class="cstat-no" title="statement not covered" > return `No mirrored directories found (${report.totalDirsAnalyzed} dirs analyzed).`;</span>
660
+ }
661
+ const lines: string[] = <span class="cstat-no" title="statement not covered" >[</span>
662
+ `Mirrored directories: ${report.pairs.length} pair(s) of ${report.totalDirsAnalyzed} analyzed`,
663
+ '',
664
+ ];
665
+ <span class="cstat-no" title="statement not covered" > for (const p of report.pairs) {</span>
666
+ <span class="cstat-no" title="statement not covered" > lines.push(</span>
667
+ ` ${p.dirA} &lt;-&gt; ${p.dirB} similarity=${(p.similarity * 100).toFixed(0)}% shared=${p.sharedFileNames.length} uniqueA=${p.uniqueToA} uniqueB=${p.uniqueToB}`,
668
+ );
669
+ }
670
+ <span class="cstat-no" title="statement not covered" > return lines.join('\n');</span>
671
+ }
672
+ &nbsp;</pre></td></tr></table></pre>
673
+
674
+ <div class='push'></div><!-- for sticky footer -->
675
+ </div><!-- /wrapper -->
676
+ <div class='footer quiet pad2 space-top1 center small'>
677
+ Code coverage generated by
678
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
679
+ at 2026-07-25T08:38:16.548Z
680
+ </div>
681
+ <script src="../../prettify.js"></script>
682
+ <script>
683
+ window.onload = function () {
684
+ prettyPrint();
685
+ };
686
+ </script>
687
+ <script src="../../sorter.js"></script>
688
+ <script src="../../block-navigation.js"></script>
689
+ </body>
690
+ </html>
691
+