scip-query 0.10.0 → 0.10.2

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 (293) hide show
  1. package/README.md +115 -58
  2. package/dist/augment-vue-worker.js +1 -1
  3. package/dist/chunk-3KLLFNT4.js +2 -0
  4. package/dist/{chunk-UIWAZ2NT.js → chunk-3UVJJ6Z7.js} +1 -1
  5. package/dist/chunk-3UW7VM4H.js +62 -0
  6. package/dist/chunk-3ZYF3ELZ.js +2 -0
  7. package/dist/{chunk-MN75T4UB.js → chunk-47UA45TU.js} +2 -2
  8. package/dist/{chunk-NC4IUW25.js → chunk-4ZUJJRWT.js} +2 -2
  9. package/dist/chunk-5B53WB6E.js +4 -0
  10. package/dist/{chunk-2WEH5QHC.js → chunk-5FOPAXWY.js} +2 -2
  11. package/dist/{chunk-VZRILF2Z.js → chunk-5M4TYWVI.js} +2 -2
  12. package/dist/{chunk-QJWN6LA5.js → chunk-5QJXH6ZL.js} +5 -5
  13. package/dist/{chunk-NN3O7TPH.js → chunk-64MNV6AB.js} +1 -1
  14. package/dist/chunk-77YBOOYT.js +2 -0
  15. package/dist/chunk-7KCSELEV.js +2 -0
  16. package/dist/{chunk-ZZ2W5P3D.js → chunk-7OHWPJ5N.js} +2 -2
  17. package/dist/chunk-7S5E7KWT.js +2 -0
  18. package/dist/chunk-A3VNUGKJ.js +2 -0
  19. package/dist/{chunk-ISCKLDSS.js → chunk-A4L36SZS.js} +3 -3
  20. package/dist/{chunk-IVAIPXNO.js → chunk-AUVBR62P.js} +2 -2
  21. package/dist/chunk-AW4N6MGC.js +18 -0
  22. package/dist/{chunk-PG3ZI5IH.js → chunk-B6MJ5VQV.js} +2 -2
  23. package/dist/chunk-B75HZHUP.js +2 -0
  24. package/dist/chunk-BGBBVSH4.js +2 -0
  25. package/dist/chunk-BKDXBJDQ.js +2 -0
  26. package/dist/{chunk-AQYBOORI.js → chunk-C2QSK7E7.js} +1 -1
  27. package/dist/chunk-C3MZZ2ZN.js +2 -0
  28. package/dist/{chunk-AP5GTKSG.js → chunk-CAWSSEVM.js} +2 -2
  29. package/dist/chunk-CFL2CNIF.js +10 -0
  30. package/dist/{chunk-4HTJZC6G.js → chunk-CJJP64OC.js} +2 -2
  31. package/dist/chunk-CNTEQMHA.js +2 -0
  32. package/dist/{chunk-WEJYUS5O.js → chunk-CRU42NJU.js} +2 -2
  33. package/dist/chunk-CSWZFD46.js +2 -0
  34. package/dist/{chunk-ZOT3WUZW.js → chunk-CTCAF3YA.js} +2 -2
  35. package/dist/chunk-D322LMSA.js +5 -0
  36. package/dist/{chunk-772YYL6I.js → chunk-DAI74TJU.js} +2 -2
  37. package/dist/chunk-DE7MA6OD.js +3 -0
  38. package/dist/chunk-DJMK4DBL.js +2 -0
  39. package/dist/chunk-DRAZH77R.js +7 -0
  40. package/dist/{chunk-L2KFPRMA.js → chunk-E44ZMVNA.js} +2 -2
  41. package/dist/{chunk-BNW3Q24R.js → chunk-E7KERP7E.js} +2 -2
  42. package/dist/{chunk-QKO474FG.js → chunk-EOZIZWW4.js} +2 -2
  43. package/dist/chunk-ERHOS6AW.js +2 -0
  44. package/dist/{chunk-ADRYSISR.js → chunk-ESG4HBEF.js} +2 -2
  45. package/dist/chunk-EWC3UK4V.js +3 -0
  46. package/dist/chunk-FGCL6NDB.js +8 -0
  47. package/dist/chunk-FIB4JPEX.js +2 -0
  48. package/dist/chunk-FNRPGGVI.js +2 -0
  49. package/dist/chunk-FOQHUKNZ.js +4 -0
  50. package/dist/chunk-FPMVCDIJ.js +2 -0
  51. package/dist/chunk-FUPDW5AC.js +3 -0
  52. package/dist/chunk-G3WGZU5Q.js +2 -0
  53. package/dist/chunk-GS33KGAY.js +2 -0
  54. package/dist/chunk-GZCQTZLK.js +2 -0
  55. package/dist/{chunk-VGBSY6N7.js → chunk-HVTYSC26.js} +2 -2
  56. package/dist/{chunk-2BMFRBV6.js → chunk-ICXVNWMI.js} +2 -2
  57. package/dist/chunk-JM72FNGA.js +2 -0
  58. package/dist/chunk-KPHKX4LP.js +71 -0
  59. package/dist/{chunk-6DEX3XP6.js → chunk-LPLGJ4HO.js} +2 -2
  60. package/dist/chunk-MHK7Z53U.js +2 -0
  61. package/dist/chunk-MHTDOFV7.js +5 -0
  62. package/dist/chunk-MUULWXSJ.js +2 -0
  63. package/dist/chunk-MZ7APUFN.js +3 -0
  64. package/dist/chunk-NNDYO2DX.js +2 -0
  65. package/dist/chunk-NP5HYVLX.js +20 -0
  66. package/dist/{chunk-Y5H7TBVE.js → chunk-NVFERV4U.js} +2 -2
  67. package/dist/{chunk-LWYIGRHR.js → chunk-NXIAHE7F.js} +1 -1
  68. package/dist/chunk-O3OKSF6O.js +2 -0
  69. package/dist/chunk-O4L4AB3T.js +2 -0
  70. package/dist/chunk-OBBDKQAG.js +3 -0
  71. package/dist/chunk-OLD6PBU6.js +7 -0
  72. package/dist/{chunk-V76FCF5F.js → chunk-PFOCOG57.js} +2 -2
  73. package/dist/chunk-PVZMPG5I.js +2 -0
  74. package/dist/chunk-QLNGUWR7.js +2 -0
  75. package/dist/chunk-QSXQT3NE.js +2 -0
  76. package/dist/{chunk-OLCKSG3Y.js → chunk-QVCCLDZI.js} +2 -2
  77. package/dist/chunk-RHTJBYZ5.js +2 -0
  78. package/dist/chunk-SPE4YCOT.js +7 -0
  79. package/dist/{chunk-FVIKFWUL.js → chunk-TM6GVHA6.js} +2 -2
  80. package/dist/chunk-TO54DY4O.js +2 -0
  81. package/dist/chunk-UMNENNTX.js +2 -0
  82. package/dist/chunk-UNJG7P2I.js +2 -0
  83. package/dist/{chunk-TKDJQ2WD.js → chunk-UUBMFL3F.js} +1 -1
  84. package/dist/chunk-VAA5FFIW.js +2 -0
  85. package/dist/chunk-WDUTG2ZR.js +4 -0
  86. package/dist/chunk-X7ZY6FFF.js +4 -0
  87. package/dist/{chunk-BGRPMGTD.js → chunk-YQH353VA.js} +2 -2
  88. package/dist/chunk-YTR4CO5S.js +38 -0
  89. package/dist/chunk-YUOAAR24.js +2 -0
  90. package/dist/{chunk-YWZBKYLS.js → chunk-YYD245WG.js} +2 -2
  91. package/dist/{chunk-SCEMECW7.js → chunk-Z4VHYJ5U.js} +2 -2
  92. package/dist/chunk-ZFMPHDAT.js +4 -0
  93. package/dist/chunk-ZQLO2SCU.js +6 -0
  94. package/dist/chunk-ZSLT7NWQ.js +61 -0
  95. package/dist/cli.js +276 -271
  96. package/dist/{config-types-CGIeLEpY.d.ts → config-types-Bj4sh28g.d.ts} +37 -1
  97. package/dist/{db-DdTPetj5.d.ts → db-CTarohbZ.d.ts} +1 -1
  98. package/dist/git-history-Dao3_Pu9.d.ts +12 -0
  99. package/dist/{health-C6r2VgpA.d.ts → health-Bx0x1HAG.d.ts} +64 -4
  100. package/dist/index.d.ts +7 -6
  101. package/dist/index.js +1 -1
  102. package/dist/postinstall.js +2 -2
  103. package/dist/queries/affected.d.ts +2 -2
  104. package/dist/queries/affected.js +1 -1
  105. package/dist/queries/bottlenecks.d.ts +6 -2
  106. package/dist/queries/bottlenecks.js +1 -1
  107. package/dist/queries/by-kind.d.ts +2 -2
  108. package/dist/queries/by-kind.js +1 -1
  109. package/dist/queries/call-graph.d.ts +2 -2
  110. package/dist/queries/call-graph.js +1 -1
  111. package/dist/queries/change-surface.d.ts +2 -2
  112. package/dist/queries/change-surface.js +1 -1
  113. package/dist/queries/cleanup-plan.d.ts +2 -2
  114. package/dist/queries/cleanup-plan.js +1 -1
  115. package/dist/queries/co-change.d.ts +40 -5
  116. package/dist/queries/co-change.js +1 -1
  117. package/dist/queries/code.d.ts +2 -2
  118. package/dist/queries/code.js +1 -1
  119. package/dist/queries/complexity-hotspots.d.ts +2 -2
  120. package/dist/queries/complexity-hotspots.js +1 -1
  121. package/dist/queries/complexity.d.ts +2 -2
  122. package/dist/queries/complexity.js +1 -1
  123. package/dist/queries/convergence.d.ts +2 -2
  124. package/dist/queries/convergence.js +1 -1
  125. package/dist/queries/coupling.d.ts +6 -2
  126. package/dist/queries/coupling.js +1 -1
  127. package/dist/queries/cycles.d.ts +2 -2
  128. package/dist/queries/cycles.js +1 -1
  129. package/dist/queries/dataflow.d.ts +2 -2
  130. package/dist/queries/dataflow.js +1 -1
  131. package/dist/queries/dead.d.ts +10 -3
  132. package/dist/queries/dead.js +1 -1
  133. package/dist/queries/deep-chains.d.ts +6 -2
  134. package/dist/queries/deep-chains.js +1 -1
  135. package/dist/queries/deps.d.ts +2 -2
  136. package/dist/queries/deps.js +1 -1
  137. package/dist/queries/diff-gate.d.ts +66 -3
  138. package/dist/queries/diff-gate.js +1 -1
  139. package/dist/queries/diff-impact.d.ts +20 -4
  140. package/dist/queries/diff-impact.js +1 -1
  141. package/dist/queries/doc-drift.d.ts +20 -3
  142. package/dist/queries/doc-drift.js +1 -1
  143. package/dist/queries/drift.d.ts +10 -3
  144. package/dist/queries/drift.js +1 -1
  145. package/dist/queries/extract-candidates.d.ts +11 -3
  146. package/dist/queries/extract-candidates.js +1 -1
  147. package/dist/queries/fan.d.ts +2 -2
  148. package/dist/queries/fan.js +1 -1
  149. package/dist/queries/files.d.ts +2 -2
  150. package/dist/queries/files.js +1 -1
  151. package/dist/queries/health.d.ts +3 -3
  152. package/dist/queries/health.js +1 -1
  153. package/dist/queries/hierarchy.d.ts +2 -2
  154. package/dist/queries/hierarchy.js +1 -1
  155. package/dist/queries/hotspots.d.ts +2 -2
  156. package/dist/queries/hotspots.js +1 -1
  157. package/dist/queries/imports.d.ts +2 -2
  158. package/dist/queries/imports.js +1 -1
  159. package/dist/queries/incomplete-migration.d.ts +16 -3
  160. package/dist/queries/incomplete-migration.js +1 -1
  161. package/dist/queries/index.d.ts +20 -12
  162. package/dist/queries/index.js +1 -1
  163. package/dist/queries/isolated.d.ts +2 -2
  164. package/dist/queries/isolated.js +1 -1
  165. package/dist/queries/locality-candidates.d.ts +51 -0
  166. package/dist/queries/locality-candidates.js +2 -0
  167. package/dist/queries/members.d.ts +2 -2
  168. package/dist/queries/members.js +1 -1
  169. package/dist/queries/methods.d.ts +2 -2
  170. package/dist/queries/methods.js +1 -1
  171. package/dist/queries/outline.d.ts +2 -2
  172. package/dist/queries/outline.js +1 -1
  173. package/dist/queries/passthrough-candidates.d.ts +8 -3
  174. package/dist/queries/passthrough-candidates.js +1 -1
  175. package/dist/queries/plan-context.d.ts +4 -2
  176. package/dist/queries/plan-context.js +1 -1
  177. package/dist/queries/react-component-duplicates.d.ts +31 -0
  178. package/dist/queries/react-component-duplicates.js +2 -0
  179. package/dist/queries/react-hook-candidates.d.ts +40 -0
  180. package/dist/queries/react-hook-candidates.js +2 -0
  181. package/dist/queries/react-large-component-pressure.d.ts +34 -0
  182. package/dist/queries/react-large-component-pressure.js +2 -0
  183. package/dist/queries/recent-duplicates.d.ts +32 -3
  184. package/dist/queries/recent-duplicates.js +1 -1
  185. package/dist/queries/redundant-reexports.d.ts +7 -3
  186. package/dist/queries/redundant-reexports.js +1 -1
  187. package/dist/queries/refs.d.ts +2 -2
  188. package/dist/queries/refs.js +1 -1
  189. package/dist/queries/self-audit.d.ts +2 -2
  190. package/dist/queries/self-audit.js +1 -1
  191. package/dist/queries/similar-chains.d.ts +2 -2
  192. package/dist/queries/similar-chains.js +1 -1
  193. package/dist/queries/similar-files.d.ts +2 -2
  194. package/dist/queries/similar-files.js +1 -1
  195. package/dist/queries/similar-signatures.d.ts +2 -2
  196. package/dist/queries/similar-signatures.js +1 -1
  197. package/dist/queries/similar.d.ts +21 -3
  198. package/dist/queries/similar.js +1 -1
  199. package/dist/queries/slice.d.ts +2 -2
  200. package/dist/queries/slice.js +1 -1
  201. package/dist/queries/stale-abstractions.d.ts +10 -3
  202. package/dist/queries/stale-abstractions.js +1 -1
  203. package/dist/queries/stats.d.ts +2 -2
  204. package/dist/queries/stats.js +1 -1
  205. package/dist/queries/surface.d.ts +2 -2
  206. package/dist/queries/surface.js +1 -1
  207. package/dist/queries/symbols.d.ts +2 -2
  208. package/dist/queries/symbols.js +1 -1
  209. package/dist/queries/system.d.ts +2 -2
  210. package/dist/queries/system.js +1 -1
  211. package/dist/queries/trace.d.ts +2 -2
  212. package/dist/queries/trace.js +1 -1
  213. package/dist/queries/unused-imports.d.ts +4 -0
  214. package/dist/queries/unused-imports.js +2 -0
  215. package/dist/queries/unused-params.d.ts +2 -2
  216. package/dist/queries/unused-params.js +1 -1
  217. package/dist/queries/vue-component-duplicates.d.ts +35 -0
  218. package/dist/queries/vue-component-duplicates.js +2 -0
  219. package/dist/queries/vue-composable-candidates.d.ts +40 -0
  220. package/dist/queries/vue-composable-candidates.js +2 -0
  221. package/dist/queries/vue-large-view-pressure.d.ts +37 -0
  222. package/dist/queries/vue-large-view-pressure.js +2 -0
  223. package/dist/queries/wrapper-candidates.d.ts +6 -3
  224. package/dist/queries/wrapper-candidates.js +1 -1
  225. package/dist/reindex-worker.js +10 -10
  226. package/dist/reindex.d.ts +1 -1
  227. package/dist/reindex.js +22 -22
  228. package/dist/runtime.d.ts +1 -1
  229. package/dist/runtime.js +2 -2
  230. package/docs/AGENT_GUIDE.md +353 -0
  231. package/docs/AI_FAILURE_MODES.md +278 -0
  232. package/docs/API.md +40 -0
  233. package/docs/COMMAND_REFERENCE.md +131 -0
  234. package/docs/DETECTOR_GUIDE.md +119 -0
  235. package/docs/accuracy-hardening-goal.md +54 -0
  236. package/docs/analyzer-inventory.md +162 -0
  237. package/docs/analyzer-validation-ledger.md +262 -0
  238. package/docs/analyzer-validation-protocol.md +192 -0
  239. package/docs/assets/scip-query-logo-dark.svg +21 -0
  240. package/docs/assets/scip-query-logo.svg +24 -0
  241. package/docs/locality-analyzer-design.md +193 -0
  242. package/package.json +44 -5
  243. package/skills/scip-directory-architecture/SKILL.md +178 -0
  244. package/skills/scip-maintainability/SKILL.md +24 -3
  245. package/skills/scip-query/SKILL.md +4 -2
  246. package/skills/scip-query-setup/SKILL.md +118 -0
  247. package/skills/scip-react-maintainability/SKILL.md +114 -0
  248. package/skills/scip-vue-maintainability/SKILL.md +130 -0
  249. package/dist/chunk-4DAPXOWD.js +0 -2
  250. package/dist/chunk-4JQFTUKD.js +0 -2
  251. package/dist/chunk-4MHT7LKP.js +0 -3
  252. package/dist/chunk-5OHZEO3U.js +0 -3
  253. package/dist/chunk-5QJIEYFB.js +0 -34
  254. package/dist/chunk-6IGXZZQ4.js +0 -4
  255. package/dist/chunk-6K2JQ2VI.js +0 -61
  256. package/dist/chunk-6QVCPUK6.js +0 -2
  257. package/dist/chunk-6VL4AIEO.js +0 -8
  258. package/dist/chunk-A2VTV2QB.js +0 -7
  259. package/dist/chunk-AI2ECT7L.js +0 -2
  260. package/dist/chunk-BUAC4Q4G.js +0 -2
  261. package/dist/chunk-BZ6LCGE6.js +0 -2
  262. package/dist/chunk-CMXFASVD.js +0 -2
  263. package/dist/chunk-CO3AL7NZ.js +0 -2
  264. package/dist/chunk-FVVT7GV6.js +0 -4
  265. package/dist/chunk-HXXRN77A.js +0 -2
  266. package/dist/chunk-IC3RC3KJ.js +0 -4
  267. package/dist/chunk-ITHQJZTG.js +0 -2
  268. package/dist/chunk-IW7ASGVF.js +0 -2
  269. package/dist/chunk-JODYQDE4.js +0 -2
  270. package/dist/chunk-MCW36F2D.js +0 -2
  271. package/dist/chunk-MX6F756F.js +0 -2
  272. package/dist/chunk-NGI4V4AB.js +0 -18
  273. package/dist/chunk-O6KCZPJQ.js +0 -62
  274. package/dist/chunk-OAI5GEIN.js +0 -6
  275. package/dist/chunk-OH5HIAID.js +0 -4
  276. package/dist/chunk-OXKEUWMJ.js +0 -2
  277. package/dist/chunk-PBGTMPJ7.js +0 -2
  278. package/dist/chunk-PRVDXGSK.js +0 -2
  279. package/dist/chunk-QYKKTYBN.js +0 -6
  280. package/dist/chunk-R3G6ERW7.js +0 -7
  281. package/dist/chunk-R6XDPWJA.js +0 -10
  282. package/dist/chunk-SJR4SB7B.js +0 -2
  283. package/dist/chunk-SYKCO25G.js +0 -16
  284. package/dist/chunk-T22X7WT6.js +0 -2
  285. package/dist/chunk-TH4JVC34.js +0 -71
  286. package/dist/chunk-VDY4HYNK.js +0 -2
  287. package/dist/chunk-VDZIEDJB.js +0 -2
  288. package/dist/chunk-VDZL45XI.js +0 -2
  289. package/dist/chunk-WJIS6BNI.js +0 -3
  290. package/dist/chunk-WN5Z3UVT.js +0 -7
  291. package/dist/chunk-XCW7DYHM.js +0 -2
  292. package/dist/chunk-ZF6P2NAT.js +0 -63
  293. package/dist/chunk-ZGIK464P.js +0 -2
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: scip-query-setup
3
+ description: Set up or refresh scip-query in a repository so agents can use compiler-resolved code intelligence effectively. Use when adopting scip-query in a repo, fixing stale setup, adding AGENTS.md guidance, checking capability coverage, configuring .scipquery.json, or calibrating locality architectural boundaries.
4
+ allowed-tools: [Bash, Read, Edit, Write, Glob, Skill]
5
+ ---
6
+
7
+ # scip-query Setup
8
+
9
+ Use this skill when a repository needs to become a reliable scip-query workspace, not merely a repo where the binary happens to run.
10
+
11
+ A scip-query workspace is a source repository with a current SCIP index, project config, and agent guidance that make code references compiler-resolved instead of guessed from text search. Its defining trait is that agents can answer "where is this defined, who uses it, and what changes with it?" from the index before editing.
12
+
13
+ A setup pass is the bounded workflow that installs or verifies the tool, creates the project index, writes agent instructions, and records repo-specific calibration. Its defining trait is that it turns one-off local success into a repeatable operating surface for future agents.
14
+
15
+ ## Setup Workflow
16
+
17
+ 1. Confirm the project root.
18
+
19
+ ```bash
20
+ pwd
21
+ git rev-parse --show-toplevel
22
+ ```
23
+
24
+ 2. Verify the command is available.
25
+
26
+ ```bash
27
+ scip-query --version
28
+ scip-query status --json
29
+ ```
30
+
31
+ If the command is missing, install or link it using the repo's package manager, then rerun this step.
32
+
33
+ 3. Create or refresh the index.
34
+
35
+ ```bash
36
+ scip-query reindex
37
+ scip-query stats
38
+ ```
39
+
40
+ If indexing fails, run `scip-query status --json` and fix the reported missing indexer, language, or config problem before continuing.
41
+
42
+ 4. Seed durable agent guidance.
43
+
44
+ ```bash
45
+ scip-query setup-agent
46
+ ```
47
+
48
+ Use `scip-query setup-agent --git-hook` only when the user wants the repository to enforce `diff-gate` before commits.
49
+
50
+ 5. Check capability coverage.
51
+
52
+ ```bash
53
+ scip-query capability-matrix
54
+ scip-query health
55
+ ```
56
+
57
+ Record unsupported or partial capabilities in the setup notes. Do not describe an analyzer as "clean" when the capability matrix says its evidence is unavailable for the language.
58
+
59
+ 6. Calibrate project config.
60
+
61
+ Open or create `.scipquery.json`. Keep config minimal and tied to observed repo facts.
62
+
63
+ ```json
64
+ {
65
+ "languages": ["typescript"],
66
+ "locality": {
67
+ "architecturalBoundarySegments": ["effect", "errors", "policies", "workflows"]
68
+ }
69
+ }
70
+ ```
71
+
72
+ An architectural boundary segment is a folder name that marks a code ownership boundary, such as `effect`, `errors`, `policies`, `routes`, `schemas`, or `workflows`. Its defining trait is that broad use of code inside that folder can mean the boundary is central and intentional, so `locality-candidates` should not invent a generic `shared` destination for it.
73
+
74
+ Before writing `locality.architecturalBoundarySegments`, classify boundary maturity:
75
+
76
+ - Mature boundary: folder names recur as intentional ownership units in code, tests, docs, route/workflow conventions, or agent standards. Add only the repo-specific segment names not already built in.
77
+ - Emerging boundary: folder names look meaningful, but ownership is inconsistent or only visible in one area. Do not configure yet; record candidates and rerun after a few reviewed locality results prove the boundary.
78
+ - No reliable boundary: the repo is mostly flat, mixed, generated, or ad hoc. Leave locality config absent or empty. Do not invent architecture; use `locality-candidates` as a discovery report and ask for human ownership decisions.
79
+
80
+ Treat boundary maturity as an evidence question. A segment needs at least two independent signals before it belongs in config: directory structure plus a project standard, repeated import convention, test organization, package boundary, route family, workflow family, or reviewed locality false positive. If the same folder name means different things in different parts of the repo, do not add it globally.
81
+
82
+ For an unstructured repo, setup runs in discovery mode. Discovery mode means the tool records candidate ownership clusters and uncertain folders, but does not write `locality.architecturalBoundarySegments`. The setup note should say which paths need a human architecture decision and should keep `locality-candidates` recommendations as suggestions to inspect, not moves to trust.
83
+
84
+ Use `locality.architecturalBoundarySegments` only when validation finds a repo-specific mature boundary that is not already in the built-in list. Add folder names, not paths.
85
+
86
+ 7. Validate directory-organization signals when setup touches locality.
87
+
88
+ ```bash
89
+ scip-query locality-candidates --json --full
90
+ ```
91
+
92
+ Review rows with non-null `suggestedHome`. Keep exact destinations only when the path already exists, stays inside the source root, and matches the repo's ownership model. When a generic `shared` destination is wrong because the current folder is a real boundary, add that folder name to `.scipquery.json` and rerun.
93
+
94
+ Validate both suppression and emission. Suppression means a bad generic home was withheld because the source already lives in a real boundary. Emission means a useful `suggestedHome` is still shown for code that genuinely lacks a home. A config that suppresses every row is acceptable only when manual review confirms there were no useful destinations to emit.
95
+
96
+ If the repo has no mature boundaries, the correct setup result is a note, not a config guess: "locality boundaries not configured; repo needs architecture ownership decisions first." A slop codebase is a codebase whose files are arranged by accident, convenience, or recent edits rather than by stable ownership rules. Its defining trait is that directory names do not reliably predict where code should live, so the setup skill must not make `locality-candidates` appear more certain than the repo itself.
97
+
98
+ 8. Finish with the standard gate.
99
+
100
+ ```bash
101
+ scip-query reindex
102
+ scip-query diff-gate
103
+ ```
104
+
105
+ Fix findings or state the explicit acceptance reason.
106
+
107
+ ## Handoff Notes
108
+
109
+ When setup changes are complete, record:
110
+
111
+ - repository path and revision;
112
+ - index command and result;
113
+ - capability matrix limitations;
114
+ - `.scipquery.json` changes and why each setting exists;
115
+ - validation commands and raw-output locations;
116
+ - final `diff-gate` result.
117
+
118
+ Do not add broad analyzer config in advance. Each setting should be justified by a reviewed false positive, false negative, capability gap, or repo convention.
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: scip-react-maintainability
3
+ description: React frontend maintainability review using scip-query's React component duplicate, hook candidate, large component pressure, recent-duplicate, incomplete-migration, and diff-gate commands. Use when reviewing React, TSX, JSX, or Next.js codebases; investigating duplicated components or hooks; checking frontend health pressure; or verifying agents reused React code correctly after a refactor.
4
+ ---
5
+
6
+ # SCIP React Maintainability Review
7
+
8
+ This skill reviews React frontends by treating components, hooks, JSX structure, and behavior lifecycles as first-class maintainability units. It uses `scip-query` evidence to decide where UI structure, state/effect/request behavior, and large components are carrying duplicated concepts or too many reasons to change.
9
+
10
+ A React component duplicate candidate is a pair or group of rendered interface structures that repeat the same user-facing arrangement, controls, states, props, or data-presentation shape enough that a shared component may reduce future divergence.
11
+
12
+ A React hook candidate is a pair or group of component behaviors that repeat the same state lifecycle, effects, requests, validation, persistence, callback policy, or derived-data rule enough that a shared hook may make the behavior easier to preserve.
13
+
14
+ Large component pressure is a maintainability signal that one React component or file contains several kinds of knowledge that change for different reasons, such as layout structure, state management, data loading, permission policy, and styling.
15
+
16
+ React health is a repo-grounded frontend pressure map. It is useful for ranking review attention, but it is not proof that code is bad and not the goal of a refactor.
17
+
18
+ ## Quick Start
19
+
20
+ Refresh the code intelligence before trusting graph facts:
21
+
22
+ ```bash
23
+ scip-query status
24
+ scip-query reindex
25
+ ```
26
+
27
+ Run the React review commands uncapped when doing a serious frontend pass. Do not combine `--full` with `--limit`.
28
+
29
+ ```bash
30
+ scip-query react-component-duplicates --scope <react-source-scope> --full --json
31
+ scip-query react-hook-candidates --scope <react-source-scope> --full --json
32
+ scip-query react-large-component-pressure --scope <react-source-scope> --full --json
33
+ scip-query recent-duplicates --scope <react-source-scope> --full --json
34
+ scip-query health --scope <react-source-scope> --json
35
+ ```
36
+
37
+ ## Workflow
38
+
39
+ 1. Bound the review to a React source root, feature area, or changed files. Prefer the narrowest scope that still includes likely reuse partners.
40
+ 2. Run the three React commands: component duplicates, hook candidates, and large component pressure.
41
+ 3. Use `recent-duplicates` to catch newly added frontend echoes of established code.
42
+ 4. Cross-check the result sets before recommending an extraction:
43
+ - Component duplicate only: inspect for a shared presentational component or an existing component callers should reuse.
44
+ - Hook candidate only: inspect for a shared behavior, lifecycle, request pattern, validation rule, persistence rule, or derived-state policy.
45
+ - Both component and hook candidate: inspect for a feature-level concept that may need both a component boundary and a hook boundary.
46
+ - Large component only: split by reason to change, not by line count alone.
47
+ 5. Open the source files for the top candidates. Similarity is evidence to inspect, not a verdict.
48
+ 6. Check existing exports, imports, and call sites before proposing anything new:
49
+
50
+ ```bash
51
+ scip-query outline <file>
52
+ scip-query deps <file>
53
+ scip-query rdeps <file>
54
+ scip-query similar-files --scope <react-source-scope>
55
+ scip-query similar <closest-existing-component-or-hook>
56
+ ```
57
+
58
+ ## Acting on Findings
59
+
60
+ Prefer reuse before extraction. If an existing component or hook already names the concept, migrate callers to it instead of creating another one.
61
+
62
+ When extracting:
63
+
64
+ - Extract a component when the repeated knowledge is rendered UI structure, props, slots/children, empty/loading/error states, or design-system composition.
65
+ - Extract a hook when the repeated knowledge is state, effects, requests, subscriptions, memoized derivations, callbacks, or persistence policy.
66
+ - Split a large component by reason to change: data loading, permission/policy, layout shell, table/list rendering, form state, and action handling are different reasons.
67
+ - Keep domain-specific variation at the call site when the variation is essential. Do not hide different product rules behind a boolean soup API.
68
+
69
+ ## Post-Change Verification
70
+
71
+ After implementing a component reuse, hook extraction, or large-component split, prove both sides of the work: the new abstraction exists and the old inline copies were migrated.
72
+
73
+ Run the checks that match what changed:
74
+
75
+ ```bash
76
+ scip-query diff-impact
77
+ scip-query react-component-duplicates --scope <react-source-scope> --full --json
78
+ scip-query react-hook-candidates --scope <react-source-scope> --full --json
79
+ scip-query react-large-component-pressure --scope <react-source-scope> --full --json
80
+ scip-query recent-duplicates --scope <react-source-scope> --full --json
81
+ scip-query incomplete-migration
82
+ scip-query unused-params
83
+ scip-query wrapper-candidates --scope <react-source-scope> --full --json
84
+ scip-query passthrough-candidates --scope <react-source-scope> --full --json
85
+ scip-query stale-abstractions --scope <react-source-scope> --include-low-confidence --full --json
86
+ scip-query reindex && scip-query diff-gate
87
+ ```
88
+
89
+ Use the results this way:
90
+
91
+ - `incomplete-migration`: if a new hook/helper was created and wired somewhere, migrate every unchanged site that still contains the same logic or document why it is not the same behavior.
92
+ - `recent-duplicates`: if the new component/hook is still an echo of established code, delete the echo or reuse the established concept.
93
+ - React duplicate commands: the specific candidate pair you acted on should disappear, weaken materially, or be explicitly accepted as essential variation.
94
+ - `unused-params`: remove speculative props/options introduced "for later."
95
+ - wrapper/pass-through/stale checks: remove local wrapper components, hook aliases, or type abstractions that do not enforce a real policy.
96
+ - `diff-gate`: treat every finding as unfinished work unless there is a written reason to accept it.
97
+
98
+ ## False Positive Checks
99
+
100
+ - Shared design-system primitives, icons, labels, route names, or test IDs are not enough to justify an extraction.
101
+ - Similar JSX with different domain lifecycles may justify a presentational component but not a hook.
102
+ - Shared hook usage may mean the right concept is already extracted; look for drift around the shared call, not another extraction.
103
+ - A large file creates review pressure, but it is not proof that behavior is duplicated.
104
+ - A local wrapper is justified only when it names a real product concept, enforces a policy, or prevents drift across callers.
105
+
106
+ ## Reporting Shape
107
+
108
+ Report findings as a frontend maintainability register:
109
+
110
+ - Executive read: whether the React code is consolidating or drifting.
111
+ - Command evidence: exact commands, scope, counts, and whether results were uncapped.
112
+ - Candidate groups: files/components, repeated UI structure, repeated behavior, and large-component pressure.
113
+ - Recommended action: reuse existing API, extract component, extract hook, split view, delete wrapper, or no action.
114
+ - Post-change proof: commands rerun, candidate pairs resolved or accepted, migration completeness checked, and `diff-gate` result.
@@ -0,0 +1,130 @@
1
+ ---
2
+ name: scip-vue-maintainability
3
+ description: Vue frontend maintainability review using scip-query's Vue SFC, template-duplicate, composable-candidate, large-view, and health commands. Use when reviewing Vue or Nuxt codebases, investigating duplicated components or composables, checking frontend health score pressure, or asking whether agents are reusing Vue code correctly.
4
+ allowed-tools: [Bash, Read, Grep, Glob]
5
+ ---
6
+
7
+ # SCIP Vue Maintainability Review
8
+
9
+ This skill reviews Vue frontends by treating `.vue` single-file components as first-class code units. It uses `scip-query` evidence to decide where templates, scripts, styles, external scripts, components, and composables are carrying duplicated concepts or too many reasons to change.
10
+
11
+ A Vue component duplicate candidate is a pair or group of rendered interface structures that repeat the same user-facing arrangement, controls, states, or data-presentation shape enough that a shared component may reduce future divergence.
12
+
13
+ A Vue composable candidate is a pair or group of script behaviors that repeat the same state lifecycle, effects, requests, validation, persistence, or derived-data policy enough that a shared composable may make the behavior easier to preserve.
14
+
15
+ Large view pressure is a maintainability signal that one SFC or linked view file contains several kinds of knowledge that change for different reasons, such as layout structure, state management, data loading, styling, and feature policy.
16
+
17
+ Vue health is a repo-grounded frontend pressure map. It is useful for ranking review attention, but it is not proof that code is bad and not the goal of a refactor.
18
+
19
+ ## Quick Start
20
+
21
+ Refresh the code intelligence before trusting graph facts:
22
+
23
+ ```bash
24
+ scip-query status
25
+ scip-query reindex
26
+ ```
27
+
28
+ If Vue files need rich internals, find the relevant TypeScript project and augment the index:
29
+
30
+ ```bash
31
+ find . -name 'tsconfig*.json' -not -path '*/node_modules/*'
32
+ scip-query augment-vue --project <path-to-tsconfig>
33
+ ```
34
+
35
+ Run the Vue review commands uncapped when doing a serious frontend pass. Do not combine `--full` with `--limit`.
36
+
37
+ ```bash
38
+ scip-query vue-component-duplicates --scope <vue-source-scope> --full --json
39
+ scip-query vue-composable-candidates --scope <vue-source-scope> --full --json
40
+ scip-query vue-large-view-pressure --scope <vue-source-scope> --full --json
41
+ scip-query health --json
42
+ ```
43
+
44
+ ## Workflow
45
+
46
+ 1. Bound the review to a Vue source root, feature area, or changed files. Prefer the narrowest scope that still includes likely reuse partners.
47
+ 2. Run `augment-vue` when component references, imported composables, script blocks, or linked external scripts matter to the question.
48
+ 3. Run the three Vue commands: component duplicates, composable candidates, and large view pressure.
49
+ 4. Cross-check the result sets before recommending an extraction:
50
+ - Component duplicate only: inspect for a shared presentational component or an existing component that callers should reuse.
51
+ - Composable candidate only: inspect for a shared behavior, lifecycle, request pattern, validation rule, persistence rule, or derived-state policy.
52
+ - Both component and composable candidate: inspect for a feature-level concept that may need both a component boundary and a composable boundary.
53
+ - Large view only: split by reason to change, not by line count alone.
54
+ 5. Open the source files for the top candidates. Similarity is evidence to inspect, not a verdict.
55
+ 6. Check existing exports, imports, and call sites before proposing anything new:
56
+
57
+ ```bash
58
+ scip-query outline <file>
59
+ scip-query deps <file>
60
+ scip-query rdeps <file>
61
+ scip-query similar-files --scope <vue-source-scope>
62
+ scip-query recent-duplicates --scope <vue-source-scope> --full --json
63
+ ```
64
+
65
+ ## Acting on Findings
66
+
67
+ Prefer reuse before extraction. If an existing component or composable already names the concept, migrate callers to it instead of creating another one.
68
+
69
+ When extracting:
70
+
71
+ - Extract a component when the repeated knowledge is rendered template structure, props, slots, empty/loading/error states, or design-system composition.
72
+ - Extract a composable when the repeated knowledge is state, lifecycle, requests, validation, persistence, derived data, or shared event policy.
73
+ - Split a large view by reason to change: data loading, permission/policy, layout shell, table/list rendering, form state, and action handling are different reasons.
74
+ - Keep domain-specific variation at the call site when the variation is essential. Do not hide different product rules behind broad option objects.
75
+
76
+ ## Post-Change Verification
77
+
78
+ After implementing a component reuse, composable extraction, or large-view split, prove both sides of the work: the new abstraction exists and the old inline copies were migrated.
79
+
80
+ Run the checks that match what changed:
81
+
82
+ ```bash
83
+ scip-query diff-impact
84
+ scip-query vue-component-duplicates --scope <vue-source-scope> --full --json
85
+ scip-query vue-composable-candidates --scope <vue-source-scope> --full --json
86
+ scip-query vue-large-view-pressure --scope <vue-source-scope> --full --json
87
+ scip-query recent-duplicates --scope <vue-source-scope> --full --json
88
+ scip-query incomplete-migration
89
+ scip-query unused-params
90
+ scip-query wrapper-candidates --scope <vue-source-scope> --full --json
91
+ scip-query passthrough-candidates --scope <vue-source-scope> --full --json
92
+ scip-query stale-abstractions --scope <vue-source-scope> --include-low-confidence --full --json
93
+ scip-query reindex && scip-query diff-gate
94
+ ```
95
+
96
+ Use the results this way:
97
+
98
+ - `incomplete-migration`: if a new composable/helper was created and wired somewhere, migrate every unchanged site that still contains the same logic or document why it is not the same behavior.
99
+ - `recent-duplicates`: if the new component/composable is still an echo of established code, delete the echo or reuse the established concept.
100
+ - Vue duplicate commands: the specific candidate pair you acted on should disappear, weaken materially, or be explicitly accepted as essential variation.
101
+ - `unused-params`: remove speculative props/options introduced "for later."
102
+ - wrapper/pass-through/stale checks: remove local wrapper components, composable aliases, or type abstractions that do not enforce a real policy.
103
+ - `diff-gate`: treat every finding as unfinished work unless there is a written reason to accept it.
104
+
105
+ ## False Positive Checks
106
+
107
+ - Shared design-system primitives, CSS utility classes, icons, labels, or test IDs are not enough to justify an extraction.
108
+ - Similar templates with different domain lifecycles may justify a presentational component but not a composable.
109
+ - Shared composable usage may mean the right concept is already extracted; look for drift around the shared call, not just another extraction.
110
+ - A large style block creates review pressure, but it is not proof that behavior is duplicated.
111
+ - A local wrapper is justified only when it names a real product concept, enforces a policy, or prevents drift across callers.
112
+
113
+ ## Reporting Shape
114
+
115
+ Report findings as a frontend maintainability register:
116
+
117
+ - Executive read: whether the Vue code is consolidating or drifting.
118
+ - Command evidence: exact commands, scope, counts, and whether results were uncapped.
119
+ - Candidate groups: files, repeated UI structure, repeated behavior, and large-view pressure.
120
+ - Recommended extractions: component, composable, view split, reuse existing API, or no action.
121
+ - Post-change proof: commands rerun, candidate pairs resolved or accepted, migration completeness checked, and `diff-gate` result.
122
+
123
+ ## Stable Management Calibration
124
+
125
+ When validating against Stable Management, use these known shapes as calibration examples, not hard-coded rules:
126
+
127
+ - `IncidentCategoriesPanel.vue` and `RecordLabelsPanel.vue` should read as both component and behavior pressure.
128
+ - `CardActionMenu.vue` and `CardStatusMenu.vue` should read as behavior/composable pressure.
129
+ - `HorseProfileFarrierVisitsSection.vue` and `HorseProfileVetRecordsSection.vue` should read as component pressure without forcing a composable.
130
+ - `InventoryView.vue` and `FacilityBookingView.vue` should count linked external script pressure when measuring large views.
@@ -1,2 +0,0 @@
1
- import{a as y}from"./chunk-IVAIPXNO.js";function R(D,k={}){let{limit:x=10,scope:M,minDepth:v=3}=k,a=y(D,M),u=new Map,c=[],l=new Map,r=new Map,g=new Set,f=[],h=0;for(let t of a.keys()){if(l.has(t))continue;let n=[],s=(a.get(t)??new Set).values();for(l.set(t,h),r.set(t,h),h+=1,f.push(t),g.add(t),n.push({node:t,iter:s,pendingChild:null});n.length>0;){let e=n[n.length-1];if(e.pendingChild!==null){let d=e.pendingChild;e.pendingChild=null,r.set(e.node,Math.min(r.get(e.node),r.get(d)))}let o=e.iter.next();if(o.done){if(r.get(e.node)===l.get(e.node)){let d=[];for(;;){let p=f.pop();if(g.delete(p),d.push(p),u.set(p,c.length),p===e.node)break}c.push(d)}n.pop();continue}let i=o.value;if(l.has(i))g.has(i)&&r.set(e.node,Math.min(r.get(e.node),l.get(i)));else{l.set(i,h),r.set(i,h),h+=1,f.push(i),g.add(i);let d=(a.get(i)??new Set).values();e.pendingChild=i,n.push({node:i,iter:d,pendingChild:null})}}}let m=new Map,w=new Array(c.length);for(let t=0;t<c.length;t++)w[t]=c[t].length,m.set(t,new Set);for(let[t,n]of a){let s=u.get(t);for(let e of n){let o=u.get(e);o!==s&&m.get(s).add(o)}}let S=new Array(c.length),I=new Array(c.length);for(let t=0;t<c.length;t++){let n=[],s=0;for(let e of m.get(t)){let o=I[e];o>s&&(s=o,n=S[e])}S[t]=[t,...n],I[t]=w[t]+s}function A(t){return S[t]}let F=c.map(t=>[...t].sort()),C=new Set,b=[];for(let t=0;t<c.length;t++){let n=A(t),s=[];for(let o of n)s.push(...F[o]);if(s.length<v)continue;let e=s.join(" ");C.has(e)||(C.add(e),b.push({chain:s,depth:s.length}))}return b.sort((t,n)=>n.depth-t.depth),b.slice(0,x)}export{R as a};
2
- //# sourceMappingURL=chunk-4DAPXOWD.js.map
@@ -1,2 +0,0 @@
1
- import{a as d,c as f,e as u,s as p}from"./chunk-O6KCZPJQ.js";var m={0:"UnspecifiedKind",1:"AbstractMethod",2:"Accessor",3:"Array",4:"Assertion",5:"AssociatedType",6:"Attribute",7:"Axiom",8:"Boolean",9:"Class",10:"Constant",11:"Constructor",12:"Contract",13:"DataFamily",14:"DefinitionMacro",15:"Delegate",16:"Enum",17:"EnumMember",18:"Error",19:"Event",20:"Fact",21:"Field",22:"File",23:"Function",24:"Getter",25:"Grammar",26:"Instance",27:"Interface",28:"Key",29:"Lang",30:"Lemma",31:"Library",32:"Macro",33:"Method",34:"MethodAlias",35:"MethodReceiver",36:"MethodSpecification",37:"Message",38:"Modifier",39:"Module",40:"Namespace",41:"Null",42:"Number",43:"Object",44:"Operator",45:"Package",46:"PackageObject",47:"Parameter",48:"ParameterLabel",49:"Pattern",50:"Predicate",51:"Property",52:"Protocol",53:"ProtocolMethod",54:"PureVirtualMethod",55:"Quasiquoter",56:"SelfParameter",57:"Setter",58:"Signature",59:"SingletonClass",60:"SingletonMethod",61:"StaticDataMember",62:"StaticEvent",63:"StaticField",64:"StaticMethod",65:"StaticProperty",66:"StaticVariable",67:"String",68:"Struct",69:"Subscript",70:"Tactic",71:"Theorem",72:"ThisParameter",73:"Trait",74:"TraitMethod",75:"Type",76:"TypeAlias",77:"TypeClass",78:"TypeClassMethod",79:"TypeFamily",80:"TypeParameter",81:"Union",82:"Value",83:"Variable"},c=new Map;for(let[e,i]of Object.entries(m))c.set(i.toLowerCase(),Number(e));function y(e){let i=parseInt(e,10);if(!isNaN(i))return i;let s=e.toLowerCase(),n=c.get(s);if(n!==void 0)return n;for(let[r,o]of c)if(r.includes(s))return o;return null}function K(e,i,s={}){let{scope:n,limit:r=100}=s,o=y(i);return o===null?[]:b(e,n).map(t=>({row:t,resolvedKind:g(t)})).filter(t=>t.resolvedKind===o).slice(0,r).map(({row:t,resolvedKind:l})=>({symbol:t.symbol,shortName:f(t.symbol),kind:l,kindName:m[l]??"Unknown",relativePath:t.relative_path,startLine:t.start_line,endLine:t.end_line}))}function P(e,i={}){let s=new Map;for(let n of b(e,i.scope)){let r=g(n);r===null||r===0||s.set(r,(s.get(r)??0)+1)}return[...s.entries()].sort((n,r)=>r[1]-n[1]||n[0]-r[0]).map(([n,r])=>({kind:n,kindName:m[n]??"Unknown",count:r}))}function b(e,i){return p(e,{scope:i}).map(S)}function S(e){return{symbol:e.symbol,kind:e.kind,documentation:e.documentation,enclosing_symbol:e.enclosingSymbol,relative_path:e.relativePath,start_line:e.startLine,end_line:e.endLine}}function g(e){return e.kind!==null&&e.kind!==0?h(e.kind,e.symbol,e.documentation):k(e.symbol,e.documentation,e.enclosing_symbol)}function h(e,i,s){let n=(s??"").toLowerCase();if(u(i)==="type"){if(n.includes("type "))return 76;if(n.includes("interface "))return 27;if(n.includes("struct "))return 68;if(n.includes("trait "))return 73;if(n.includes("class "))return 9}return e}function k(e,i,s){let n=d(e);if("kind"in n)return null;let r=n.descriptors,o=r[r.length-2]??null,a=u(e),t=(i??"").toLowerCase();return a==="type"?t.includes("type ")?76:t.includes("interface ")?27:t.includes("struct ")?68:t.includes("trait ")?73:(t.includes("class "),9):a==="method"?o?.suffix==="type"?33:23:a==="namespace"?39:a!=="term"?null:t.includes("async def ")||t.includes("def ")?23:(s?u(s):o?.suffix??null)==="type"?21:83}export{K as a,P as b};
2
- //# sourceMappingURL=chunk-4JQFTUKD.js.map
@@ -1,3 +0,0 @@
1
- import{b as D,c as $,d as Q,f as v,g as A,h as N,m as y,n as d,q as w,w as f}from"./chunk-O6KCZPJQ.js";function re(e,n){let t=Z(e,n.trim());if(t)return t;let i=q(e,n);if(i)return i;let o=F(e,n);return o||j(e,n)}function F(e,n){let t=x(n),i=I(t);if(!i)return null;let o=`%${i.path}%`,r=i.leaf,c=O(e,o,r,t)[0];return c?f(e,c):null}function O(e,n,t,i){let o=w([],[...z(e,n,t),...W(e,n,t)]).filter(r=>!e.isIgnored(r.relative_path)).filter(r=>h(r,i)>1);return o.sort((r,a)=>h(a,i)-h(r,i)||r.end_line-r.start_line-(a.end_line-a.start_line)||r.start_line-a.start_line||r.symbol.localeCompare(a.symbol)),o}function z(e,n,t){return y(e,{where:"d.relative_path LIKE ? AND (gs.display_name = ? OR gs.symbol LIKE ?)",params:[n,t,`%/${t}.%`]})}function W(e,n,t){return d(e,{where:"d.relative_path LIKE ? AND (gs.display_name = ? OR gs.symbol LIKE ?)",params:[n,t,`%/${t}.%`]})}function j(e,n){let t=x(n),i=U(n),o=H(e,i),r=V(o,n,t);if(r&&!e.isIgnored(r.relative_path))return f(e,r);let a=null;for(let c of o){if(e.isIgnored(c.relative_path))continue;let l=J(c,n,t,i);l<=0||(!a||l>a.score)&&(a={row:c,score:l})}return a?f(e,a.row):null}function q(e,n){let t=n.match(/^(.+):(\d+)-(\d+)$/);if(!t)return null;let[,i,o,r]=t,a=Math.max(0,parseInt(o,10)-1),c=Math.max(a,parseInt(r,10)-1),l=T(e,i,a,c)??X(e,i,a,c);return l&&!e.isIgnored(l.relative_path)?f(e,l):null}function T(e,n,t,i){return y(e,{where:"d.relative_path LIKE ? AND der.start_line <= ? AND der.end_line >= ?",params:[`%${n}%`,t,i],orderBy:"(der.end_line - der.start_line) ASC",limit:1})[0]}function X(e,n,t,i){return d(e,{where:"d.relative_path LIKE ? AND c.start_line <= ? AND c.end_line >= ?",params:[`%${n}%`,t,i],orderBy:"(MAX(c.end_line) - MIN(c.start_line)) ASC",limit:1})[0]}function Z(e,n){let i=y(e,{where:"gs.symbol = ?",params:[n],orderBy:"d.relative_path, der.start_line",limit:1})[0]??d(e,{where:"gs.symbol = ?",params:[n],orderBy:"d.relative_path, start_line",limit:1})[0];return!i||e.isIgnored(i.relative_path)?null:f(e,i)}function ae(e,n){if("symbol"in n&&"relativePath"in n)return n;let t=G(e,n.symbolId)[0];return t?f(e,t):null}function G(e,n){let t=y(e,{where:"gs.id = ?",params:[n],orderBy:"der.start_line, der.end_line"}),i=d(e,{where:"gs.id = ?",params:[n],orderBy:"start_line, end_line"});return w(t,i)}function H(e,n){let t=n.map(()=>"(gs.symbol LIKE ? OR d.relative_path LIKE ? OR COALESCE(gs.display_name, '') LIKE ?)"),i=n.flatMap(c=>{let l=`%${c}%`;return[l,l,l]}),o=t.join(`
2
- AND `),r=y(e,{where:o,params:i,limit:200}),a=d(e,{where:o,params:i,limit:200});return w(r,a)}function J(e,n,t,i){let o=n.trim(),r=t,a=r.replace(/\(\)$/,""),c=n.toLowerCase(),l=t.toLowerCase(),S=l.replace(/\(\)$/,""),k=e.symbol,C=$(e.symbol),b=Q(e.symbol),E=e.display_name??"",g=e.symbol.toLowerCase(),u=C.toLowerCase(),m=b.toLowerCase(),R=E.toLowerCase(),p=e.relative_path.toLowerCase(),K=/[/:.]/.test(t),M=I(t),_=M?.leaf.toLowerCase(),s=0;return(k===o||k===r)&&(s+=1150),(C===o||C===r)&&(s+=1100),E===a&&(s+=1180),b===a&&(s+=1160),(`${b}()`===o||`${b}()`===r)&&(s+=955),(g===c||g===l)&&(s+=1e3),(u===c||u===l)&&(s+=950),(p===c||p===l)&&(s+=925),(p.endsWith(`/${l}`)||p.endsWith(`/${c}`))&&(s+=875),R===S&&(s+=850),m===S&&(s+=825),(`${m}()`===c||`${m}()`===l)&&(s+=820),(u.endsWith(`:${l}`)||u.endsWith(`:${S}`)||u.endsWith(`:${S}()`))&&(s+=800),g.includes(l)&&(s+=120),u.includes(l)&&(s+=140),p.includes(l)&&(s+=140),R.includes(l)&&(s+=110),i.every(B=>{let L=B.toLowerCase();return g.includes(L)||u.includes(L)||p.includes(L)||R.includes(L)})&&(s+=100+i.length*15),M&&p.includes(M.path.toLowerCase())&&(s+=360,_&&(m===_||`${m}()`===_||`${m}()`==`${_}()`)&&(s+=700),v(e.symbol)&&(s+=180)),A(e.symbol)&&m===S&&(s+=60),!K&&N(e.symbol)&&(s-=160),s-=Math.min(50,Math.max(0,e.end_line-e.start_line)),s}function I(e){let n=e.trim().replace(/\\/g,"/"),t=n.lastIndexOf("/");if(t<=0||t===n.length-1)return null;let i=n.slice(t+1).replace(/\(\)$/,"");return!i||i.includes(".")?null:{path:n.slice(0,t),leaf:i}}function x(e){return e.trim().replace(/\(\)$/,"").replace(/\(.*$/,"")}function U(e){let n=x(e),t=n.split(/[^A-Za-z0-9_]+/).map(i=>i.trim()).filter(i=>i.length>0);return t.length>0?[...new Set(t)]:[n]}function V(e,n,t){let i=n.trim(),o=e.filter(r=>{let a=$(r.symbol),c=(r.display_name??"").trim();return r.symbol===i||a===i||a===t||c===i||c===t||`${c}()`===i||h(r,t)>1||r.relative_path===i});return o.length===0?null:(o.sort((r,a)=>h(a,t)-h(r,t)||r.end_line-r.start_line-(a.end_line-a.start_line)||r.relative_path.localeCompare(a.relative_path)||r.symbol.localeCompare(a.symbol)),o[0]??null)}function h(e,n){let t=I(n);if(!t)return 0;let i=e.relative_path.toLowerCase(),o=Q(e.symbol).toLowerCase(),r=t.path.toLowerCase(),a=t.leaf.toLowerCase();return i.includes(r)?o!==a?1:v(e.symbol)?D(e.symbol)===null?5:4:D(e.symbol)===null?3:2:0}export{re as a,Z as b,ae as c};
3
- //# sourceMappingURL=chunk-4MHT7LKP.js.map
@@ -1,3 +0,0 @@
1
- import{a as L}from"./chunk-SJR4SB7B.js";import{a as d}from"./chunk-B32FX5KB.js";import{a as B}from"./chunk-6IGXZZQ4.js";import{a as G}from"./chunk-AQYBOORI.js";import{a as I}from"./chunk-WN5Z3UVT.js";import{a as F}from"./chunk-BUAC4Q4G.js";import{a as v}from"./chunk-VDY4HYNK.js";import{a as E}from"./chunk-MCW36F2D.js";import{a as _}from"./chunk-6VL4AIEO.js";import{a as A,b as x}from"./chunk-OAI5GEIN.js";import{b as R}from"./chunk-SYKCO25G.js";import{c as N}from"./chunk-HXXRN77A.js";import{a as w}from"./chunk-NGI4V4AB.js";import{b as $}from"./chunk-6QVCPUK6.js";import{a as S}from"./chunk-JODYQDE4.js";import{f as D}from"./chunk-R3G6ERW7.js";import{a as C}from"./chunk-4HTJZC6G.js";import{a as k}from"./chunk-IW7ASGVF.js";import{e as g,f as y}from"./chunk-QYKKTYBN.js";import{existsSync as H}from"fs";import{existsSync as M,readFileSync as O,writeFileSync as U}from"fs";import{isAbsolute as q,join as K}from"path";var Y=75e3,z=5e3,J=2500;function V(e){let i=G(e);return i.symbols>=Y||i.documents>=z?J:void 0}var W=".scipquery-baseline.json";function b(e,i){return i&&q(i)?i:K(e.config.projectRoot,i??W)}function P(e,i={}){let{scope:t}=i,o=V(e),s=[],a=$(e,{scope:t,...d.dead,scanLimit:o});for(let n of a.symbols)g(e,n.relativePath)||y(e,n.symbol,n.relativePath)||n.kind==="dead-code"&&s.push(`dead:${n.relativePath}:${n.shortName}`);for(let n of F(e,{scope:t,...d.isolated,scanLimit:o}))g(e,n.relativePath)||y(e,n.symbol,n.relativePath)||s.push(`isolated:${n.relativePath}:${n.shortName}`);for(let n of C(e,{scope:t}))n.kind==="real"&&s.push(`cycle:${Q(n.path)}`);for(let n of x(e,{scope:t,...d.similar,scanLimit:o}))s.push(`similar:${[n.symbolA,n.symbolB].sort().join("|")}`);for(let n of E(e,{scope:t,...d.extract,scanLimit:o}))s.push(`extract:${n.relativePath}:${n.shortName}`);for(let n of I(e,{scope:t,...d.wrappers,scanLimit:o}))s.push(`wrapper:${n.file}:${n.shortName}`);for(let n of v(e,{scope:t,...d.passthroughs,scanLimit:o}))s.push(`passthrough:${n.file}:${n.shortName}`);for(let n of B(e,{scope:t,...d.stale,scanLimit:o}))s.push(`stale:${n.file}:${n.shortName}`);for(let n of w(e,{scope:t,...d.drift}).results)n.kind!=="pattern-deviation"&&s.push(`drift:${n.kind}:${n.file}:${n.dep}`);return[...new Set(s)].sort()}function Q(e){if(e.length===0)return"";let i=0;for(let t=1;t<e.length;t++)e[t]<e[i]&&(i=t);return[...e.slice(i),...e.slice(0,i)].join(">")}function Se(e,i={}){let t=P(e,{scope:i.scope}),o=b(e,i.path);return U(o,JSON.stringify({version:1,findings:t},null,2)+`
2
- `),{path:o,findingCount:t.length}}function T(e,i={}){let t=b(e,i.path);if(!M(t))throw new Error(`No baseline found at ${t}. Create one with: scip-query health --write-baseline`);let o=JSON.parse(O(t,"utf-8")),s=new Set(o.findings??[]),a=P(e,{scope:i.scope}),n=new Set(a);return{baselinePath:t,baselineCount:s.size,current:a,newFindings:a.filter(r=>!s.has(r)),fixedFindings:[...s].filter(r=>!n.has(r))}}var Be=["echo","incomplete-migration","co-change-partner","doc-reference","unused-params","new-dead","baseline"];function Ge(e,i={}){let t=i.base??"HEAD",{minTogether:o=6,minConfidence:s=.6,maxEchoChecks:a=Number.POSITIVE_INFINITY,maxHelpers:n=Number.POSITIVE_INFINITY,minSimilarity:r=.8}=i,c=new Set(i.skip??[]),h=R(e,{base:t}),l=h.changedFiles,p=new Set(l),f={base:t,changedFiles:l,changedSymbols:h.changedSymbols.length,checksRun:[],skipped:[],findings:[],note:h.summary.note};if(l.length===0)return f;let m=(u,j)=>{if(c.has(u)){f.skipped.push({check:u,reason:"skipped via --skip"});return}j()};return m("echo",()=>X(e,h.changedSymbols,p,a,r,f)),m("incomplete-migration",()=>Z(e,t,n,f)),m("co-change-partner",()=>ee(e,p,o,s,f)),m("doc-reference",()=>ne(e,p,f)),m("unused-params",()=>ie(e,l,f)),m("new-dead",()=>te(e,h.changedSymbols,f)),m("baseline",()=>oe(e,f)),f}function X(e,i,t,o,s,a){a.checksRun.push("echo");for(let n of i.slice(0,o)){let r=A(e,n.symbol,{minSimilarity:s,limit:3});for(let c of r){let h=c.fileA===n.file?c.fileB:c.fileA,l=c.fileA===n.file?c.shortNameB:c.shortNameA;t.has(h)||a.findings.push({check:"echo",message:`${n.shortName} (${n.file}) is ${Math.round(c.similarity*100)}% similar to established ${l} (${h})`,remediation:`Extend or reuse ${l} instead of keeping the re-implementation.`})}}i.length>o&&a.skipped.push({check:"echo",reason:`echo check capped at ${o} of ${i.length} changed symbols`})}function Z(e,i,t,o){let s=_(e,{base:i,maxHelpers:t});if(!s.available){o.skipped.push({check:"incomplete-migration",reason:"no git history"});return}o.checksRun.push("incomplete-migration"),s.note&&o.skipped.push({check:"incomplete-migration",reason:s.note});for(let a of s.findings){let n=a.leftovers.map(r=>`${r.shortName} (${r.file}, ${Math.round(r.containment*100)}%)`).join(", ");o.findings.push({check:"incomplete-migration",message:`new helper ${a.helperShortName} (${a.helperFile}) is wired into ${a.migratedFiles.length} file(s), but ${a.leftovers.length} similar un-migrated site(s) remain: ${n}`,remediation:`Migrate the remaining sites to ${a.helperShortName}, or confirm they are intentionally different.`})}}function ee(e,i,t,o,s){let a=D(e,{minTogether:t,minConfidence:0});if(!a){s.skipped.push({check:"co-change-partner",reason:"no git history"});return}s.checksRun.push("co-change-partner");let n=new Set;for(let r of a){let c=i.has(r.fileA),h=i.has(r.fileB);if(c===h)continue;let l=c?r.fileA:r.fileB,p=c?r.fileB:r.fileA,f=c?r.changesA:r.changesB,m=f>0?r.together/f:0;if(m<o||S(p)||S(l)||!H(`${e.config.projectRoot}/${p}`))continue;let u=`${l}|${p}`;n.has(u)||(n.add(u),s.findings.push({check:"co-change-partner",message:`${l} changed, but ${p} did not \u2014 they change together ${r.together}x (${Math.round(m*100)}% of the time)`,remediation:`Update ${p} alongside this change, or confirm the coupling no longer holds.`}))}}function ne(e,i,t){t.checksRun.push("doc-reference");for(let o of N(e,i))i.has(o.doc)||t.findings.push({check:"doc-reference",message:`${o.doc} cites ${o.cited.join(", ")} \u2014 changed in this diff, doc untouched`,remediation:`Re-read ${o.doc} and update its claims, or update its citations.`})}function ie(e,i,t){t.checksRun.push("unused-params");for(let o of L(e,{files:i,limit:50}))t.findings.push({check:"unused-params",message:`${o.shortName} (${o.file}) has trailing unused parameter(s): ${o.unusedTrailing.join(", ")}`,remediation:"Drop the unused trailing parameters and their call-site arguments."})}function te(e,i,t){t.checksRun.push("new-dead");let o=new k(e);for(let s of i)s.fanIn>0||o.fileKind(s.file)!=="test"&&(g(e,s.file)||y(e,s.symbol,s.file)||t.findings.push({check:"new-dead",message:`${s.shortName} (${s.file}) was changed but has zero indexed consumers`,remediation:"Wire it up, or remove it before it becomes permanent dead code."}))}function oe(e,i){if(!H(b(e))){i.skipped.push({check:"baseline",reason:"no .scipquery-baseline.json \u2014 run health --write-baseline to enable"});return}i.checksRun.push("baseline");let t=T(e);for(let o of t.newFindings)i.findings.push({check:"baseline",message:`new finding vs committed baseline: ${o}`,remediation:"Fix the finding, or knowingly accept it via health --write-baseline."})}export{P as a,Se as b,T as c,Be as d,Ge as e};
3
- //# sourceMappingURL=chunk-5OHZEO3U.js.map
@@ -1,34 +0,0 @@
1
- import{b as P,g as F,h as H,i as G,n as W}from"./chunk-VGBSY6N7.js";import{a as $,b as J,d as j,f as B}from"./chunk-ZF6P2NAT.js";import{a as v}from"./chunk-IVAIPXNO.js";import{d as k,f as O,r as N,s as T,v as x}from"./chunk-O6KCZPJQ.js";import{a as C,c as I,i as M}from"./chunk-OH5HIAID.js";import{a as L,b as _,e as A,f as D}from"./chunk-ISCKLDSS.js";import{c as E,d as w}from"./chunk-VDZL45XI.js";function Me(e,n,o={}){let i=U(e,[n],{additive:o.additive,semantic:o.semantic}),s=o.callableOnly?(i.get(n.symbolId)??[]).filter(r=>O(r.symbol)):i.get(n.symbolId)??[];return typeof o.limit=="number"?s.slice(0,o.limit):s}function Re(e,n,o={}){let i=q(e)?Q(e,n,{semantic:o.semantic!==!1}):z(e).get(n.symbolId)??[];return typeof o.limit=="number"?i.slice(0,o.limit):i}var V=w("caller-rows",{clearGroups:["whole-project"]}),Y=2e4;function q(e){return(e.get("SELECT COUNT(*) AS count FROM global_symbols")?.count??0)>Y}function z(e){return V.get(e,()=>{let n=T(e),o=U(e,n),i=new Map;for(let l of n)i.set(l.symbol,l.symbolId);let s=new Map,r=new Map;for(let l of n){let a=o.get(l.symbolId);if(!(!a||a.length===0))for(let m of a){let t=i.get(m.symbol);if(t===void 0||t===l.symbolId)continue;let c=s.get(t);c||(c=[],s.set(t,c),r.set(t,new Set));let u=`${l.symbol}|${l.relativePath}`;r.get(t).has(u)||(r.get(t).add(u),c.push({symbol:l.symbol,file:l.relativePath,source:"caller-map-inversion"}))}}return s})}function Q(e,n,o){let i=[],s=new Set,r=a=>{if(a.symbol===n.symbol)return;let m=`${a.symbol}|${a.file}`;s.has(m)||(s.add(m),i.push(a))};for(let a of W(e,n))a.file!==n.relativePath&&r({symbol:a.enclosingSymbol??a.file,file:a.file,source:"resolved-reference"});let l=o.semantic?X(e,n):null;if(l)for(let a of j(e,l)){if(a.file===n.relativePath||e.isIgnored(a.file))continue;let m=x(N(e,a.file),a.line);r({symbol:m?.symbol??a.file,file:a.file,source:"semantic-reference"})}return i}function X(e,n){return e.get(`SELECT
2
- d.id AS documentId,
3
- gs.id AS symbolId,
4
- gs.symbol,
5
- d.relative_path AS relativePath,
6
- COALESCE(der.start_line, c.start_line) AS startLine,
7
- COALESCE(der.end_line, c.end_line) AS endLine,
8
- COALESCE(gs.display_name, '') AS leaf,
9
- NULL AS parentTypeName,
10
- CASE WHEN gs.kind IN (6, 12, 13) OR gs.symbol LIKE '%().' THEN 1 ELSE 0 END AS isFunctionLike,
11
- CASE WHEN gs.kind IN (5, 8, 11) THEN 1 ELSE 0 END AS isTypeLike,
12
- gs.kind AS kind,
13
- gs.documentation AS documentation,
14
- gs.enclosing_symbol AS enclosingSymbol
15
- FROM global_symbols gs
16
- LEFT JOIN defn_enclosing_ranges der ON der.symbol_id = gs.id
17
- LEFT JOIN chunks c ON c.document_id = der.document_id
18
- JOIN documents d ON d.id = COALESCE(der.document_id, c.document_id)
19
- WHERE gs.id = ?
20
- LIMIT 1`,n.symbolId)??null}function U(e,n,o={}){if(n.length===0)return new Map;let i=o.additive??!1,s=[],r=[];for(let c of n)I(c.relativePath)&&M(e,c.relativePath)!==null?s.push(c):r.push(c);let l=new Map,a=new Map,m=c=>{for(let[u,g]of c){let b=l.get(u);b||(b=[],l.set(u,b));let y=a.get(u);y||(y=new Set,a.set(u,y));for(let d of g){let f=`${d.symbol}|${d.chunkId}`;y.has(f)||(y.add(f),b.push(d))}}};s.length>0&&m(oe(e,s)),o.semantic!==!1&&m(re(Z(e,n)));let t=i?n:r;return t.length>0&&m(ae(e,t)),l}function Z(e,n){let o=new Map,i=[],s=[];for(let l of n){if(!$(l.relativePath))continue;let a=C(e,l.relativePath);if(!a){s.push(l);continue}let m=_(e,l.relativePath,a),t=te(e,l.relativePath),c=A(e,l.relativePath,l.symbol,m,t);if(c!==null){let u=ee(c);if(u){u.length>0&&o.set(l.symbolId,u);continue}}i.push({def:l,contentHash:m,depsDigest:t})}if(i.length===0&&s.length===0)return o;let r=B(e,[...s,...i.map(l=>l.def)]);for(let[l,a]of r)o.set(l,a);return J(e).availability().available&&D(e,i.map(l=>({relativePath:l.def.relativePath,symbol:l.def.symbol,contentHash:l.contentHash,depsDigest:l.depsDigest,payload:JSON.stringify(r.get(l.def.symbolId)??[])}))),o}function ee(e){try{return JSON.parse(e)}catch{return null}}var ne=E("semantic-deps-digest",{clearGroups:["whole-project","source-file"]});function te(e,n){return ne.get(e,n,()=>{let i=[...v(e).get(n)??[]].sort().map(s=>`${s}:${_(e,s,C(e,s))}`);return L(i.join("|"))})}function oe(e,n){let o=new Map,i=le(n,o),s=G(e);for(let[r,l]of i){let a=M(e,r);if(a)for(let m of a){let t=ie(l,m.line);if(!t)continue;let c=se(e,r,s,m.calleeLeaf,m.memberAccess);c&&c.symbol!==t.symbol&&o.get(t.symbolId).push({symbol:c.symbol,file:c.file,chunkId:m.line,source:"ast-callsite"})}}return o}function le(e,n){let o=new Map;for(let i of e){let s=o.get(i.relativePath);s?s.push(i):o.set(i.relativePath,[i]),n.set(i.symbolId,[])}for(let i of o.values())i.sort((s,r)=>s.endLine-s.startLine-(r.endLine-r.startLine));return o}function ie(e,n){return e.find(o=>n>=o.startLine&&n<=o.endLine)??null}function se(e,n,o,i,s){let r=F(n,o.get(i)??[]);return r.length===0?null:H(e,n,r,s)}function ae(e,n){if(n.length===0)return new Map;let o=e.all(`SELECT c.document_id, c.id AS chunk_id, c.start_line, c.end_line, m.symbol_id
21
- FROM mentions m
22
- JOIN chunks c ON m.chunk_id = c.id
23
- WHERE m.role != 1`),i=new Map;for(let t of o)i.has(t.document_id)||i.set(t.document_id,[]),i.get(t.document_id).push(t);let s=new Map(e.all("SELECT id, relative_path FROM documents").map(t=>[t.id,t.relative_path])),r=new Map,l=e.all(`SELECT gs.id AS symbol_id, gs.symbol,
24
- COALESCE(der.document_id, def_chunk.document_id) AS document_id
25
- FROM global_symbols gs
26
- LEFT JOIN defn_enclosing_ranges der ON der.symbol_id = gs.id
27
- LEFT JOIN (
28
- SELECT m.symbol_id, MIN(c.document_id) AS document_id
29
- FROM mentions m
30
- JOIN chunks c ON m.chunk_id = c.id
31
- WHERE m.role = 1
32
- GROUP BY m.symbol_id
33
- ) def_chunk ON def_chunk.symbol_id = gs.id`);for(let t of l)r.has(t.symbol_id)||r.set(t.symbol_id,{symbol:t.symbol,file:t.document_id!==null?s.get(t.document_id)??"":""});let a=new Map,m=s;for(let t of n){let c=i.get(t.documentId)??[],u=new Set,g=[],b=null,y=()=>{if(b)return b;let d=m.get(t.documentId)??"",f=new Set;if(d){let S=P(e,d),h=Math.max(0,t.startLine),R=Math.min(S.length-1,t.endLine);for(let p=h;p<=R;p+=1)for(let K of S[p])f.add(K)}return b=f,f};for(let d of c){if(d.symbol_id===t.symbolId)continue;let f=r.get(d.symbol_id);if(!f)continue;if(!(d.start_line>=t.startLine&&d.end_line<=t.endLine)){if(!(d.start_line<=t.endLine&&d.end_line>=t.startLine))continue;let p=k(f.symbol);if(!p||!y().has(p))continue}let h=`${f.symbol}|${d.chunk_id}`;u.has(h)||(u.add(h),g.push({...f,chunkId:d.chunk_id,source:"scip-chunk"}))}a.set(t.symbolId,g)}return a}function re(e){let n=new Map;for(let[o,i]of e){let s=[];for(let r of i)s.push({symbol:r.symbol,file:r.file,chunkId:-1,source:"semantic-callee"});n.set(o,s)}return n}export{Me as a,Re as b,U as c};
34
- //# sourceMappingURL=chunk-5QJIEYFB.js.map
@@ -1,4 +0,0 @@
1
- import{a as h,b as F,c as w}from"./chunk-WJIS6BNI.js";import{a as M}from"./chunk-V76FCF5F.js";import{a as b}from"./chunk-MX6F756F.js";import{a as P}from"./chunk-IW7ASGVF.js";import{a as S,f as D}from"./chunk-QYKKTYBN.js";import{a as L,c as v,d as p}from"./chunk-O6KCZPJQ.js";import{a as y,j as I}from"./chunk-OH5HIAID.js";function ie(t,e){let{scope:n,minLoc:i=3,maxLoc:s=80,limit:r=30,includeLowConfidence:l=!1,scanLimit:a}=e??{},f=e?.semantic!==!1,o=new P(t),d=o.scopedDefinitions(n),g=V(o,n),x={high:0,medium:1,low:2};return M({candidates:()=>$(t,o,d,{minLoc:i,maxLoc:s}),orderCandidates:(c,u)=>b(u)-b(c)||c.relativePath.localeCompare(u.relativePath),scanLimit:a,prepare:c=>({consumerFileMap:A(o,c,{semantic:f}),singletonBackedClassIds:O(t,o,d,c,{semantic:f}),candidateIndex:B(c)}),evaluate:(c,u)=>{if(u.singletonBackedClassIds.has(c.symbolId))return null;let m=N(t,c,u.consumerFileMap,u.candidateIndex);if(m.transitivelyReachable||m.realConsumers.length>1||m.realConsumers.length===0&&m.barrelConsumers>0||!Z(m.definition,m.realConsumers.length,g))return null;let C=j(t,m);return!l&&C.confidence==="low"?null:C},orderResults:(c,u)=>x[c.confidence]-x[u.confidence]||u.loc-c.loc||c.file.localeCompare(u.file)||c.startLine-u.startLine,limit:r})}function $(t,e,n,i){return n.filter(s=>s.isTypeLike&&b(s)>=i.minLoc).filter(s=>b(s)<=i.maxLoc).filter(s=>!t.isIgnored(s.relativePath)).filter(s=>S(s.relativePath)!=="test").filter(s=>!D(t,s.symbol,s.relativePath)).filter(s=>!H(s.symbol)).filter(s=>!e.hasSuppressionComment(s))}function A(t,e,n){return h(t,e,{semantic:n.semantic})}function B(t){let e=new Map;for(let n of t){let i=e.get(n.relativePath);i||(i=new Map,e.set(n.relativePath,i));let s=p(n.symbol);s&&i.set(s,n)}return e}function N(t,e,n,i){let r=[...n.get(e.symbolId)??new Set].filter(d=>d!==e.relativePath&&!t.isIgnored(d)),{realConsumers:l,barrelConsumers:a,importOnlyConsumers:f}=F(t,e,r),o=_(t,e,n,i);return{definition:e,realConsumers:l,barrelConsumers:a+f,transitivelyReachable:o}}function j(t,e){let n=k(t,e.definition.relativePath,e.definition.startLine),i=T(e.definition.relativePath)?!0:q(t,e.definition),{confidence:s,reason:r}=G(e.realConsumers.length,n,i);return{symbol:e.definition.symbol,shortName:v(e.definition.symbol),file:e.definition.relativePath,startLine:e.definition.startLine,endLine:e.definition.endLine,loc:b(e.definition),consumers:e.realConsumers.length,barrelConsumers:e.barrelConsumers,kind:n,definerUsesType:i,confidence:s,reason:r}}function O(t,e,n,i,s){let r=W(t,U(n),i),l=r.map(o=>o.singleton);if(r.length===0)return new Set;let a=h(e,l,{semantic:s.semantic}),f=new Set;for(let{singleton:o,classId:d}of r)E(t,o,a)&&f.add(d);return f}function U(t){let e=new Map;for(let n of t){let i=p(n.symbol);i&&e.set(R(n.relativePath,i),n)}return e}function W(t,e,n){let i=[];for(let s of n){let r=z(t,e,s);r&&i.push({singleton:r,classId:s.symbolId})}return i}function z(t,e,n){if(k(t,n.relativePath,n.startLine)!=="class")return null;let i=p(n.symbol);if(!i)return null;let s=K(t,n.relativePath,i);return s?e.get(R(n.relativePath,s))??null:null}function E(t,e,n){let i=p(e.symbol),s=n.get(e.symbolId);return!i||!s?!1:[...s].some(r=>r!==e.relativePath&&!t.isIgnored(r)&&!w(t,r,i))}function R(t,e){return`${t}\0${e}`}function K(t,e,n){let i=y(t,e);if(!i)return null;let s=n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=new RegExp(`\\bexport\\s+const\\s+([A-Za-z_$][\\w$]*)\\s*=\\s*new\\s+${s}\\s*\\(`);return i.match(r)?.[1]??null}function V(t,e){return new Set(t.scopedDefinitions(e).filter(n=>n.isFunctionLike).map(n=>n.relativePath))}function H(t){let e=L(t);if("kind"in e)return!1;let n=e.descriptors;if(n.length<2)return!1;let i=n[n.length-1],s=n[n.length-2];return i?.suffix==="type"&&s?.suffix==="type"}function T(t){let n=(t.split("/").pop()??"").replace(/\.[^.]+$/,"");return!!(n==="types"||n.endsWith("-types")||n==="models"||n==="schema"||n==="common"||n==="protocol"||n==="proto"||n==="dto"||n==="mod"||n==="contracts"||/(^|\/)types(\/|\.)/.test(t)||/(^|\/)models?(\/|\.)/.test(t)||/(^|\/)proto(?:col)?(\/|\.)/.test(t)||/(^|\/)schema(\/|\.)/.test(t)||/(^|\/)contracts?(\/|\.)/.test(t))}function Z(t,e,n){return!(T(t.relativePath)&&e>0||e===0&&n.has(t.relativePath))}function _(t,e,n,i){let s=I(t,e.relativePath),r=p(e.symbol);if(!r)return!1;let l=s.get(r);if(!l||l.size===0)return!1;let a=i.get(e.relativePath);if(!a)return!1;for(let f of l){let o=a.get(f);if(!o)continue;let d=n.get(o.symbolId);if(d){for(let g of d)if(g!==e.relativePath&&!t.isIgnored(g))return!0}}return!1}function k(t,e,n){let i=y(t,e);if(!i)return"other";let s=i.split(`
2
- `),r=Math.max(0,n-2),l=Math.min(s.length-1,n+2);for(let a=r;a<=l;a++){let o=(s[a]??"").replace(/^\s*\/\/.*$/g,"");if(/\b(?:export\s+)?(?:abstract\s+)?class\s+\w/.test(o))return"class";if(/\b(?:export\s+)?interface\s+\w/.test(o))return"interface";if(/\b(?:export\s+)?type\s+\w/.test(o))return"type";if(/\b(?:export\s+)?(?:const\s+)?enum\s+\w/.test(o))return"enum"}return"other"}function q(t,e){let n=y(t,e.relativePath);if(!n)return!1;let i=p(e.symbol);if(!i)return!1;let s=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),r=new RegExp(`\\b${s}\\b`),l=n.split(`
3
- `);for(let a=0;a<l.length;a++)if(!(a>=e.startLine&&a<=e.endLine)&&r.test(l[a]??""))return!0;return!1}function G(t,e,n){return t===0?{confidence:"high",reason:"unused \u2014 no consumers and defining file has no real usage"}:t===1&&e==="class"?{confidence:"low",reason:"1 consumer + class kind \u2014 likely 1:1 encapsulation, not over-abstraction"}:t===1&&!n?{confidence:"high",reason:"1 consumer + defining file never uses it \u2014 type belongs with its consumer"}:{confidence:"medium",reason:"1 consumer \u2014 single-use abstraction"}}export{ie as a};
4
- //# sourceMappingURL=chunk-6IGXZZQ4.js.map
@@ -1,61 +0,0 @@
1
- import{a as _}from"./chunk-IW7ASGVF.js";import{c as u}from"./chunk-QYKKTYBN.js";import{b as l,c as d}from"./chunk-FVVT7GV6.js";import{c as a,e as m}from"./chunk-O6KCZPJQ.js";import{a as s}from"./chunk-NN3O7TPH.js";function A(e,o={}){let{scope:n,limit:r}=o,t=new _(e),i=h([...b(e,n),...g(e,t,n)]);return y(i),r?i.slice(0,r):i}function b(e,o){let n=[];for(let r of f(e,o)){if(e.isIgnored(r.barrel_path)||e.isIgnored(r.original_path)||u(e,r.barrel_path))continue;let t=R(e,r),i=t?.barrel_consumers??0,c=t?.direct_consumers??0;i!==0||c!==0||n.push({barrelFile:r.barrel_path,symbol:r.symbol,shortName:a(r.symbol),originalFile:r.original_path,barrelConsumers:i,directConsumers:c})}return n}function f(e,o){let n=o?`AND barrel_d.relative_path LIKE '%${o}%'`:"";return e.all(`SELECT DISTINCT
2
- barrel_d.id AS barrel_doc_id,
3
- barrel_d.relative_path AS barrel_path,
4
- gs.id AS symbol_id,
5
- gs.symbol AS symbol,
6
- orig_d.id AS original_doc_id,
7
- orig_d.relative_path AS original_path
8
- FROM mentions m
9
- JOIN chunks c ON m.chunk_id = c.id
10
- JOIN documents barrel_d ON c.document_id = barrel_d.id
11
- JOIN global_symbols gs ON m.symbol_id = gs.id
12
- JOIN (
13
- SELECT m2.symbol_id, c2.document_id
14
- FROM mentions m2
15
- JOIN chunks c2 ON m2.chunk_id = c2.id
16
- WHERE m2.role = 1
17
- GROUP BY m2.symbol_id
18
- ) sym_def ON sym_def.symbol_id = gs.id
19
- JOIN documents orig_d ON sym_def.document_id = orig_d.id
20
- WHERE m.role != 1
21
- AND (barrel_d.relative_path LIKE '%/index.ts'
22
- OR barrel_d.relative_path LIKE '%/index.js'
23
- OR barrel_d.relative_path = 'index.ts'
24
- OR barrel_d.relative_path = 'index.js')
25
- AND orig_d.id != barrel_d.id
26
- ${e.pathExclusionsFor("barrel_d","orig_d")}
27
- ${e.symbolNoiseFor("gs")}
28
- -- Only function-level symbols (ending with ().), not module-level
29
- AND gs.symbol LIKE '%().'
30
- ${n}
31
- ORDER BY barrel_d.relative_path, gs.symbol`)}function R(e,o){return e.get(`SELECT
32
- SUM(CASE WHEN uses_barrel = 1 THEN 1 ELSE 0 END) AS barrel_consumers,
33
- SUM(CASE WHEN uses_barrel = 0 THEN 1 ELSE 0 END) AS direct_consumers
34
- FROM (
35
- SELECT
36
- consumer_d.id AS consumer_doc_id,
37
- MAX(CASE WHEN EXISTS (
38
- SELECT 1
39
- FROM mentions barrel_m
40
- JOIN chunks barrel_c ON barrel_m.chunk_id = barrel_c.id
41
- WHERE barrel_c.document_id = consumer_d.id
42
- AND barrel_m.role != 1
43
- AND barrel_m.symbol_id IN (
44
- SELECT m2.symbol_id
45
- FROM mentions m2
46
- JOIN chunks c2 ON m2.chunk_id = c2.id
47
- WHERE c2.document_id = ?
48
- AND m2.role != 1
49
- )
50
- ) THEN 1 ELSE 0 END) AS uses_barrel
51
- FROM mentions ref_m
52
- JOIN chunks ref_c ON ref_m.chunk_id = ref_c.id
53
- JOIN documents consumer_d ON ref_c.document_id = consumer_d.id
54
- WHERE ref_m.symbol_id = ?
55
- AND ref_m.role != 1
56
- AND consumer_d.id != ?
57
- AND consumer_d.id != ?
58
- ${e.pathExclusionsFor("consumer_d")}
59
- GROUP BY consumer_d.id
60
- )`,o.barrel_doc_id,o.symbol_id,o.barrel_doc_id,o.original_doc_id)}function g(e,o,n){let r=[];for(let t of E(e,n))p(e,t,t)>0||r.push(...S(e,o,t));return r}function E(e,o){return s(e,{scope:o,includeIgnored:!1}).filter(n=>d(e,n).length>0)}function S(e,o,n){return d(e,n).filter(r=>r.sourcePath&&!e.isIgnored(r.sourcePath)).flatMap(r=>x(e,o,n,r.sourcePath))}function x(e,o,n,r){let t=N(o,r);return t?[{barrelFile:n,symbol:t.symbol,shortName:a(t.symbol),originalFile:r,barrelConsumers:0,directConsumers:p(e,r,n)}]:[]}function p(e,o,n){let r=new Set;for(let t of s(e,{includeIgnored:!1}))if(t!==n)for(let i of l(e,t))i.sourcePath===o&&r.add(t);return r.size}function N(e,o){let n=e.definitionsForFile(o);return n.find(r=>m(r.symbol)==="method")??n[0]??null}function h(e){let o=new Set,n=[];for(let r of e){let t=`${r.barrelFile}|${r.symbol}|${r.originalFile}`;o.has(t)||(o.add(t),n.push(r))}return n}function y(e){e.sort((o,n)=>n.directConsumers-o.directConsumers||o.barrelFile.localeCompare(n.barrelFile)||o.shortName.localeCompare(n.shortName))}export{A as a};
61
- //# sourceMappingURL=chunk-6K2JQ2VI.js.map
@@ -1,2 +0,0 @@
1
- import{c as G}from"./chunk-MX6F756F.js";import{a as E}from"./chunk-IW7ASGVF.js";import{a as F,d as N,e as k,f as T}from"./chunk-QYKKTYBN.js";import{a as z}from"./chunk-VDZIEDJB.js";import{c as H,d as U,f as v,j as q}from"./chunk-VGBSY6N7.js";import{b as I}from"./chunk-FVVT7GV6.js";import{c as M,f as A,g as j,h as O,i as B,j as W,r as V,x}from"./chunk-O6KCZPJQ.js";import{c as P,e as _}from"./chunk-OH5HIAID.js";import{a as h}from"./chunk-NN3O7TPH.js";import{b as S}from"./chunk-VDZL45XI.js";var g=new WeakMap;function J(e,n){let t=P(n);return t==="rust"?pe(e,n):t==="typescript"||t==="tsx"||t==="javascript"?de(e,n):[]}var ue=new Set(["describe","it","test","fdescribe","fit","xdescribe","xit","beforeEach","afterEach","beforeAll","afterAll","before","after","suite","bench","benchmark"]);function de(e,n){let t=_(e,n);if(!t)return[];let i=g.get(t);if(i)return i;let r=/(^|\/)(pages|app)\/.+\.(tsx?|jsx?)$/.test(n)||/(^|\/)(layout|page|loading|error|not-found|head|template|default)\.(tsx?|jsx?)$/.test(n),o=/(^|\/)src\/(pages|views|routes)\/.+\.(tsx?|jsx?|vue)$/.test(n),s=!1,c=t.rootNode;for(let u of c.namedChildren){if(u.type!=="expression_statement")continue;let a=u.namedChild(0);if(!a||a.type!=="call_expression")continue;let d=a.namedChild(0);if(!d)continue;let f=d.type==="member_expression"?d.namedChild(d.namedChildCount-1)?.text:d.text;if(f&&ue.has(f)){s=!0;break}}let l=[];s&&l.push({startLine:0,endLine:c.endPosition.row,reason:"TS/JS test file (describe/it/test at top level)"}),(r||o)&&l.push({startLine:0,endLine:c.endPosition.row,reason:r?"Next.js / Remix route file":"Vite/Vue route component"});for(let u of c.namedChildren){let a=null,d=null;if(u.type==="function_declaration")a=u.namedChild(0)?.text??null,d=u;else if(u.type==="export_statement"){let f=u.namedChild(0);f?.type==="function_declaration"&&(a=f.namedChild(0)?.text??null,d=f)}else if(u.type==="lexical_declaration"){let f=u.namedChild(0);if(f?.type==="variable_declarator"){let b=f.namedChild(0)?.text,y=f.namedChild(1);b&&(y?.type==="arrow_function"||y?.type==="function_expression")&&(a=b,d=f)}}a&&/^use[A-Z]/.test(a)&&d&&l.push({startLine:d.startPosition.row,endLine:d.endPosition.row,reason:"React custom hook (use*)"})}return l.push(...K(t,new Set(["function_declaration","method_definition","class_declaration","interface_declaration","type_alias_declaration","enum_declaration","variable_declarator","export_statement"]),new Set(["comment"]))),g.set(t,l),l}var fe=/scip-query[\s:-]*ignore[\s:-]*(?:dead(?:-code)?|stale)?/i;function me(e){return fe.test(e)}function K(e,n,t){let i=[],r=o=>{if(n.has(o.type)&&o.parent){let c=o.parent.children,l=-1;for(let u=0;u<c.length;u+=1)if(c[u].startIndex===o.startIndex&&c[u].type===o.type){l=u;break}if(l>0)for(let u=l-1;u>=0;u-=1){let a=c[u];if(t.has(a.type)){if(me(a.text)){i.push({startLine:o.startPosition.row,endLine:o.endPosition.row,reason:"scip-query suppression comment"});break}continue}if(!(a.type==="attribute_item"||a.type==="inner_attribute_item"))break}}for(let s of o.namedChildren)r(s)};return r(e.rootNode),i}function pe(e,n){let t=_(e,n);if(!t)return[];let i=g.get(t);if(i)return i;let r=[],o=be(t);return o?(g.set(t,o),o):(X(t.rootNode,r,!1,!1),r.push(...K(t,new Set(["function_item","function_signature_item","struct_item","enum_item","union_item","impl_item","mod_item","static_item","const_item"]),new Set(["line_comment","block_comment"]))),r.push(...ve(t.rootNode)),g.set(t,r),r)}function be(e){return Ee(e.rootNode)?[{startLine:0,endLine:e.rootNode.endPosition.row,reason:"generated file (@generated header)"}]:null}function X(e,n,t,i){let r=t,o=i;e.type==="trait_item"&&n.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"trait declaration body (dynamic dispatch)"}),e.type==="impl_item"&&e.childForFieldName("trait")&&(o=!0,n.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"trait impl block (dynamic dispatch)"})),e.type==="function_item"||e.type==="function_signature_item"?ye(e,n,t,i):i&&_e(e)?n.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"trait impl associated item (dynamic dispatch)"}):e.type==="struct_item"||e.type==="enum_item"||e.type==="union_item"?ge(e,n,t):e.type==="mod_item"&&C(e).some(s=>/#\[\s*cfg\s*\(\s*test\s*\)/.test(s))&&(r=!0);for(let s of e.namedChildren)X(s,n,r,o)}function ye(e,n,t,i){let r=C(e),o=null;i?o="trait impl method (dynamic dispatch)":t&&(o="inside #[cfg(test)] mod");for(let s of r){let c=xe(s);if(c){o=c;break}if(Z(s)){o="#[allow(dead_code)]";break}}o&&n.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:o})}function ge(e,n,t){let i=C(e),r=e.namedChildren.find(o=>o.type==="type_identifier")?.text;i.some(Se)&&n.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"#[derive(<reflective>)] \u2014 fields accessed via macro/reflection",containerName:r}),i.some(Z)&&n.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"#[allow(dead_code)]",containerName:r}),t&&n.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"inside #[cfg(test)] mod",containerName:r})}function C(e){let n=e.parent;if(!n)return[];let t=n.children,i=-1;for(let o=0;o<t.length;o+=1)if(t[o].startIndex===e.startIndex&&t[o].type===e.type){i=o;break}if(i<=0)return[];let r=[];for(let o=i-1;o>=0;o-=1){let s=t[o];if(s.type==="attribute_item"||s.type==="inner_attribute_item")r.push(s.text);else{if(s.type==="line_comment"||s.type==="block_comment")continue;break}}return r}var he=[{re:/#\[\s*tauri::command\b/,reason:"#[tauri::command]"},{re:/#\[\s*command\b/,reason:"#[command]"},{re:/#\[\s*test\b/,reason:"#[test]"},{re:/#\[\s*bench\b/,reason:"#[bench]"},{re:/#\[\s*tokio::test\b/,reason:"#[tokio::test]"},{re:/#\[\s*async_std::test\b/,reason:"#[async_std::test]"},{re:/#\[\s*wasm_bindgen\b/,reason:"#[wasm_bindgen]"},{re:/#\[\s*no_mangle\b/,reason:"#[no_mangle]"},{re:/#\[\s*napi\b/,reason:"#[napi]"},{re:/#\[\s*pyfunction\b/,reason:"#[pyfunction]"},{re:/#\[\s*pymethod\b/,reason:"#[pymethod]"},{re:/#\[\s*pyo3\b/,reason:"#[pyo3]"},{re:/#\[\s*cfg\s*\(\s*test\s*\)/,reason:"#[cfg(test)]"},{re:/#\[\s*doc\s*\(\s*hidden\s*\)/,reason:"#[doc(hidden)]"}];function xe(e){return he.find(({re:n})=>n.test(e))?.reason??null}var Re=[/\bSerialize\b/,/\bDeserialize\b/,/\bFromRow\b/,/\bsqlx::FromRow\b/,/\bDeriveEntityModel\b/,/\bIntoSchema\b/,/\bToSchema\b/,/\bDeriveValueType\b/,/\bError\b/,/\bthiserror::Error\b/];function Se(e){return/#\[\s*derive\s*\(/.test(e)?Re.some(n=>n.test(e)):!1}function Z(e){return/#\[\s*allow\s*\(\s*dead_code\s*\)/.test(e)}function _e(e){return e.type==="const_item"||e.type==="type_item"||e.type==="static_item"||e.type==="associated_type"}function ve(e){let n=De(e);if(n.size===0)return[];let t=[];for(let i of e.descendantsOfType("mod_item")){let r=i.childForFieldName("name")?.text;r&&n.has(r)&&t.push({startLine:i.startPosition.row,endLine:i.endPosition.row,reason:'serde `with = "..."` module \u2014 body invoked via reflection',containerName:r})}return t}function Ee(e){for(let n=0;n<Math.min(e.namedChildCount,12);n+=1){let t=e.namedChild(n);if(!t||t.type!=="line_comment"&&t.type!=="block_comment")break;if(/@generated\b/.test(t.text)||/This file is .*generated\b/i.test(t.text)||/Code generated by/i.test(t.text)||/Generated by:\s*https?:\/\/openapi-generator/i.test(t.text)||/openapi-generator/i.test(t.text)&&/Generated by/i.test(t.text))return!0}return!1}var Ce=/^#!?\[\s*serde\s*\(/,$=/\bwith\s*=\s*"([^"]+)"/g;function De(e){let n=new Set;for(let t of e.descendantsOfType("attribute_item")){if(!Ce.test(t.text))continue;$.lastIndex=0;let i;for(;(i=$.exec(t.text))!==null;){let r=i[1],o=r.split("::").pop()??r;o&&n.add(o)}}return n}function Q(e){let n=new Map,t=i=>{let r=n.get(i);if(r)return r;let o=J(e,i);return r={ranges:o.map(s=>({startLine:s.startLine,endLine:s.endLine})),containers:new Set(o.map(s=>s.containerName).filter(s=>!!s))},n.set(i,r),r};return(i,r,o,s)=>{let c=t(i);for(let l of c.ranges)if(r>=l.startLine&&r<=l.endLine)return!0;if(s&&c.containers.has(s))return!0;for(let l of x(o))if(c.containers.has(l))return!0;return!1}}function ze(e,n={}){S(e,{groups:n.semanticProvider===!0?["whole-project","semantic-provider"]:["whole-project"]})}function D(e,n,t={}){S(e,{groups:t.definitions===!0?["source-file","definition-catalog"]:["source-file"],file:n.replace(/\\/g,"/")})}function ee(e,n){return n.isIgnoredPath(e.relativePath)?m("ignored-file"):O(e.symbol)?m("module-like-symbol"):Y(e.symbol)?!e.isFunctionLike&&e.enclosingSymbol&&Y(e.enclosingSymbol)?m("nested-non-callable-value"):!n.includeTests&&!w(e.relativePath)?m("test-file"):!n.includeTests&&n.isExcludedRegion(e.relativePath,e.startLine,e.symbol,e.parentTypeName)?m("excluded-file-region"):B(e.symbol)?m("rust-trait-impl-member"):W(e.symbol)?m("rust-test-module"):!n.includeMembers&&!we(e)?m("member"):e.endLine-e.startLine+1<n.minLoc?m("below-min-loc"):{accepted:!0}:m("non-value-symbol")}function w(e){return F(e)!=="test"}function m(e){return{accepted:!1,rejectionReason:e}}function Y(e){return j(e)||e.endsWith("().")||e.endsWith(".")}function we(e){return A(e.symbol)||x(e.symbol).length===0}function te(){return new Map}function ne(e,n,t){let i=new Map;for(let r of H(e,t))e.isIgnored(r.relative_path)||n.has(r.relative_path)||R(i,r.symbol_id,r.relative_path,r.ref_count,"scip-mention");return i}function re(e,n,t){let i=new Set;for(let r of U(e,n))e.isIgnored(r.relative_path)||t.has(r.relative_path)||i.add(r.symbol_id);return i}function L(e,n){let t=e.get(n);if(!t)return!1;for(let i of t.values())if(i.occurrences>0)return!0;return!1}function ie(e){return e?.occurrences??0}function R(e,n,t,i,r="source-fallback"){if(i<=0)return;let o=se(e,n,t);o.occurrences+=i,o.sources.add(r)}function oe(e,n,t,i,r){if(i<=0)return;let o=se(e,n,t);o.occurrences=Math.max(i,o.occurrences),o.sources.add(r)}function se(e,n,t){let i=e.get(n);i||(i=new Map,e.set(n,i));let r=i.get(t);return r||(r={occurrences:0,sources:new Set},i.set(t,r)),r}function mt(e,n={}){let{scope:t,minLoc:i=1,includeTests:r=!1,skipBarrels:o=!1,includeMembers:s=!1,deadCodeOnly:c=!1,scanLimit:l,semantic:u=!0}=n,a=G(Le(e,{scope:t,minLoc:i,includeTests:r,includeMembers:s}),l),d=o?new Set(N(e)):new Set,f=c?te():ne(e,d,a.map(p=>p.symbolId)),b=c?re(e,a.map(p=>p.symbolId),d):new Set,y=c?a.filter(p=>!b.has(p.symbolId)):a;c?ke(e,y,f,d):Ne(e,y,f,d);let ce=c?y.filter(p=>!L(f,p.symbolId)):a;Oe(e,ce,f,{includeTests:r,inactiveBarrelPaths:d,includeSemantic:!c&&u});let le=c?y.filter(p=>!L(f,p.symbolId)):a;return Fe(e,Pe(le,f))}function Le(e,n){let t=Q(e),i=[];for(let r of h(e,{scope:n.scope}))try{for(let o of V(e,r))ee(o,{minLoc:n.minLoc,includeTests:n.includeTests,includeMembers:n.includeMembers,isIgnoredPath:c=>e.isIgnored(c),isExcludedRegion:t}).accepted&&i.push(o)}finally{D(e,r,{definitions:!0})}return i}function Pe(e,n){return e.map(t=>Ie(t,n)).filter(t=>t.cross_file_refs===0).sort((t,i)=>i.loc-t.loc||t.relative_path.localeCompare(i.relative_path)||t.start_line-i.start_line)}function Ie(e,n){let t=n.get(e.symbolId)??new Map,i=ie(t.get(e.relativePath)),r=0;for(let[o,s]of t)o!==e.relativePath&&(r+=s.occurrences);return{relative_path:e.relativePath,start_line:e.startLine,end_line:e.endLine,loc:e.endLine-e.startLine+1,symbol:e.symbol,same_file_refs:i,cross_file_refs:r}}function Fe(e,n){let t=[],i=0,r=0,o=0;for(let s of n){if(e.isIgnored(s.relative_path)||k(e,s.relative_path)||T(e,s.symbol,s.relative_path))continue;let c=s.same_file_refs===0?"dead-code":"file-internal";c==="dead-code"?i++:r++,o+=s.loc,t.push({relativePath:s.relative_path,startLine:s.start_line,endLine:s.end_line,loc:s.loc,symbol:s.symbol,shortName:M(s.symbol),sameFileRefs:s.same_file_refs,kind:c})}return{symbols:t,totalCount:t.length,deadCodeCount:i,fileInternalCount:r,totalLoc:o}}function Ne(e,n,t,i){if(n.length===0)return;let r=new E(e),o=new Set(n.map(l=>l.symbolId)),s=new Set(n.map(l=>l.leaf).filter(Boolean)),c=new Set(r.sourceFiles());for(let l of h(e))c.add(l);r.scanSourceReferences({paths:c,includeVueSfc:!0,includeCrossLanguageDispatchNames:!0,includeRustAttributeNames:!0,identifierResolution:"permissive",candidateNames:s,skipPath:l=>i.has(l)},l=>{o.has(l.target.symbolId)&&(Ae(e,l)||R(t,l.target.symbolId,l.sourceFile,je(l),"source-fallback"))})}function ke(e,n,t,i){if(n.length===0)return;let r=new E(e),o=Te(n),s=new Set(r.sourceFiles());for(let a of h(e))s.add(a);let c=new Set(o.keys()),l=new Map,u=a=>{let d=l.get(a);return d||(d=q(e,a),l.set(a,d)),d};r.scanSourceReferences({paths:s,includeVueSfc:!0,includeCrossLanguageDispatchNames:!0,includeRustAttributeNames:!0,identifierResolution:"permissive",candidateNames:c,skipPath:a=>i.has(a),resolveTargets:({sourceFile:a,name:d,kind:f})=>{let b=o.get(d);return b?Me(a,d,b,u(a),{permissive:f!=="cross-language-dispatch"}):[]},afterPath:a=>{l.delete(a),D(e,a)}},a=>{let d=a.kind==="identifier"&&a.sourceFile===a.target.relativePath?Math.max(0,a.occurrences-1):a.occurrences;a.kind==="identifier"&&ae(e,{sourceFile:a.sourceFile,name:a.name,target:a.target,occurrences:d})||R(t,a.target.symbolId,a.sourceFile,d,"source-fallback")})}function Te(e){let n=new Map;for(let t of e){if(!t.leaf)continue;let i=n.get(t.leaf)??[];i.push(t),n.set(t.leaf,i)}return n}function Me(e,n,t,i,r){let o=t.filter(l=>l.relativePath===e);if(o.length>0)return o;if(!r.permissive&&t.length===1)return[...t];let s=i.get(n);if(s)for(let l of s){let u=t.filter(a=>v(l,a.relativePath));if(u.length>0)return u}let c=new Set;for(let l of i.values())for(let u of l)c.add(u);for(let l of c){let u=t.filter(a=>v(l,a.relativePath));if(u.length>0&&u.length===t.length)return u}return r.permissive?[...t]:[]}function Ae(e,n){return n.kind==="cross-language-dispatch"&&n.target.relativePath===n.sourceFile?!0:n.kind==="identifier"&&ae(e,n)}function je(e){return e.kind==="identifier"&&e.target.relativePath===e.sourceFile?Math.max(0,e.occurrences-1):e.occurrences}function ae(e,n){return n.occurrences>1?!1:I(e,n.sourceFile).some(t=>t.used||t.sourcePath!==n.target.relativePath?!1:t.importedName===n.name||t.localName===n.name)}function Oe(e,n,t,i){for(let r of n){let o=z(e,r,{semantic:i.includeSemantic!==!1});if(o.length!==0)for(let s of o){let c=s.file;c===r.relativePath||e.isIgnored(c)||i.inactiveBarrelPaths.has(c)||!i.includeTests&&!w(c)||oe(t,r.symbolId,c,1,"caller-map")}}}export{ze as a,mt as b};
2
- //# sourceMappingURL=chunk-6QVCPUK6.js.map
@@ -1,8 +0,0 @@
1
- import{c as k,d as P}from"./chunk-OAI5GEIN.js";import{d as E}from"./chunk-UIWAZ2NT.js";import{a as w,c as x}from"./chunk-SYKCO25G.js";import{a as _}from"./chunk-IW7ASGVF.js";import{c as u}from"./chunk-O6KCZPJQ.js";import{execFileSync as T}from"child_process";var $=5;function U(n,l={}){let{base:s="HEAD",minContainment:m=.7,minCallees:c=3,maxHelpers:o=Number.POSITIVE_INFINITY,limit:a=20}=l,y=l.semantic!==!1,g=x(n,{base:s}),t={available:g.note!==w,base:s,changedFiles:g.changedFiles,helpersChecked:0,skipped:[],findings:[]};if(!t.available||g.changedFiles.length===0)return t;let v=new _(n),S=new Set(g.changedFiles),h=A(n,v,S,s);if(h.length===0)return t;let C=h.slice(0,o);h.length>o&&(t.note=`helper scoring capped at ${o} of ${h.length} new symbols`);let d=k(n,{minCallees:Math.min(3,c),semantic:y}),R=v.calleeMap(C,{semantic:y}),D=C.map(e=>({def:e,callees:P((R.get(e.symbolId)??[]).map(i=>i.symbol))})),b=new Map;for(let e of d)for(let i of e.callees)b.set(i,(b.get(i)??0)+1);let L=Math.max(8,Math.ceil(Math.sqrt(d.length)));for(let{def:e,callees:i}of D){let F=u(e.symbol);if(i.size<c){t.skipped.push({helperShortName:F,helperFile:e.relativePath,reason:`fewer than ${c} meaningful callees \u2014 too small to score`});continue}let M=H(n,e.symbolId);if(M.length===0){t.skipped.push({helperShortName:F,helperFile:e.relativePath,reason:"no references yet \u2014 covered by the new-dead check"});continue}t.helpersChecked+=1;let f=[];for(let r of d){if(r.symbol===e.symbol||S.has(r.file)||r.callees.has(e.symbol))continue;let p=E(i,r.callees);if(p<m)continue;let N=[...i].filter(I=>r.callees.has(I));N.some(I=>(b.get(I)??0)<=L)&&f.push({symbol:r.symbol,shortName:u(r.symbol),file:r.file,containment:p,sharedCallees:N.map(u).sort()})}f.length!==0&&(f.sort((r,p)=>p.containment-r.containment||r.file.localeCompare(p.file)),t.findings.push({helperSymbol:e.symbol,helperShortName:F,helperFile:e.relativePath,migratedFiles:M.sort(),leftovers:f.slice(0,$)}))}return t.findings.sort((e,i)=>(i.leftovers[0]?.containment??0)-(e.leftovers[0]?.containment??0)||e.helperFile.localeCompare(i.helperFile)),t.findings=t.findings.slice(0,a),t}function A(n,l,s,m){let c=new Map;return l.productionCallableDefinitions({requireFunctionLikeSymbol:!0}).filter(o=>{if(!s.has(o.relativePath))return!1;let a=c.get(o.relativePath);return a===void 0&&(a=O(n.config.projectRoot,m,o.relativePath),c.set(o.relativePath,a)),a===null||!new RegExp(`\\b${j(o.leaf)}\\b`).test(a)})}function O(n,l,s){try{return T("git",["show",`${l}:./${s}`],{encoding:"utf-8",cwd:n,timeout:1e4,stdio:["ignore","pipe","ignore"]})}catch{return null}}function H(n,l){return n.all(`SELECT DISTINCT ref_d.relative_path
2
- FROM mentions m
3
- JOIN chunks c ON m.chunk_id = c.id
4
- JOIN documents ref_d ON c.document_id = ref_d.id
5
- WHERE m.symbol_id = ?
6
- AND m.role != 1
7
- ${n.pathExclusionsFor("ref_d")}`,l).map(m=>m.relative_path)}function j(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}export{U as a};
8
- //# sourceMappingURL=chunk-6VL4AIEO.js.map
@@ -1,7 +0,0 @@
1
- import{b as k}from"./chunk-6QVCPUK6.js";import{a as D}from"./chunk-IW7ASGVF.js";import{e as h,f as y}from"./chunk-QYKKTYBN.js";import{n as S}from"./chunk-VGBSY6N7.js";import{c as v,r as L}from"./chunk-O6KCZPJQ.js";function z(e,n={}){let{scope:s,minLoc:c=1,maxDepth:a=5,scanLimit:f}=n,t=new D(e),i=_(e,s,c,f),o=new P;for(let r of i)o.add(r);let m=[],I=[];i.length>0&&m.push(C(e,0,i,o));let b=i.map(r=>r.definition).filter(r=>r!==null),x=new Set(i.map(r=>r.symbol));for(let r=1;r<=a&&b.length>0;r++){let u=t.calleeMap(b,{semantic:!1}),E=new Set;for(let d of b)for(let l of u.get(d.symbolId)??[])x.has(l.symbol)||E.add(l.symbol);let p=[];for(let d of E){x.add(d);let l=F(e,d);if(!l||e.isIgnored(l.relativePath)||h(e,l.relativePath)||y(e,l.symbol,l.relativePath)||t.fileKind(l.relativePath)==="test"||t.hasSuppressionComment(l))continue;let g=B(e,l,o);g.removable?p.push(w(l,"cascade")):g.blockingFiles.length>0&&I.push({shortName:v(l.symbol),file:l.relativePath,blockingFiles:g.blockingFiles.slice(0,3)})}if(p.length===0)break;for(let d of p)o.add(d);m.push(C(e,r,p,o)),b=p.map(d=>d.definition).filter(d=>d!==null)}let N=m.reduce((r,u)=>r+u.loc,0),R=m.reduce((r,u)=>r+u.entries.length,0);return{batches:m,totalSymbols:R,totalLoc:N,blocked:I}}function _(e,n,s,c){let a=k(e,{scope:n,minLoc:s,skipBarrels:!0,deadCodeOnly:!0,scanLimit:c,semantic:!1}),f=[];for(let t of a.symbols)t.kind==="dead-code"&&(h(e,t.relativePath)||y(e,t.symbol,t.relativePath)||f.push({symbol:t.symbol,shortName:t.shortName,file:t.relativePath,startLine:t.startLine,endLine:t.endLine,loc:t.loc,evidence:"graph-fact",definition:F(e,t.symbol)}));return f}function w(e,n){return{symbol:e.symbol,shortName:v(e.symbol),file:e.relativePath,startLine:e.startLine,endLine:e.endLine,loc:e.endLine-e.startLine+1,evidence:n,definition:e}}function F(e,n){let s=e.get(`SELECT d.relative_path
2
- FROM global_symbols gs
3
- JOIN defn_enclosing_ranges der ON der.symbol_id = gs.id
4
- JOIN documents d ON d.id = der.document_id
5
- WHERE gs.symbol = ?
6
- LIMIT 1`,n);return s?L(e,s.relative_path).find(c=>c.symbol===n)??null:null}function B(e,n,s){let c=S(e,n);if(c.length===0)return{removable:!1,blockingFiles:[]};let a=new Set;for(let f of c)f.file===n.relativePath&&f.line>=n.startLine&&f.line<=n.endLine||s.contains(f.file,f.line)||a.add(f.file);return{removable:a.size===0,blockingFiles:[...a]}}function C(e,n,s,c){let a=[...s].sort((i,o)=>i.file.localeCompare(o.file)||i.startLine-o.startLine),f=new Set(a.map(i=>i.file)),t=[];for(let i of f){let o=L(e,i);o.length>0&&o.every(m=>c.contains(i,m.startLine))&&t.push(i)}return{depth:n,entries:a.map(({definition:i,...o})=>o),loc:a.reduce((i,o)=>i+o.loc,0),filesEmptied:t.sort()}}var P=class{ranges=new Map;add(n){let s=this.ranges.get(n.file)??[];s.push({start:n.startLine,end:n.endLine}),this.ranges.set(n.file,s)}contains(n,s){let c=this.ranges.get(n);return c?c.some(a=>s>=a.start&&s<=a.end):!1}};export{z as a,P as b};
7
- //# sourceMappingURL=chunk-A2VTV2QB.js.map