scip-query 0.10.11 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/{vendor/scip/LICENSE.scip → LICENSE} +1 -0
  3. package/README.md +168 -55
  4. package/dist/augment-vue-worker.js +1 -1
  5. package/dist/chunk-2VSDXOG5.js +2 -0
  6. package/dist/chunk-343O6EVV.js +2 -0
  7. package/dist/chunk-3KDUITBE.js +7 -0
  8. package/dist/chunk-3T2FNHIU.js +2 -0
  9. package/dist/chunk-3V6JQQM5.js +2 -0
  10. package/dist/chunk-5AAAEZ2Z.js +2 -0
  11. package/dist/chunk-6Q6OFLFQ.js +8 -0
  12. package/dist/chunk-6XA4LDHY.js +2 -0
  13. package/dist/chunk-75X52JTA.js +2 -0
  14. package/dist/{chunk-54KGX7EX.js → chunk-7HB3CZFD.js} +2 -2
  15. package/dist/chunk-7JZRFDCU.js +2 -0
  16. package/dist/chunk-7XL7J7PT.js +3 -0
  17. package/dist/chunk-ALHNAPS2.js +2 -0
  18. package/dist/{chunk-JATUZIEH.js → chunk-BDRBPG7Y.js} +2 -2
  19. package/dist/chunk-BN5SXXQS.js +40 -0
  20. package/dist/chunk-C4ICAIJ4.js +3 -0
  21. package/dist/{chunk-LSET2TXH.js → chunk-CMHYBXJB.js} +2 -2
  22. package/dist/{chunk-YWYFU2V3.js → chunk-DRPAQAFM.js} +6 -6
  23. package/dist/chunk-FERAXG6Y.js +72 -0
  24. package/dist/chunk-FLJJLSGB.js +2 -0
  25. package/dist/chunk-FXG3PHVW.js +9 -0
  26. package/dist/chunk-GCN2P4EJ.js +2 -0
  27. package/dist/chunk-GHXRVCIY.js +21 -0
  28. package/dist/chunk-GNG622H3.js +3 -0
  29. package/dist/chunk-H4LUPLEJ.js +2 -0
  30. package/dist/{chunk-BASVXNY3.js → chunk-H56MGERE.js} +4 -4
  31. package/dist/chunk-H7NSJ7L2.js +5 -0
  32. package/dist/chunk-HINMXZ6J.js +2 -0
  33. package/dist/chunk-HXXMPYEF.js +2 -0
  34. package/dist/{chunk-Z3YYR4OS.js → chunk-HZKMEXA3.js} +2 -2
  35. package/dist/chunk-IFSX6YVU.js +4 -0
  36. package/dist/chunk-ISLWJ4PY.js +10 -0
  37. package/dist/chunk-J5WVNZ6O.js +2 -0
  38. package/dist/chunk-K2HYR5A7.js +3 -0
  39. package/dist/chunk-K6UI6EBZ.js +2 -0
  40. package/dist/chunk-KJCDEDQW.js +2 -0
  41. package/dist/{chunk-Z4HICZGY.js → chunk-KKMOB3OJ.js} +2 -2
  42. package/dist/{chunk-YWOOQ4FF.js → chunk-KMVGRIO2.js} +2 -2
  43. package/dist/chunk-LWOOTRHC.js +2 -0
  44. package/dist/{chunk-EY43NV4M.js → chunk-LZNLRE4X.js} +17 -8
  45. package/dist/chunk-M2YXL62V.js +23 -0
  46. package/dist/chunk-MNEJYEHW.js +3 -0
  47. package/dist/chunk-MTDBHTSF.js +2 -0
  48. package/dist/{chunk-ZQDIXAF5.js → chunk-N2Z3CU7X.js} +2 -2
  49. package/dist/chunk-N7PNFLGY.js +2 -0
  50. package/dist/chunk-NAH5EAZS.js +6 -0
  51. package/dist/chunk-NBXK32I6.js +2 -0
  52. package/dist/chunk-NJJ7AS4F.js +2 -0
  53. package/dist/{chunk-FDEQIPPK.js → chunk-NLMRJ7SI.js} +2 -2
  54. package/dist/chunk-ODVITBYU.js +26 -0
  55. package/dist/chunk-ORBRX2QJ.js +2 -0
  56. package/dist/chunk-P36UR5II.js +2 -0
  57. package/dist/chunk-PYZZBIEU.js +3 -0
  58. package/dist/chunk-PZS6J5YG.js +16 -0
  59. package/dist/{chunk-LM5SHAN4.js → chunk-QARYU7R3.js} +2 -2
  60. package/dist/chunk-QJ3FK4TB.js +38 -0
  61. package/dist/chunk-QXGTGE2C.js +35 -0
  62. package/dist/chunk-QZ4JVECJ.js +2 -0
  63. package/dist/chunk-R3JY4EZ4.js +102 -0
  64. package/dist/{chunk-VOYOYC5T.js → chunk-R5336VHZ.js} +2 -2
  65. package/dist/chunk-RJMXSHKM.js +2 -0
  66. package/dist/chunk-STBXCPKY.js +5 -0
  67. package/dist/chunk-T2FQ4GHD.js +9 -0
  68. package/dist/chunk-TFWDJDGO.js +2 -0
  69. package/dist/chunk-TG7QSYCJ.js +2 -0
  70. package/dist/{chunk-FKCGBZAC.js → chunk-TTS75UF2.js} +5 -5
  71. package/dist/{chunk-BVRS7RKQ.js → chunk-U7I373V4.js} +2 -2
  72. package/dist/chunk-UIKLA3F5.js +2 -0
  73. package/dist/{chunk-P753MDDE.js → chunk-UMPNL7T6.js} +2 -2
  74. package/dist/chunk-URSSPS5H.js +2 -0
  75. package/dist/chunk-VGMUFW3J.js +2 -0
  76. package/dist/chunk-VXTNADIW.js +18 -0
  77. package/dist/chunk-VYF5HA76.js +2 -0
  78. package/dist/chunk-WFGOH2UI.js +43 -0
  79. package/dist/chunk-WGA5BBTA.js +4 -0
  80. package/dist/chunk-WIBFXSYB.js +6 -0
  81. package/dist/chunk-WPSS37EW.js +2 -0
  82. package/dist/chunk-WQHWIVA7.js +3 -0
  83. package/dist/chunk-WS3Z6W3M.js +65 -0
  84. package/dist/chunk-WXVGNFAO.js +2 -0
  85. package/dist/{chunk-6LJHXREW.js → chunk-WZLPXFZU.js} +2 -2
  86. package/dist/chunk-X4O6K47U.js +2 -0
  87. package/dist/chunk-X6OGDTQH.js +2 -0
  88. package/dist/chunk-XEMQUN3Z.js +20 -0
  89. package/dist/{chunk-7B6LP46R.js → chunk-XHWLNQVZ.js} +2 -2
  90. package/dist/chunk-XMR747CP.js +2 -0
  91. package/dist/chunk-Y6L4LXPG.js +2 -0
  92. package/dist/chunk-YCPASUCX.js +2 -0
  93. package/dist/chunk-YZXV3CU3.js +60 -0
  94. package/dist/chunk-ZEKBR4OK.js +10 -0
  95. package/dist/chunk-ZMGBWSFZ.js +2 -0
  96. package/dist/cli.js +462 -274
  97. package/dist/{config-types-BDIWAYzr.d.ts → config-types-BrHl3Bge.d.ts} +61 -1
  98. package/dist/{db-Djj3Nqrb.d.ts → db-_Bdx0E1W.d.ts} +1 -1
  99. package/dist/diff-gate-types-CG2YQ_ei.d.ts +4 -0
  100. package/dist/{frontend-behavior-evidence-BxKpKWUu.d.ts → frontend-behavior-evidence-EfM4_9bc.d.ts} +1 -1
  101. package/dist/{health-D5J42g4D.d.ts → health-BEZ1Rt0S.d.ts} +54 -2
  102. package/dist/index.d.ts +10 -70
  103. package/dist/index.js +2 -2
  104. package/dist/postinstall.js +1 -4
  105. package/dist/queries/affected.d.ts +2 -2
  106. package/dist/queries/affected.js +1 -1
  107. package/dist/queries/bottlenecks.d.ts +2 -2
  108. package/dist/queries/bottlenecks.js +1 -1
  109. package/dist/queries/by-kind.d.ts +2 -2
  110. package/dist/queries/by-kind.js +1 -1
  111. package/dist/queries/call-graph.d.ts +2 -2
  112. package/dist/queries/call-graph.js +1 -1
  113. package/dist/queries/change-surface.d.ts +2 -2
  114. package/dist/queries/change-surface.js +1 -1
  115. package/dist/queries/cleanup-plan.d.ts +2 -2
  116. package/dist/queries/cleanup-plan.js +1 -1
  117. package/dist/queries/co-change.d.ts +12 -2
  118. package/dist/queries/co-change.js +1 -1
  119. package/dist/queries/code.d.ts +2 -2
  120. package/dist/queries/code.js +1 -1
  121. package/dist/queries/complexity-hotspots.d.ts +7 -3
  122. package/dist/queries/complexity-hotspots.js +1 -1
  123. package/dist/queries/complexity.d.ts +42 -4
  124. package/dist/queries/complexity.js +1 -1
  125. package/dist/queries/convergence.d.ts +2 -2
  126. package/dist/queries/convergence.js +1 -1
  127. package/dist/queries/coupling.d.ts +2 -2
  128. package/dist/queries/coupling.js +1 -1
  129. package/dist/queries/cycles.d.ts +12 -3
  130. package/dist/queries/cycles.js +1 -1
  131. package/dist/queries/dataflow.d.ts +2 -2
  132. package/dist/queries/dataflow.js +1 -1
  133. package/dist/queries/dead.d.ts +3 -3
  134. package/dist/queries/dead.js +1 -1
  135. package/dist/queries/deep-chains.d.ts +2 -2
  136. package/dist/queries/deep-chains.js +1 -1
  137. package/dist/queries/deps.d.ts +2 -2
  138. package/dist/queries/deps.js +1 -1
  139. package/dist/queries/diff-gate.d.ts +65 -8
  140. package/dist/queries/diff-gate.js +1 -1
  141. package/dist/queries/diff-impact.d.ts +21 -3
  142. package/dist/queries/diff-impact.js +1 -1
  143. package/dist/queries/doc-drift.d.ts +29 -2
  144. package/dist/queries/doc-drift.js +1 -1
  145. package/dist/queries/drift.d.ts +15 -3
  146. package/dist/queries/drift.js +1 -1
  147. package/dist/queries/duplicate-bodies.d.ts +55 -0
  148. package/dist/queries/duplicate-bodies.js +2 -0
  149. package/dist/queries/extract-candidates.d.ts +2 -2
  150. package/dist/queries/extract-candidates.js +1 -1
  151. package/dist/queries/fan.d.ts +2 -2
  152. package/dist/queries/fan.js +1 -1
  153. package/dist/queries/files.d.ts +4 -3
  154. package/dist/queries/files.js +1 -1
  155. package/dist/queries/health.d.ts +3 -3
  156. package/dist/queries/health.js +1 -1
  157. package/dist/queries/hierarchy.d.ts +2 -2
  158. package/dist/queries/hierarchy.js +1 -1
  159. package/dist/queries/hotspots.d.ts +2 -2
  160. package/dist/queries/hotspots.js +1 -1
  161. package/dist/queries/imports.d.ts +2 -2
  162. package/dist/queries/imports.js +1 -1
  163. package/dist/queries/incomplete-migration.d.ts +3 -2
  164. package/dist/queries/incomplete-migration.js +1 -1
  165. package/dist/queries/index.d.ts +12 -7
  166. package/dist/queries/index.js +1 -1
  167. package/dist/queries/isolated.d.ts +2 -2
  168. package/dist/queries/isolated.js +1 -1
  169. package/dist/queries/locality-candidates.d.ts +2 -2
  170. package/dist/queries/locality-candidates.js +1 -1
  171. package/dist/queries/members.d.ts +2 -2
  172. package/dist/queries/members.js +1 -1
  173. package/dist/queries/methods.d.ts +2 -2
  174. package/dist/queries/methods.js +1 -1
  175. package/dist/queries/outline.d.ts +2 -2
  176. package/dist/queries/outline.js +1 -1
  177. package/dist/queries/passthrough-candidates.d.ts +11 -3
  178. package/dist/queries/passthrough-candidates.js +1 -1
  179. package/dist/queries/plan-context.d.ts +3 -2
  180. package/dist/queries/plan-context.js +1 -1
  181. package/dist/queries/react-component-duplicates.d.ts +7 -2
  182. package/dist/queries/react-component-duplicates.js +1 -1
  183. package/dist/queries/react-hook-candidates.d.ts +3 -3
  184. package/dist/queries/react-hook-candidates.js +1 -1
  185. package/dist/queries/react-large-component-pressure.d.ts +2 -2
  186. package/dist/queries/react-large-component-pressure.js +1 -1
  187. package/dist/queries/recent-duplicates.d.ts +2 -2
  188. package/dist/queries/recent-duplicates.js +1 -1
  189. package/dist/queries/redundant-reexports.d.ts +2 -2
  190. package/dist/queries/redundant-reexports.js +1 -1
  191. package/dist/queries/refs.d.ts +2 -2
  192. package/dist/queries/refs.js +1 -1
  193. package/dist/queries/self-audit.d.ts +9 -4
  194. package/dist/queries/self-audit.js +1 -1
  195. package/dist/queries/similar-chains.d.ts +2 -2
  196. package/dist/queries/similar-chains.js +1 -1
  197. package/dist/queries/similar-files.d.ts +2 -2
  198. package/dist/queries/similar-files.js +1 -1
  199. package/dist/queries/similar-signatures.d.ts +17 -10
  200. package/dist/queries/similar-signatures.js +1 -1
  201. package/dist/queries/similar.d.ts +85 -17
  202. package/dist/queries/similar.js +1 -1
  203. package/dist/queries/slice.d.ts +2 -2
  204. package/dist/queries/slice.js +1 -1
  205. package/dist/queries/stale-abstractions.d.ts +2 -2
  206. package/dist/queries/stale-abstractions.js +1 -1
  207. package/dist/queries/stats.d.ts +2 -2
  208. package/dist/queries/surface.d.ts +2 -2
  209. package/dist/queries/surface.js +1 -1
  210. package/dist/queries/symbols.d.ts +2 -2
  211. package/dist/queries/symbols.js +1 -1
  212. package/dist/queries/system.d.ts +2 -2
  213. package/dist/queries/system.js +1 -1
  214. package/dist/queries/trace.d.ts +2 -2
  215. package/dist/queries/trace.js +1 -1
  216. package/dist/queries/twin-ab.d.ts +55 -0
  217. package/dist/queries/twin-ab.js +2 -0
  218. package/dist/queries/twin-drift.d.ts +97 -0
  219. package/dist/queries/twin-drift.js +2 -0
  220. package/dist/queries/unused-imports.d.ts +2 -2
  221. package/dist/queries/unused-imports.js +1 -1
  222. package/dist/queries/unused-params.d.ts +2 -2
  223. package/dist/queries/unused-params.js +1 -1
  224. package/dist/queries/vue-component-duplicates.d.ts +7 -2
  225. package/dist/queries/vue-component-duplicates.js +1 -1
  226. package/dist/queries/vue-composable-candidates.d.ts +3 -3
  227. package/dist/queries/vue-composable-candidates.js +1 -1
  228. package/dist/queries/vue-large-view-pressure.d.ts +6 -2
  229. package/dist/queries/vue-large-view-pressure.js +1 -1
  230. package/dist/queries/wrapper-candidates.d.ts +2 -2
  231. package/dist/queries/wrapper-candidates.js +1 -1
  232. package/dist/reindex-worker.js +9 -9
  233. package/dist/reindex.d.ts +30 -4
  234. package/dist/reindex.js +19 -19
  235. package/dist/runtime.d.ts +12 -6
  236. package/dist/runtime.js +2 -2
  237. package/dist/{scip-cli-CnK9Va4O.d.ts → scip-cli-C7cg4ZHR.d.ts} +1 -1
  238. package/dist/symbol-types-DaoeXKUt.d.ts +66 -0
  239. package/docs/AGENT_GUIDE.md +20 -18
  240. package/docs/AI_FAILURE_MODES.md +36 -13
  241. package/docs/API.md +1 -1
  242. package/docs/COMMAND_REFERENCE.md +57 -14
  243. package/docs/DETECTOR_GUIDE.md +20 -3
  244. package/docs/REGEX_POLICY.md +34 -0
  245. package/docs/analyzer-inventory.md +48 -3
  246. package/docs/analyzer-validation-ledger.md +41 -6
  247. package/package.json +23 -7
  248. package/scripts/build-scip-windows.mjs +10 -7
  249. package/scripts/evidence-product-contract.mjs +197 -0
  250. package/skills/_shared/SKILL.md +243 -0
  251. package/skills/_shared/agents/openai.yaml +4 -0
  252. package/skills/scip-api-impact/SKILL.md +55 -71
  253. package/skills/scip-claim-audit/SKILL.md +105 -0
  254. package/skills/scip-claim-audit/agents/openai.yaml +4 -0
  255. package/skills/scip-cleanup-audit/SKILL.md +122 -0
  256. package/skills/scip-cleanup-audit/agents/openai.yaml +4 -0
  257. package/skills/scip-cleanup-improve/SKILL.md +84 -0
  258. package/skills/scip-cleanup-improve/agents/openai.yaml +4 -0
  259. package/skills/scip-concrete-plan/SKILL.md +181 -0
  260. package/skills/scip-concrete-plan/agents/openai.yaml +4 -0
  261. package/skills/scip-conductor/SKILL.md +133 -0
  262. package/skills/scip-conductor/agents/openai.yaml +4 -0
  263. package/skills/scip-debug/SKILL.md +60 -58
  264. package/skills/scip-diagram/SKILL.md +64 -94
  265. package/skills/scip-directory-architecture/SKILL.md +65 -107
  266. package/skills/scip-doc-reconcile/SKILL.md +56 -67
  267. package/skills/scip-explore/SKILL.md +78 -210
  268. package/skills/scip-hyper-optimization/SKILL.md +124 -198
  269. package/skills/scip-integrity-audit/SKILL.md +103 -0
  270. package/skills/scip-integrity-audit/agents/openai.yaml +4 -0
  271. package/skills/scip-language-playbook/SKILL.md +56 -326
  272. package/skills/scip-maintainability/SKILL.md +80 -219
  273. package/skills/scip-probe-reachability/SKILL.md +92 -0
  274. package/skills/scip-probe-reachability/agents/openai.yaml +4 -0
  275. package/skills/scip-query/SKILL.md +108 -124
  276. package/skills/scip-react-maintainability/SKILL.md +64 -82
  277. package/skills/scip-setup/SKILL.md +121 -0
  278. package/skills/scip-setup/agents/openai.yaml +4 -0
  279. package/skills/scip-tla-model-system/SKILL.md +138 -0
  280. package/skills/scip-tla-model-system/agents/openai.yaml +4 -0
  281. package/skills/scip-triage-issue/SKILL.md +53 -41
  282. package/skills/scip-twin-drift/SKILL.md +107 -0
  283. package/skills/scip-twin-drift/agents/openai.yaml +4 -0
  284. package/skills/scip-verify/SKILL.md +70 -88
  285. package/skills/scip-vue-maintainability/SKILL.md +67 -94
  286. package/dist/chunk-2KHTSEIL.js +0 -102
  287. package/dist/chunk-3VD3JMK2.js +0 -2
  288. package/dist/chunk-4UZO3XCV.js +0 -35
  289. package/dist/chunk-5GOLFJEO.js +0 -8
  290. package/dist/chunk-5OST6GYB.js +0 -2
  291. package/dist/chunk-65AU3HFZ.js +0 -2
  292. package/dist/chunk-6GN7FXCH.js +0 -2
  293. package/dist/chunk-6IR2AOBM.js +0 -7
  294. package/dist/chunk-6JRV4MY2.js +0 -23
  295. package/dist/chunk-6QSOCTZT.js +0 -18
  296. package/dist/chunk-72KY2ZFO.js +0 -2
  297. package/dist/chunk-7GO4EQF5.js +0 -2
  298. package/dist/chunk-7IVSJJZU.js +0 -7
  299. package/dist/chunk-7TWLSZK5.js +0 -2
  300. package/dist/chunk-A536TEU4.js +0 -3
  301. package/dist/chunk-AVWPHM2Q.js +0 -4
  302. package/dist/chunk-B32FX5KB.js +0 -2
  303. package/dist/chunk-B6MJ5VQV.js +0 -2
  304. package/dist/chunk-BFXPG2VN.js +0 -2
  305. package/dist/chunk-BSN22NRK.js +0 -9
  306. package/dist/chunk-BZ53S4ZN.js +0 -2
  307. package/dist/chunk-C5CTSJ6X.js +0 -6
  308. package/dist/chunk-CO5GJRP7.js +0 -2
  309. package/dist/chunk-CW5YFOCP.js +0 -5
  310. package/dist/chunk-DS6QEB3G.js +0 -5
  311. package/dist/chunk-E35O7UCB.js +0 -2
  312. package/dist/chunk-EXDQ35NN.js +0 -2
  313. package/dist/chunk-FAYI6KZ5.js +0 -2
  314. package/dist/chunk-FFVIFETB.js +0 -2
  315. package/dist/chunk-FG4NT6VY.js +0 -2
  316. package/dist/chunk-FXNWFMKW.js +0 -25
  317. package/dist/chunk-G5UPYQGL.js +0 -4
  318. package/dist/chunk-GQBMH2TQ.js +0 -2
  319. package/dist/chunk-GRJY65YT.js +0 -2
  320. package/dist/chunk-HF25DFSC.js +0 -3
  321. package/dist/chunk-HHN2B5KA.js +0 -2
  322. package/dist/chunk-IHUETYFW.js +0 -2
  323. package/dist/chunk-JCLDUKT6.js +0 -38
  324. package/dist/chunk-JGN2ZFJR.js +0 -2
  325. package/dist/chunk-JM72FNGA.js +0 -2
  326. package/dist/chunk-JME7OWD3.js +0 -2
  327. package/dist/chunk-KDFONWTW.js +0 -40
  328. package/dist/chunk-LPL4MA6R.js +0 -2
  329. package/dist/chunk-LZHUWKGD.js +0 -2
  330. package/dist/chunk-M4COR2H6.js +0 -2
  331. package/dist/chunk-NOJAM5ZV.js +0 -21
  332. package/dist/chunk-O6ZH6C6Y.js +0 -2
  333. package/dist/chunk-OBGRLXWF.js +0 -3
  334. package/dist/chunk-OLTESY4K.js +0 -3
  335. package/dist/chunk-ONPCQ2PM.js +0 -6
  336. package/dist/chunk-P4KYUPBD.js +0 -4
  337. package/dist/chunk-P5RYBRIO.js +0 -4
  338. package/dist/chunk-P7AL7Y37.js +0 -2
  339. package/dist/chunk-PFOCOG57.js +0 -2
  340. package/dist/chunk-QLAUCRDJ.js +0 -2
  341. package/dist/chunk-QPU7EXAW.js +0 -2
  342. package/dist/chunk-QYB5P7GL.js +0 -2
  343. package/dist/chunk-RNM6LMCF.js +0 -2
  344. package/dist/chunk-RVWSAMTT.js +0 -2
  345. package/dist/chunk-TK7O5ER5.js +0 -3
  346. package/dist/chunk-TQ5W2H3S.js +0 -4
  347. package/dist/chunk-USPV3T5K.js +0 -2
  348. package/dist/chunk-UUBMFL3F.js +0 -59
  349. package/dist/chunk-VCQYSG2M.js +0 -10
  350. package/dist/chunk-VUKC6F77.js +0 -20
  351. package/dist/chunk-W2CBNBEL.js +0 -71
  352. package/dist/chunk-W6BVEKYC.js +0 -3
  353. package/dist/chunk-WUCEKFQC.js +0 -3
  354. package/dist/chunk-XUGQU7PM.js +0 -41
  355. package/dist/chunk-Y5NBHMQX.js +0 -2
  356. package/dist/chunk-YCOFCT4B.js +0 -2
  357. package/dist/chunk-YZA6PPZL.js +0 -3
  358. package/skills/concrete-plan/SKILL.md +0 -372
  359. package/skills/concrete-plan/agents/openai.yaml +0 -4
  360. package/skills/scip-adoption/SKILL.md +0 -122
  361. package/skills/scip-adoption/agents/openai.yaml +0 -4
  362. package/skills/scip-ai-cleanup/SKILL.md +0 -153
  363. package/skills/scip-ai-cleanup/agents/openai.yaml +0 -4
  364. package/skills/scip-debloat/SKILL.md +0 -439
  365. package/skills/scip-debloat/agents/openai.yaml +0 -4
  366. package/skills/scip-health-audit/SKILL.md +0 -162
  367. package/skills/scip-health-audit/agents/openai.yaml +0 -4
  368. package/skills/scip-health-improve/SKILL.md +0 -155
  369. package/skills/scip-health-improve/agents/openai.yaml +0 -4
  370. package/skills/scip-query-setup/SKILL.md +0 -170
  371. package/skills/scip-query-setup/agents/openai.yaml +0 -3
  372. package/vendor/scip/README.md +0 -6
  373. package/vendor/scip/win32-arm64/scip.exe +0 -0
  374. package/vendor/scip/win32-x64/scip.exe +0 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ All notable changes to `scip-query` are documented here. This file starts at 0.11.0; everything below covers behavior changes made since the 0.10.12 release.
4
+
5
+ ## [0.11.0]
6
+
7
+ ### Breaking (one-way doors — read before upgrading)
8
+
9
+ - **`npm install` no longer installs anything beyond the package itself.** Postinstall used to symlink skills into your home directory and could shell out to `brew`/`go install` for missing toolchains. It now prints exactly one line — `scip-query installed -- run 'scip-query setup' in a repo to enable skills, hooks, and the index.` — and does nothing else. Run `scip-query setup` explicitly in a project to get skills, hooks, and a first index.
10
+ - **Project hooks default to an untracked file.** `scip-query setup` (and `setup-hooks`) now write Claude Code hooks to `.claude/settings.local.json` instead of the tracked `.claude/settings.json`, so a teammate's agent tooling preferences no longer land in git by default. Run `setup-hooks --shared` to opt back into the tracked file. `setup-hooks --remove` writes a decline tombstone so a later `setup` won't silently re-add hooks you removed; `--force` overrides it.
11
+ - **Suppression IDs use a new stable hash.** `.scipquery.json` suppression `id`s are now derived from `(check, symbol, file)` only, not the full match set, so an unrelated new similar function elsewhere no longer silently un-suppresses an accepted finding. Existing legacy-format IDs still match (dual-matching) — nothing in your config needs to change today — but `config-validate` now prints an info diagnostic naming the stable replacement for each legacy entry.
12
+ - **Windows no longer ships a vendored `scip.exe`.** The 39 MB vendored binary is gone. Windows installs now receive the binary through `scip-query-scip-windows`, a universal (x64 + arm64) os-gated optional npm dependency fetched only on Windows; resolution order is PATH → `SCIP_QUERY_SCIP_BIN` env → sidecar package → printed instructions. Publishing the main package auto-builds and auto-publishes the sidecar (`prepublishOnly`). Set `SCIP_QUERY_SCIP_BIN` to a local `scip.exe` to override.
13
+ - **`convergence` is deprecated.** Use `similar <symbol1> <symbol2> --plan` instead. `convergence` still works (as a thin alias) but is not the documented path going forward.
14
+ - **`drift`'s pattern-deviation channel is now opt-in.** The "only sibling in this directory depends on X" noise channel used to run by default; it now requires `--patterns`. `drift` also gained `-n/--limit <n>` (default 50) — previously unbounded output could reach hundreds of KB on a large repo. Unused-import and layer-violation findings are unaffected and still run by default.
15
+ - **`doc-reference` findings are now split by citation granularity.** Only line-anchored citations (`file.ts:123`) or citations of a file that was deleted/renamed still block `diff-gate`. A bare file-mention citation (no line anchor) is now advisory: it prints and is suppressible but never fails the gate by itself.
16
+ - **`tla verify` groups findings by default.** Human-mode output now prints findings grouped by `(category, modelElement)` with a count and up to 3 exemplars per group, instead of every finding individually — one Vega-scale model previously produced 10,724 lines of output from a handful of root causes. Pass `--full` to get the old ungrouped behavior. `--json` is unaffected except for a new `findingGroups` summary alongside the still-complete `findings` array.
17
+
18
+ ### Notable (new capabilities)
19
+
20
+ - **New commands:** `duplicate-bodies` (finds byte-identical small callable bodies across files — the "same helper copy-pasted into seven files" shape `similar`'s shape-based scoring is too coarse to catch), `twin-drift` (finds same-name or near-name functions across files whose bodies have diverged — a signal one side got a fix the other never received), `uninstall` (reverses `install-skills`/`setup-hooks`, with `--dry-run`), and the `tla` model-checking family: `tla scaffold` (draft a TLA+ spec/config/mapping from indexed code), `tla instrument` (generate a trace recorder plus wiring sites), `tla trace-check` (prove a recorded execution is a legal model transition via the real TLC checker), and `tla fetch-tools` (download the sha256-pinned `tla2tools.jar`). This release also adds `tla verify`/`trace-check --timeout-ms` and `tla verify --full`.
21
+ - **`tla verify` actually verifies now.** Declared `reads` are checked against a static scan (not just parsed and ignored); variable/action referents that resolve to a type instead of a value produce a hard error; every waiver requires a reason and is counted in the output; the checker's config `INVARIANT`s are cross-checked against the mapping's declared invariants. A PASS with unwaived findings is no longer possible, and the proof summary is itemized (`writes: N verified, M waived`, etc.) instead of a single overclaiming sentence.
22
+ - **Two new `diff-gate` checks:** `twin-partner` (advisory — a changed symbol has a same-name twin elsewhere that this diff left untouched) and `coverage-contract` (a configured `.scipquery.json` `coverageContracts` entry drifted from its ground-truth source — enumeration rot).
23
+ - **Three new lens skills:** `scip-twin-drift`, `scip-claim-audit` (classify whether an "available"/"verified"/"safe"/"PASS" claim is derived from a real check or merely asserted), and `scip-probe-reachability` (prove whether a parser/AST branch is actually reachable by running the real parser on minimal inputs).
24
+ - **Skill set consolidated.** `scip-adoption`/`scip-query-setup` merged into `scip-setup`; the four-skill cleanup family collapsed into `scip-cleanup-audit` (report-only, three modes) and `scip-cleanup-improve` (autonomous fixing loop); every workflow now closes out through a single `scip-verify` skill instead of duplicated inline postchecks.
25
+ - **Skill set standardized on the `scip-` prefix.** `concrete-plan` → `scip-concrete-plan` and `tla-model-system` → `scip-tla-model-system`; `install-skills` prunes the old symlinked names automatically on the next run, no manual cleanup needed. `_shared` is the one intentional exception (reference infrastructure loaded by other skills, not user-invoked).
26
+ - **New skill: `scip-conductor`.** Bundles the previously user-global-only "conduct a multi-phase program" method (plan, delegate, verify handoffs, close, with pre-registered benchmarks) as a first-class installed skill, routed from the `scip-query` router with a tie-break against `scip-concrete-plan` (one change vs. a program of changes with delegation).
27
+ - **README documents every bundled skill.** A new "Bundled skills" table in README.md lists all 25 installed skills with a one-line essential-difference summary each, explicitly disambiguating the clusters that are easy to confuse (`scip-concrete-plan` vs `scip-conductor`, `scip-cleanup-audit` vs `scip-cleanup-improve`, `scip-verify` vs `scip-integrity-audit` vs `scip-maintainability` vs `scip-twin-drift`, `scip-directory-architecture` vs `scip-maintainability`).
28
+ - **`analysisBudget` JSON disclosure extended to every budgeted command.** Previously only `diff-gate --json` disclosed when a large-index scan cap engaged. Now `change-surface`, `incomplete-migration`, `dataflow`, `slice`, `plan-context`, `complexity`, `dead`, `extract-candidates`, `locality-candidates`, `cleanup-plan`, `recent-duplicates`, and every command built on the generic list/report/table command builders (`refs`, `imports`, `trace`, `similar`, `drift`, `isolated`, `unused-params`, and more) include an `analysisBudget` field in their JSON envelope whenever a cap engaged (omitted otherwise) — a reduced-coverage pass no longer presents as a full one to a JSON consumer.
29
+ - **Every command's evidence tier is now architectural, not per-command artisanal.** Human output prints a heuristic disclaimer and `--json` stamps an `evidence: "graph-fact" | "heuristic" | "mixed"` field for every command, driven by the descriptor registry rather than five different disconnected mechanisms. "Safe to delete" language is gone everywhere except compiler-verified (tier-4) output — cleanup findings now read "deletion candidates; confirm with cleanup-plan --verify."
30
+ - **`cleanup-plan --verify` reads the real checker exit status.** The banner is now `VERIFIED (<oracle>)` (naming `tsc`, `go build`, `ruff`, `python-compileall`, `clj-kondo`, or `cargo check`) instead of a blanket "COMPILER-VERIFIED", and it discloses when working-tree files outside the plan were dirty at verification time.
31
+ - **`finding-outcome ledger` and precision reporting.** `diff-gate` now tracks each check's resolution/suppression rate over time; low-precision checks surface a nudge in `--hook` mode, and `health --json` reports `detectorPrecision` per check.
32
+ - **Snapshot-doc policy.** `.scipquery.json`'s `docs.snapshotPaths` globs (or an inline `<!-- scip-query: snapshot -->` marker) exempt dated ledger/report docs from `doc-reference`/`doc-drift` findings, eliminating a recurring wall of false doc-drift positives on append-only docs.
33
+ - **Health dogfood: 97 → 100.** The layer policy gained `runtime → tla` (the CLI layer importing its own query module, the established pattern) and `src/core` is now a legal dependency for `source`, `semantic`, `runtime`, `tla`, and `language-parsers`. `escapeRegex` moved to a new zero-dependency `src/core/regex-utils.ts`, restoring the documented invariant that `src/semantic` never imports `src/source`. `binaryAvailable` moved to `src/core/command-availability.ts`; the shared download/checksum/cache primitive both `tla fetch-tools` and the Windows `scip.exe` fetcher needed now lives in `src/core/verified-binary-fetch.ts`, letting three prior "we'd extract this but `src/core` isn't reachable yet" suppressions be deleted outright. Four duplicate-body pairs were consolidated into shared helpers; three were left as documented intentional variation (React/Vue parity functions, echo/baseline remediation text) rather than force-merged.
34
+
35
+ ### Fixes (accuracy / false-positive)
36
+
37
+ - **Three false-dead archetypes fixed.** Symbols consumed only via `import type` across a `tsconfig` path alias are no longer reported dead. pnpm-workspace cross-package consumers are now resolved via a new workspace-package resolver (this also fixed a real bug — `fanInBySymbolId.get(id) === 0` treated an *absent* symbol the same as a zero-reference one, suppressing semantic enrichment broadly, not just for the workspace case). Vue `<script setup>` composable consumers were verified already correct and gained a regression fixture. Where the remaining gap couldn't be closed this release (an ambiguous leaf name across an unresolved barrel re-export hop), the finding is now labeled `unconfirmed` instead of asserted `dead`.
38
+ - **`diff-gate` fails closed.** A git-diff-unavailable condition (diff too large for the exec buffer, a bad `--base`, or a git error) now exits nonzero having run zero checks, instead of silently passing.
39
+ - **`doc-drift` epoch-0 timestamp bug fixed.** A doc whose only commit touched it as part of a >50-file bulk sweep now falls back to file mtime instead of being reported as "last changed at the Unix epoch."
40
+ - **SANY XML export was silently dead code.** `-o <path>` on the SANY invocation meant "offline mode," not "output path" — the real-parser XML export path never actually ran. Fixed the invocation and rewrote the XML grammar parser against real `tla2tools` v1.8.0 output.
41
+ - **`tla verify`/`trace-check` timeout misclassification fixed.** `spawnSync`'s own timeout kill has no `ETIMEDOUT` error shape — only `signal: 'SIGTERM'` — so a genuine timeout was previously reported as an ordinary `failed` run. A SIGTERM landing at or after the requested `timeoutMs` boundary is now classified `timed-out`.
42
+ - **Calibration retunes from external repo validation:** `duplicate-bodies`' default `--min-loc` raised from 1 to 3 (kills 1-line forwarding-stub noise); `twin-drift` excludes synthetic constructor-style leaves and test-only groups; `co-change` exempts locale/i18n sibling resource files from hidden-coupling findings; `stale-abstractions`/`wrapper-candidates` gained an explicit false-positive-rate caveat and were demoted from the default `cleanup-audit` sweep to an opt-in deep-dive.
43
+ - Assorted smaller fixes: parameterized SQL in a scope filter (injection-shaped hygiene, no known exploit), fan-in/hotspot queries no longer counting a symbol's own defining file as a consumer, AST-based cyclomatic-complexity counting, nested `.gitignore` support, and Vue single-file-component script extraction unified across the codebase.
44
+
45
+ [0.11.0]: https://github.com/PlunderStruck/scip-query/releases/tag/v0.11.0
@@ -1,3 +1,4 @@
1
+
1
2
  Apache License
2
3
  Version 2.0, January 2004
3
4
  http://www.apache.org/licenses/
package/README.md CHANGED
@@ -20,29 +20,40 @@
20
20
  <a href="https://www.apache.org/licenses/LICENSE-2.0"><img alt="License" src="https://img.shields.io/npm/l/scip-query.svg"></a>
21
21
  </p>
22
22
 
23
- `scip-query` is a TypeScript CLI and npm package that turns SCIP indexes, git history, language-aware source analysis, and your repository's own checks into commands AI coding agents can use before, during, and after a change.
23
+ `scip-query` gives AI coding agents compiler-grade evidence about your repository and mechanical gates on what they produce. Under the hood it is a TypeScript CLI and npm package built on SCIP indexes, git history, language-aware source analysis, and your repository's own checks.
24
24
 
25
25
  Agents are effective at editing the code in front of them. They are less reliable at preserving a whole-repository model across a long task: they miss existing helpers, plan from partial context, migrate only some call sites, overlook files coupled only by history, and declare a diff finished while it still adds duplication, dead code, or stale documentation.
26
26
 
27
27
  `scip-query` gives them a repeatable operating loop: map the target and its blast radius, build a concrete plan from repository evidence, check for reuse before adding a concept, detect unfinished migrations and hidden coupling, and gate the final diff. It does not replace the compiler, tests, or review; it makes structural evidence and repository checks easy for agents to invoke and report.
28
28
 
29
- ## The Agent Loop
29
+ ## How Agents Use It
30
30
 
31
- | Phase | What the agent needs to establish | Commands |
32
- |---|---|---|
33
- | Orient | What exists, where it is defined, and what depends on it | `system`, `trace`, `affected`, `plan-context` |
34
- | Plan | Externally consumed surfaces, change scope, blast radius, and historical partners | `surface`, `change-surface`, `co-change` |
35
- | Reuse | Whether the helper, component, hook, or composable already exists | `similar`, `recent-duplicates` |
36
- | Finish | Whether an extraction or migration reached every relevant site | `incomplete-migration`, `unused-params` |
37
- | Verify | What the diff affected and whether covered structural checks regressed | `diff-impact --json`, `doc-drift`, `diff-gate --json`, `health --baseline` |
38
- | Clean up | Candidate removals and newly exposed dead-code cascades | `cleanup-plan --verify` |
31
+ Two layers, wired by `scip-query setup`:
32
+
33
+ **Ambient** no invocation required. Session-start hooks supply index state and routing context; the Stop-hook / pre-commit **diff gate** checks every finished diff for echoes of existing code, unfinished migrations, missing co-change partners, stale doc citations, and new dead code and feeds findings back to the agent.
34
+
35
+ **Invoked** the agent routes work through skills, each carrying its own short command list so it never navigates the full CLI:
36
+
37
+ | Phase | Skill | Commands underneath (also usable directly) |
38
+ | --------- | -------------------------------------------------------- | ----------------------------------------------- |
39
+ | Orient | `scip-explore` | `system`, `trace`, `plan-context`, `call-graph` |
40
+ | Plan | `scip-concrete-plan` (one change) · `scip-conductor` (a program) | `plan-context`, `change-surface`, `co-change` |
41
+ | Reuse | (taught in-loop by the planning skills) | `similar`, `duplicate-bodies`, `recent-duplicates` |
42
+ | Implement | your agent + the post-change check for the change type | `incomplete-migration`, `unused-params`, `co-change` |
43
+ | Verify | `scip-verify` (closeout) + the ambient diff gate | `diff-impact`, `diff-gate`, `health --baseline` |
44
+ | Clean up | `scip-cleanup-audit` → `scip-cleanup-improve` | `cleanup-plan --verify`, `dead`, `twin-drift` |
45
+
46
+ Interrogation lenses go deeper on demand: `scip-integrity-audit` ("is this implementation real?"), `scip-twin-drift`, `scip-claim-audit`, `scip-probe-reachability`, and `scip-maintainability`. The full map with essential differences is in [Bundled skills](#bundled-skills); every command remains directly invocable for humans and scripts.
39
47
 
40
48
  React and Vue repositories get additional framework-aware checks for repeated component/template structure, hook/composable behavior, and large-component or large-view pressure. These extend the same reuse and completion workflow; the core graph, history, planning, cleanup, and diff-gate commands are not frontend-specific.
41
49
 
42
50
  ## Install
43
51
 
52
+ `npm install` only installs the package — it does not touch your home directory, your shell config, or any agent's skill/hook setup. Every write happens explicitly, when you ask for it:
53
+
44
54
  ```bash
45
55
  npm install -g scip-query@latest
56
+ scip-query setup # opt-in: skills, project hooks, first index, health dossier
46
57
  scip-query check-deps
47
58
  scip-query reindex
48
59
  ```
@@ -99,11 +110,15 @@ Heuristic findings are candidates for inspection, not proof of equivalence or ba
99
110
 
100
111
  Graph navigation works through supported [SCIP](https://github.com/sourcegraph/scip) indexers. Higher-confidence augmentation and verification vary by language and project toolchain. TypeScript currently has the richest semantic augmentation. React and Vue add built-in framework-aware maintainability checks on top of the core workflow.
101
112
 
113
+ Clojure projects are indexed through `scip-clojure`. Source fallback adds namespace imports, callable/callsite evidence, and protocol/record member evidence for `.clj`, `.cljs`, and `.cljc` files. When the project has `clj-kondo` available, cleanup-plan verification can use `clj-kondo --lint .`. Clojure does not currently have a scip-query semantic provider equivalent to TypeScript's `ts-morph` layer; capability output reports that boundary explicitly.
114
+
102
115
  ## Cleaning Up AI-Generated Code
103
116
 
104
117
  These checks target specific ways AI-assisted development rots a codebase. The full catalog, with prevention wiring for each detector, is in [docs/AI_FAILURE_MODES.md](docs/AI_FAILURE_MODES.md):
105
118
 
106
- **1. Find the echoes.** Agents re-implement helpers, hooks, composables, and frontend components they didn't know existed. `recent-duplicates` makes similarity *directional* using git file ages - which side is the established original, which is the recent echo:
119
+ **1. Find the echoes.** Agents re-implement helpers, hooks, composables, and frontend components they didn't know existed. `recent-duplicates` makes similarity _directional_ using git file ages - which side is the established original, which is the recent echo.
120
+
121
+ Illustrative output:
107
122
 
108
123
  ```
109
124
  91% ECHO react-component src/components/ProjectCardVisual.tsx ProjectCardVisual (added 62 commits ago)
@@ -114,7 +129,9 @@ These checks target specific ways AI-assisted development rots a codebase. The f
114
129
  (both new - one agent session duplicated itself; consolidate before they diverge)
115
130
  ```
116
131
 
117
- **2. Finish the half-done extraction.** Agents extract a helper, rewire one or two call sites, and abandon the rest — the extracted logic survives inline at every site they missed. `incomplete-migration` finds helpers that are new in the diff, confirms they were wired in somewhere, and lists the established sites that still contain the helper's logic but never call it (containment scoring, because a missed site holds the helper's logic *plus* its own):
132
+ **2. Finish the half-done extraction.** Agents extract a helper, rewire one or two call sites, and abandon the rest — the extracted logic survives inline at every site they missed. `incomplete-migration` finds helpers that are new in the diff, confirms they were wired in somewhere, and lists the established sites that still contain the helper's logic but never call it (containment scoring, because a missed site holds the helper's logic _plus_ its own).
133
+
134
+ Illustrative output:
118
135
 
119
136
  ```
120
137
  src/utils/priceLabel.ts priceLabel()
@@ -123,7 +140,7 @@ src/utils/priceLabel.ts priceLabel()
123
140
  un-migrated: 100% buildReportC() (src/cards/price-summary-c.ts)
124
141
  ```
125
142
 
126
- **3. Catch your standards docs lying.** If you keep in-repo standards for agents to read before implementing, a stale standard is worse than none. `doc-drift` reads every doc's file citations *and* its co-change history, then flags docs whose code moved on without them — including **broken references** to files that no longer exist:
143
+ **3. Catch your standards docs lying.** If you keep in-repo standards for agents to read before implementing, a stale standard is worse than none. `doc-drift` reads every doc's file citations _and_ its co-change history, then flags docs whose code moved on without them — including **broken references** to files that no longer exist:
127
144
 
128
145
  ```
129
146
  staleness 94 product/domain-model.md
@@ -131,7 +148,7 @@ staleness 94 product/domain-model.md
131
148
  22 change(s) since doc update src/workflows/serviceTasks.ts (referenced by doc)
132
149
  ```
133
150
 
134
- **4. Delete with project checks.** `cleanup-plan` runs dead-code analysis to a *fixpoint* — deleting batch 0 makes batch 1 dead, and the plan shows the cascade. `--verify` applies each batch in a throwaway git worktree and runs the supported checker detected for your project (differentially, so pre-existing errors don't drown the signal):
151
+ **4. Delete with project checks.** `cleanup-plan` runs dead-code analysis to a _fixpoint_ — deleting batch 0 makes batch 1 dead, and the plan shows the cascade. `--verify` applies each batch in a throwaway git worktree and runs the supported checker detected for your project (differentially, so pre-existing errors don't drown the signal):
135
152
 
136
153
  ```
137
154
  ── Batch 0: deletable now (graph-fact, 67 LOC) ──
@@ -139,22 +156,44 @@ staleness 94 product/domain-model.md
139
156
  Batch 0: COMPILER-VERIFIED
140
157
  ```
141
158
 
142
- When verification *fails*, the errors name the exact references the static evidence missed — that failure has caught real detector mistakes and stopped build-breaking deletions.
159
+ When verification _fails_, the errors name the exact references the static evidence missed — that failure has caught real detector mistakes and stopped build-breaking deletions.
143
160
 
144
161
  **5. Trim speculative generality.** `unused-params` finds trailing parameters no body ever uses (the classic "options for later"), scoped to removals that are type-safe by construction.
145
162
 
146
163
  **6. Keep frontend reuse honest.** React and Vue have dedicated frontend hygiene checks: component-duplicate commands compare JSX/template structure, hook/composable commands compare state/effect/request behavior, and large-component/view commands flag files that concentrate too many reasons to change. `health` includes these as hygiene pressure, while `incomplete-migration` remains the direct check for a hook/composable/helper extraction that was wired into some sites but not all of them.
147
164
 
148
- **7. Surface hidden coupling.** `co-change` finds file pairs that repeatedly change in the same commits with *no* dependency edge — schema ↔ generated inventory ↔ doc triangles, backend schemas ↔ frontend stores, `.env.example` ↔ its parser. The reference graph cannot see these; the change graph can.
165
+ **7. Surface hidden coupling.** `co-change` finds file pairs that repeatedly change in the same commits with _no_ dependency edge — schema ↔ generated inventory ↔ doc triangles, backend schemas ↔ frontend stores, `.env.example` ↔ its parser. The reference graph cannot see these; the change graph can.
149
166
 
150
- **8. Gate every diff.** `diff-gate` runs a defined set of checks scoped to what a change *introduces* echoes of established code, incomplete migrations, missing co-change partners, docs that cite the changed files, fresh unused params, new dead symbols, baseline regressions — and exits nonzero with remediation text for each finding:
167
+ **8. Gate every diff.** `diff-gate` runs a defined set of checks scoped to what a change _introduces_ and exits nonzero with remediation text for each finding. Baseline regressions are included when you pass `--baseline`.
168
+
169
+ <!-- BEGIN GENERATED DIFF-GATE CHECKS -->
170
+ | Check | What it catches | When it runs |
171
+ | --- | --- | --- |
172
+ | `echo` | Changed symbols that newly echo established code elsewhere. | Default diff gate. |
173
+ | `incomplete-migration` | New helpers or abstractions wired into some sites while older inline sites remain. | Default diff gate. |
174
+ | `co-change-partner` | Historically coupled files that usually change together but are missing from this diff. | Default diff gate. |
175
+ | `twin-partner` | A changed symbol has a same-(near-)name twin (identical or already-divergent) elsewhere that this diff left untouched. | Default diff gate. Advisory: findings print but never cause a nonzero exit by themselves. |
176
+ | `coverage-contract` | A configured `coverageContracts` entry (.scipquery.json) drifted: its declared key set no longer matches its ground-truth source. | Default diff gate, only when either side of a configured contract changed. |
177
+ | `doc-reference` | Docs that cite changed files and may need a matching update. Dated snapshot docs (docs.snapshotPaths) are excluded by policy. | Default diff gate. Advisory (21.2) for bare file-mention citations; blocking when the citation has a line anchor or the cited file was deleted/renamed. |
178
+ | `unused-params` | Fresh trailing parameters or options that no changed body uses. | Default diff gate. |
179
+ | `new-dead` | Changed production symbols with zero indexed consumers. | Default diff gate. |
180
+ | `baseline` | New health finding identities compared with the committed health baseline. | Only with `diff-gate --baseline`. |
181
+ <!-- END GENERATED DIFF-GATE CHECKS -->
182
+
183
+ Illustrative output:
151
184
 
152
185
  ```
153
186
  [co-change-partner] schema.prisma changed, but scripts/scope-inventory.mjs did not — they change together 12x (86% of the time)
154
187
  -> Update scripts/scope-inventory.mjs alongside this change, or confirm the coupling no longer holds.
155
188
  ```
156
189
 
157
- **9. Ratchet it in CI.** `health --write-baseline` snapshots finding identities into a committable file; `health --baseline` exits 1 on any *new* finding. "Don't get worse" is an objective gate that no score arithmetic can game.
190
+ **9. Ratchet it in CI.** `health --write-baseline` snapshots finding identities into a committable file; `health --baseline` exits 1 on any _new_ finding. "Don't get worse" is an objective gate that no score arithmetic can game.
191
+
192
+ **10. Catch byte-identical tiny helpers `similar`'s fingerprints miss.** `duplicate-bodies` normalizes and hashes small callable bodies (comments/whitespace stripped, default `--min-loc 3`) and reports exact matches spanning multiple files — the "escapeRegex copy-pasted into seven files" shape that shape-based similarity scoring is too coarse to flag.
193
+
194
+ **11. Catch a same-name function that drifted apart.** `twin-drift` finds functions with the same (or near-same) name in different files whose bodies have diverged — a strong signal one side got a bug fix, edge case, or feature the other never received. Synthetic leaves and test-only groups are excluded by default.
195
+
196
+ Baseline finding identities are keyed as `detector:file:shortName`. A rename can therefore appear as one fixed identity plus one new identity; refresh the baseline after intentional renames once the changed code has been reviewed.
158
197
 
159
198
  Accepted findings can be recorded without weakening the rest of the gate:
160
199
 
@@ -162,13 +201,15 @@ Accepted findings can be recorded without weakening the rest of the gate:
162
201
  scip-query suppress SQABC123DEF456 --check echo --reason "intentional compatibility shim"
163
202
  ```
164
203
 
165
- This appends a reasoned entry to `.scipquery.json`; `config-validate` rejects suppressions without an identity and reason, and `diff-gate --json` reports both active and suppressed findings.
204
+ This appends a reasoned entry to `.scipquery.json`; `config-validate` requires every suppression to include a reason plus either a stable finding id or both `check` and `file`. Check+file suppressions are allowed but warn because they waive every matching finding in that file. `diff-gate --json` reports both active and suppressed findings.
166
205
 
167
206
  Before any edit, `plan-context <target>` bundles the structural picture — definitions, references, call graph, blast radius — plus a HISTORY section: churn, fix-commit density, and the files that usually change together with the target ("editing this usually means editing these").
168
207
 
169
208
  ## A Health Score You Can Argue With
170
209
 
171
- `scip-query health` refuses to be a vanity number:
210
+ `scip-query health` refuses to be a vanity number.
211
+
212
+ Illustrative output:
172
213
 
173
214
  ```
174
215
  Codebase Health Score: 95/100
@@ -187,7 +228,7 @@ Axes:
187
228
 
188
229
  - **Risk vs. Hygiene** are separate claims: risk components are tied to graph facts and repository-history signals; hygiene components are tidiness. Blending them is how scores become meaningless.
189
230
  - **Every deduction is itemized** — the scalar is auditable, not vibes.
190
- - **The validation axis is a falsifiability loop**: it measures whether flagged files actually attract more fix commits than the rest *in your repo*, per detector. On some codebases a detector tracks repeated fixes; on others it is mostly noise — the tool reports which, instead of assuming.
231
+ - **The validation axis is a falsifiability loop**: it measures whether flagged files actually attract more fix commits than the rest _in your repo_, per detector. On some codebases a detector tracks repeated fixes; on others it is mostly noise — the tool reports which, instead of assuming.
191
232
  - **Suppressions are data**: every `// scip-query: ignore-*` comment is a precision label, counted and reported.
192
233
 
193
234
  ## Accuracy Model
@@ -196,10 +237,12 @@ Evidence tiers are kept explicit, strongest first:
196
237
 
197
238
  1. **Compiler-backed facts** from the SCIP database (`trace`, `refs`, `deps`, `outline`, ...).
198
239
  2. **Semantic augmentation** via `ts-morph` for TypeScript — verified references, callers, callees when SCIP alone is incomplete.
199
- 3. **Source-backed heuristics** (AST/text) for cleanup signals. Always labeled: *"these are candidates, not exact compiler facts."*
240
+ 3. **Source-backed heuristics** (AST/text) for cleanup signals. Always labeled: _"these are candidates, not exact compiler facts."_
200
241
  4. **Compiler verification** for deletions — the only tier that earns the word "safe."
201
242
 
202
- And because accuracy you don't measure is a feeling, `self-audit` samples symbols and scores the cheap paths against the TypeScript compiler:
243
+ And because accuracy you don't measure is a feeling, `self-audit` samples symbols and scores the cheap paths against the TypeScript compiler.
244
+
245
+ Illustrative output:
203
246
 
204
247
  ```
205
248
  references precision 1.0 recall 0.9 (the cheap path doesn't fabricate; it occasionally misses)
@@ -209,11 +252,59 @@ Heuristic detectors carry guardrails learned from real codebases: published `pac
209
252
 
210
253
  ## Agent Skills
211
254
 
212
- `scip-query install-skills` symlinks bundled skills into Claude Code, Codex, and shared agent roots (`~/.agents/skills/`) so they update automatically with the package. The `scip-query` router skill dispatches codebase work to specialists for setup/adoption, health audit and autonomous health improvement, hyper optimization, debugging, issue triage, HTML diagrams, API impact, exploration, planning, cleanup, doc reconciliation, maintainability review, React/Vue review, AI-rot cleanup, language playbooks, and post-change verification.
255
+ `scip-query install-skills` symlinks bundled skills into Claude Code, Codex, and shared agent roots (`~/.agents/skills/`) so they update automatically with the package. The `scip-query` router skill dispatches codebase work to the specialist below; when unsure which owns a task, start there.
256
+
257
+ ### Bundled skills
258
+
259
+ One-line "essential difference" per skill — read this table before the Routes table in `skills/scip-query/SKILL.md` if two names sound alike.
260
+
261
+ | Skill | Essential difference |
262
+ | --- | --- |
263
+ | `scip-query` | Router: dispatches codebase work to the specialist skill below. |
264
+ | `scip-explore` | Understand before touching. |
265
+ | `scip-concrete-plan` | Specify ONE change so an executor can't guess. |
266
+ | `scip-conductor` | Run a multi-phase program (delegate, verify handoffs, pre-registered benchmarks). |
267
+ | `scip-debug` | Root-cause a failure. |
268
+ | `scip-triage-issue` | Package a report into an actionable issue+fix plan. |
269
+ | `scip-verify` | Post-change closeout gate. |
270
+ | `scip-cleanup-audit` | Rank findings, no edits. |
271
+ | `scip-cleanup-improve` | Autonomously fix confirmed findings. |
272
+ | `scip-maintainability` | Is this well-organized (scattered concepts, accidental variation)? |
273
+ | `scip-integrity-audit` | Is this real (decorative checkers, faked implementations, dead fallback-hidden paths)? |
274
+ | `scip-twin-drift` | Same-name implementations that drifted apart. |
275
+ | `scip-claim-audit` | Status words derived vs asserted. |
276
+ | `scip-probe-reachability` | Prove parser/AST branches actually fire. |
277
+ | `scip-api-impact` | Blast radius before changing public surfaces. |
278
+ | `scip-directory-architecture` | Folder/ownership layout. |
279
+ | `scip-doc-reconcile` | Docs vs code drift. |
280
+ | `scip-diagram` | Visual artifacts. |
281
+ | `scip-react-maintainability` | Framework-specific reuse lens (React). |
282
+ | `scip-vue-maintainability` | Framework-specific reuse lens (Vue). |
283
+ | `scip-language-playbook` | Which commands per language. |
284
+ | `scip-hyper-optimization` | Performance campaigns without output changes. |
285
+ | `scip-tla-model-system` | Formal models tied to code evidence. |
286
+ | `scip-setup` | Adopt or repair scip-query in a repo. |
287
+ | `_shared` | Reference loaded by other skills, not user-invoked. |
288
+
289
+ The confusable clusters, disambiguated: `scip-concrete-plan` (one change) vs `scip-conductor` (a program of changes with delegation); `scip-cleanup-audit` (report only) vs `scip-cleanup-improve` (autonomous fixing loop); `scip-verify` (did this specific change land safely) vs `scip-integrity-audit` (does this code actually work at all) vs `scip-maintainability` (is this well organized) vs `scip-twin-drift` (one drifted same-name pair specifically); `scip-directory-architecture` (folder ownership) vs `scip-maintainability` (deeper structural compression). `skills/scip-query/SKILL.md`'s Tie-Breaks section has the full routing logic.
290
+
291
+ Project setup writes reviewable project-local lifecycle hooks for Codex and Claude Code (`.codex/hooks.json` and `.claude/settings.local.json` by default; `setup-hooks --shared` opts into `.claude/settings.json`). These hooks add scip-query context at session start, route prompts toward the right skill, and run an advisory Stop-hook wrapper around the diff gate only for that repository. The Stop hook sends feedback to the agent by default instead of blocking; set `SCIP_QUERY_STOP_HOOK_MODE=warn` for a warning-only hook response, or `SCIP_QUERY_STOP_HOOK_MODE=block` to enforce the gate. Set `SCIP_QUERY_SKIP_HOOK_INSTALL=1` or run `scip-query setup --no-hooks` to skip hook installation during setup, and run `scip-query setup-hooks --json` later to repair the current repo's hooks.
292
+
293
+ For a project, run `scip-query setup`. It installs/refreshes skills, configures project-local hooks unless skipped, checks indexer readiness, attempts configured indexer remediation, refreshes the index, smoke-tests representative command families, writes `docs/scip-query/health-dossier.md` and `.json`, reports the health score and items needing attention, and seeds AGENTS.md/CLAUDE.md guidance. After setup, `scip-cleanup-audit` confirms raw signals and `scip-cleanup-improve` keeps fixing the worst confirmed items until no safe confirmed cleanup remains. Use `scip-query setup --git-hook` when you also want a local pre-commit diff gate. CI setup is intentionally separate.
294
+
295
+ ## Formal Models (TLA+)
296
+
297
+ For the parts of a system where the risk lives in interleaving — retries, concurrency, partial failure, money, a state machine with guards — `scip-query` scaffolds a TLA+ model tied to indexed code and keeps it honest against that code:
213
298
 
214
- Project setup writes reviewable project-local lifecycle hooks for Codex and Claude Code (`.codex/hooks.json` and `.claude/settings.json`). These hooks add scip-query context at session start, route prompts toward the right skill, and run an advisory Stop-hook wrapper around the diff gate only for that repository. The Stop hook warns by default instead of blocking the agent; set `SCIP_QUERY_STOP_HOOK_MODE=feedback` to ask the agent to continue without a hook error, or `SCIP_QUERY_STOP_HOOK_MODE=block` to enforce the gate. Set `SCIP_QUERY_SKIP_HOOK_INSTALL=1` to skip hook installation during setup, or run `scip-query setup-hooks --json` later to repair the current repo's hooks.
299
+ ```bash
300
+ scip-query tla scaffold src/queue/store.ts # draft spec + config + mapping from indexed code
301
+ scip-query tla verify specs/queue/Queue.tla # mechanical conformance: referents, reads/writes, calls, model checker
302
+ scip-query tla instrument specs/queue/Queue.tla # generate a trace recorder + wiring sites for each mapped action
303
+ scip-query tla trace-check specs/queue/Queue.tla --trace traces/run1.json # check a recorded execution against Next
304
+ scip-query tla fetch-tools # download the pinned tla2tools.jar into the cache
305
+ ```
215
306
 
216
- For a project, run `scip-query setup`. It installs/refreshes skills, configures project-local hooks, checks indexer readiness, attempts configured indexer remediation, refreshes the index, smoke-tests representative command families, writes `docs/scip-query/health-dossier.md` and `.json`, reports the health score and items needing attention, and seeds AGENTS.md/CLAUDE.md guidance. After setup, `scip-health-audit` confirms raw signals and `scip-health-improve` keeps fixing the worst confirmed items until the score is as high as reasonably possible. Use `scip-query setup --git-hook` when you also want a local pre-commit diff gate. CI setup is intentionally separate.
307
+ `tla verify` checks the mapping contract against the model text and the indexed code: variable and action referents must resolve to value-like symbols (not types), declared reads/writes are checked against a static scan, and every waiver requires a reason and is counted in the output. At scale, findings are grouped by `(category, modelElement)` with up to 3 exemplars per group by default pass `--full` to print every finding ungrouped. The `scip-tla-model-system` skill (`scip-query install-skills`) walks the scaffold verify instrument trace-check loop end to end.
217
308
 
218
309
  ## Quick Start
219
310
 
@@ -224,7 +315,7 @@ scip-query stats
224
315
  scip-query system src/auth
225
316
  scip-query plan-context login
226
317
  scip-query diff-impact --json
227
- scip-query health --json --full
318
+ scip-query health --json
228
319
  scip-query cleanup-plan --verify
229
320
  scip-query health --write-baseline # start the ratchet
230
321
  ```
@@ -235,18 +326,21 @@ scip-query health --write-baseline # start the ratchet
235
326
  - `scip` CLI, from [Sourcegraph SCIP releases](https://github.com/sourcegraph/scip/releases)
236
327
  - A language-specific SCIP indexer for your project
237
328
 
238
- | Language | Indexer | Install |
239
- |---|---|---|
240
- | TypeScript / JavaScript / Vue | scip-typescript | `npm install -g @sourcegraph/scip-typescript` |
241
- | Java / Scala / Kotlin | scip-java | [releases](https://github.com/sourcegraph/scip-java/releases) |
242
- | Rust | rust-analyzer | Ships with rust-analyzer: `rust-analyzer scip` |
243
- | Python | scip-python-plus | `npm install -g scip-python-plus` |
244
- | Go | scip-go | `go install github.com/sourcegraph/scip-go@latest` |
245
- | Ruby | scip-ruby | [releases](https://github.com/sourcegraph/scip-ruby/releases) |
246
- | C / C++ | scip-clang | [releases](https://github.com/sourcegraph/scip-clang/releases) |
247
- | C# / VB | scip-dotnet | [releases](https://github.com/sourcegraph/scip-dotnet/releases) |
248
- | Dart | scip-dart | [releases](https://github.com/nicovince/scip-dart/releases) |
249
- | PHP | scip-php | [releases](https://github.com/nicovince/scip-php/releases) |
329
+ On Windows, the `scip` binary is installed automatically from npm: `scip-query-scip-windows` is an os-gated optional dependency (universal package, x64 + arm64) that only Windows installs fetch. Resolution order: `scip` on PATH, then `SCIP_QUERY_SCIP_BIN`, then the sidecar package. Run `scip-query check-deps` for platform-specific install instructions.
330
+
331
+ | Language | Indexer | Install |
332
+ | ----------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------- |
333
+ | TypeScript / JavaScript / Vue | scip-typescript | `npm install -g @sourcegraph/scip-typescript` |
334
+ | Java / Scala / Kotlin | scip-java | [releases](https://github.com/sourcegraph/scip-java/releases) |
335
+ | Rust | rust-analyzer | Ships with rust-analyzer: `rust-analyzer scip` |
336
+ | Python | scip-python-plus | `npm install -g scip-python-plus` |
337
+ | Go | scip-go | `go install github.com/sourcegraph/scip-go@latest` |
338
+ | Ruby | scip-ruby | [releases](https://github.com/sourcegraph/scip-ruby/releases) |
339
+ | C / C++ | scip-clang | [releases](https://github.com/sourcegraph/scip-clang/releases) |
340
+ | C# / VB | scip-dotnet | [releases](https://github.com/sourcegraph/scip-dotnet/releases) |
341
+ | Dart | scip-dart | [releases](https://github.com/Workiva/scip-dart/releases) or `dart pub global activate scip_dart` |
342
+ | PHP | scip-php | [releases](https://github.com/davidrjenni/scip-php/releases) or Composer package `davidrjenni/scip-php` |
343
+ | Clojure / ClojureScript | scip-clojure | Requires a `scip-clojure` binary on PATH; source: [PlunderStruck/scip-clojure](https://github.com/PlunderStruck/scip-clojure) |
250
344
 
251
345
  For Python, the executable may be `scip-python`, `scip-python-plus`, or both. `scip-query` accepts either name.
252
346
 
@@ -265,6 +359,19 @@ By default, indexes live in `~/.cache/scip-query/projects/<hash>/`, keeping proj
265
359
  TypeScript monorepos can opt into project sharding with `indexer.typescript.projectMode: "workspace"`. In that mode, `scip-query` discovers repo-local TypeScript project roots, runs one `scip-typescript` process per project with bounded concurrency, merges the shard protobufs, and still publishes one TypeScript language index. Set `indexer.typescript.projects` to an explicit list of project directories or tsconfig paths when automatic discovery is too broad. Set `indexerConcurrency` when a repo needs a persistent worker cap; CLI `--indexer-concurrency` and `SCIP_QUERY_INDEXER_CONCURRENCY` still override ad hoc runs.
266
360
  Use `indexer.typescript.pnpmWorkspaces` only with the default single-project mode; workspace mode passes explicit projects instead.
267
361
 
362
+ Clojure projects can pass a project-local `scip-clojure` config file through `.scipquery.json`:
363
+
364
+ ```json
365
+ {
366
+ "languages": ["clojure"],
367
+ "indexer": {
368
+ "clojure": {
369
+ "configPath": ".scip-clojure.json"
370
+ }
371
+ }
372
+ }
373
+ ```
374
+
268
375
  Most read-only commands accept `--json` and use the same envelope:
269
376
 
270
377
  ```json
@@ -279,26 +386,26 @@ Run this in a project root:
279
386
  scip-query init
280
387
  ```
281
388
 
282
- It creates `.scipquery.json`:
389
+ It creates a minimal `.scipquery.json`:
283
390
 
284
391
  ```json
285
392
  {
286
393
  "languages": ["typescript"],
287
- "indexerConcurrency": 6,
288
394
  "watch": {
289
395
  "enabled": false,
290
396
  "debounceMs": 30000,
291
- "cooldownMs": 60000
292
- },
293
- "indexer": {
294
- "typescript": {
295
- "projectMode": "workspace",
296
- "projects": ["apps/api", "apps/web"]
297
- }
397
+ "cooldownMs": 60000,
398
+ "gitPollMs": 2000,
399
+ "autoRefresh": true
298
400
  }
299
401
  }
300
402
  ```
301
403
 
404
+ Add optional fields such as `indexerConcurrency`, `indexer`, `entryRoots`,
405
+ `declaredCouplings`, and `suppressions` only when the project needs them.
406
+
407
+ `scip-query watch` is a foreground process. It writes a project-local watcher lock and refuses a second watcher for the same index cache; keep one terminal running it, or stop it with Ctrl+C before starting another.
408
+
302
409
  Use `declaredCouplings` for files that intentionally form one maintenance unit.
303
410
  These pairs are treated as structurally linked by `co-change` and health, while
304
411
  still appearing in file-specific exploration. The cleanup detector example
@@ -321,14 +428,20 @@ because they share candidate and evidence policy changes:
321
428
  }
322
429
  ```
323
430
 
431
+ The consumer evidence product migration kept this declared-coupling example
432
+ current: `src/queries/cleanup/stale-abstractions.ts` still belongs to the
433
+ cleanup detector family and still shares candidate/evidence policy with the
434
+ dead and isolated cleanup detectors.
435
+
324
436
  Useful environment variables:
325
437
 
326
- | Variable | Purpose |
327
- |---|---|
328
- | `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory |
329
- | `SCIP_QUERY_INDEX_DB` | Override the SQLite database path |
330
- | `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path |
331
- | `SCIP_QUERY_CACHE_DIR` | Override the cache directory |
438
+ | Variable | Purpose |
439
+ | ------------------------- | --------------------------------------------------------------------- |
440
+ | `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory |
441
+ | `SCIP_QUERY_INDEX_DB` | Override the SQLite database path |
442
+ | `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path |
443
+ | `SCIP_QUERY_CACHE_DIR` | Override the cache directory |
444
+ | `SCIP_QUERY_SCIP_BIN` | Path to a local `scip` binary (overrides PATH and the Windows sidecar) |
332
445
 
333
446
  Query results are filtered through the project's `.gitignore`. If none exists, common generated directories such as `dist/`, `target/`, `node_modules/`, and `.venv/` are excluded by default.
334
447
 
@@ -339,7 +452,7 @@ Query results are filtered through the project's `.gitignore`. If none exists, c
339
452
  - [Agent Guide](docs/AGENT_GUIDE.md): goal-oriented workflows for tracing, planning, cleanup, quality checks, and change verification.
340
453
  - [Command Reference](docs/COMMAND_REFERENCE.md): generated command syntax, descriptions, and options.
341
454
  - [Programmatic API](docs/API.md): using the query functions from TypeScript.
342
- - [Historical plans](docs/plans/): implementation notes and completed cleanup plans.
455
+ - [Historical plans](https://github.com/PlunderStruck/scip-query/tree/main/docs/plans): implementation notes and completed cleanup plans.
343
456
 
344
457
  ## License
345
458
 
@@ -1,2 +1,2 @@
1
- import{c as t}from"./chunk-W2CBNBEL.js";import{writeFileSync as o}from"fs";import{workerData as s}from"worker_threads";var e=s;try{let r=t({projectRoot:e.projectRoot,dbPath:e.dbPath,tsconfig:e.tsconfig,vueFiles:e.vueFiles,tasks:e.tasks});o(e.resultPath,JSON.stringify({ok:!0,result:r}))}catch(r){o(e.resultPath,JSON.stringify({ok:!1,error:r instanceof Error?r.message:String(r)}))}finally{let r=new Int32Array(e.sharedBuffer);Atomics.add(r,0,1),Atomics.notify(r,0)}
1
+ import{e as t}from"./chunk-FERAXG6Y.js";import{writeFileSync as o}from"fs";import{workerData as s}from"worker_threads";var e=s;try{let r=t({projectRoot:e.projectRoot,dbPath:e.dbPath,tsconfig:e.tsconfig,vueFiles:e.vueFiles,tasks:e.tasks});o(e.resultPath,JSON.stringify({ok:!0,result:r}))}catch(r){o(e.resultPath,JSON.stringify({ok:!1,error:r instanceof Error?r.message:String(r)}))}finally{let r=new Int32Array(e.sharedBuffer);Atomics.add(r,0,1),Atomics.notify(r,0)}
2
2
  //# sourceMappingURL=augment-vue-worker.js.map
@@ -0,0 +1,2 @@
1
+ import{b as r}from"./chunk-XHWLNQVZ.js";import{k as e}from"./chunk-R3JY4EZ4.js";function l(t,s){let o=r(t,s);return e(t,o).map(({relativePath:n,...a})=>a)}export{l as a};
2
+ //# sourceMappingURL=chunk-2VSDXOG5.js.map
@@ -0,0 +1,2 @@
1
+ import{b as oe}from"./chunk-B75HZHUP.js";import{a as N}from"./chunk-X4O6K47U.js";import{b as J,e as $,f as G,g as X}from"./chunk-NAH5EAZS.js";import{c as se}from"./chunk-QJ3FK4TB.js";import{c as Y,d as ee,e as te,f as ne,l as ie}from"./chunk-WFGOH2UI.js";import{e as re}from"./chunk-C4ICAIJ4.js";import{j as Q,o as _}from"./chunk-R3JY4EZ4.js";import{d as U,g as H,h as V,i as K,j as Z,k as q}from"./chunk-HXXMPYEF.js";import{m as W}from"./chunk-T2FQ4GHD.js";import{A as P,x as z}from"./chunk-ISLWJ4PY.js";import{b as O,l as b,m as B,o as j,p as I}from"./chunk-WS3Z6W3M.js";import{c as w}from"./chunk-GNG622H3.js";import{a as R}from"./chunk-64MNV6AB.js";import{b as L}from"./chunk-7S5E7KWT.js";var x=new WeakMap,ae=B({kind:"definition-exclusions",invalidation:j("definition-exclusions"),serialize:e=>JSON.stringify(e),deserialize:De});function le(e,t){let n=z(t);if(!(n==="rust"||n==="typescript"||n==="tsx"||n==="javascript"))return[];let r=I(e,t);if(!r)return[];let s=O(e,t,r),a=ae.read(e,t,s);if(a)return a;let u=n==="rust"?Te(e,t):Pe(e,t);return ae.write(e,t,s,u),u}function De(e){try{let t=JSON.parse(e);return!Array.isArray(t)||!t.every(Le)?null:t}catch{return null}}function Le(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.startLine!="number"||!Number.isFinite(t.startLine)||typeof t.endLine!="number"||!Number.isFinite(t.endLine)||typeof t.reason!="string"?!1:t.containerName===void 0||typeof t.containerName=="string"}var ue=new Set(["describe","it","test","fdescribe","fit","xdescribe","xit","beforeEach","afterEach","beforeAll","afterAll","before","after","suite","bench","benchmark"]),we=/\b(?:describe|it|test|fdescribe|fit|xdescribe|xit|beforeEach|afterEach|beforeAll|afterAll|before|after|suite|bench|benchmark)\s*\(/,Ie=/\b(?:export\s+)?(?:async\s+)?function\s+use[A-Z][A-Za-z0-9_$]*\b|\b(?:const|let|var)\s+use[A-Z][A-Za-z0-9_$]*\s*(?::[^=;]+)?=\s*(?:async\s*)?(?:function\b|(?:<[^=;{]+>\s*)?(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>)/;function Pe(e,t){let n=I(e,t);if(!n||!Ne(n))return[];let i=P(e,t);if(!i)return[];let r=x.get(i);if(r)return r;let s=!1,a=i.rootNode;for(let l of a.namedChildren){if(l.type!=="expression_statement")continue;let d=l.namedChild(0);if(!d||d.type!=="call_expression")continue;let o=d.namedChild(0);if(!o)continue;let c=o.type==="member_expression"?o.namedChild(o.namedChildCount-1)?.text:o.text;if(c&&ue.has(c)){s=!0;break}}let u=[];s&&u.push({startLine:0,endLine:a.endPosition.row,reason:"TS/JS test file (describe/it/test at top level)"});for(let l of a.namedChildren){let d=null,o=null;if(l.type==="function_declaration")d=l.namedChild(0)?.text??null,o=l;else if(l.type==="export_statement"){let c=l.namedChild(0);c?.type==="function_declaration"&&(d=c.namedChild(0)?.text??null,o=c)}else if(l.type==="lexical_declaration"){let c=l.namedChild(0);if(c?.type==="variable_declarator"){let p=c.namedChild(0)?.text,m=c.namedChild(1);p&&(m?.type==="arrow_function"||m?.type==="function_expression")&&(d=p,o=c)}}d&&/^use[A-Z]/.test(d)&&o&&u.push({startLine:o.startPosition.row,endLine:o.endPosition.row,reason:"React custom hook (use*)"})}return u.push(...de(i,new Set(["function_declaration","method_definition","class_declaration","interface_declaration","type_alias_declaration","enum_declaration","variable_declarator","export_statement"]),new Set(["comment"]))),x.set(i,u),u}function Ne(e){if(e.includes("scip-query"))return!0;let t=!1;for(let n of ue)if(e.includes(n)){t=!0;break}return t&&we.test(e)?!0:e.includes("use")&&Ie.test(e)}var ke=/scip-query[\s:-]*ignore[\s:-]*(?:dead(?:-code)?|stale)?/i;function Fe(e){return ke.test(e)}function de(e,t,n){let i=[],r=s=>{if(t.has(s.type)&&s.parent){let u=s.parent.children,l=-1;for(let d=0;d<u.length;d+=1)if(u[d].startIndex===s.startIndex&&u[d].type===s.type){l=d;break}if(l>0)for(let d=l-1;d>=0;d-=1){let o=u[d];if(n.has(o.type)){if(Fe(o.text)){i.push({startLine:s.startPosition.row,endLine:s.endPosition.row,reason:"scip-query suppression comment"});break}continue}if(!(o.type==="attribute_item"||o.type==="inner_attribute_item"))break}}for(let a of s.namedChildren)r(a)};return r(e.rootNode),i}function Te(e,t){let n=P(e,t);if(!n)return[];let i=x.get(n);if(i)return i;let r=[],s=Ae(n);return s?(x.set(n,s),s):(fe(n.rootNode,r,!1,!1),r.push(...de(n,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(...He(n.rootNode)),x.set(n,r),r)}function Ae(e){return Ve(e.rootNode)?[{startLine:0,endLine:e.rootNode.endPosition.row,reason:"generated file (@generated header)"}]:null}function fe(e,t,n,i){let r=n,s=i;e.type==="trait_item"&&t.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"trait declaration body (dynamic dispatch)"}),e.type==="impl_item"&&e.childForFieldName("trait")&&(s=!0,t.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"trait impl block (dynamic dispatch)"})),e.type==="function_item"||e.type==="function_signature_item"?Me(e,t,n,i):i&&Ue(e)?t.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"?Oe(e,t,n):e.type==="mod_item"&&k(e).some(a=>/#\[\s*cfg\s*\(\s*test\s*\)/.test(a))&&(r=!0);for(let a of e.namedChildren)fe(a,t,r,s)}function Me(e,t,n,i){let r=k(e),s=null;i?s="trait impl method (dynamic dispatch)":n&&(s="inside #[cfg(test)] mod");for(let a of r){let u=je(a);if(u){s=u;break}if(me(a)){s="#[allow(dead_code)]";break}}s&&t.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:s})}function Oe(e,t,n){let i=k(e),r=e.namedChildren.find(s=>s.type==="type_identifier")?.text;i.some(We)&&t.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"#[derive(<reflective>)] \u2014 fields accessed via macro/reflection",containerName:r}),i.some(me)&&t.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"#[allow(dead_code)]",containerName:r}),n&&t.push({startLine:e.startPosition.row,endLine:e.endPosition.row,reason:"inside #[cfg(test)] mod",containerName:r})}function k(e){let t=e.parent;if(!t)return[];let n=t.children,i=-1;for(let s=0;s<n.length;s+=1)if(n[s].startIndex===e.startIndex&&n[s].type===e.type){i=s;break}if(i<=0)return[];let r=[];for(let s=i-1;s>=0;s-=1){let a=n[s];if(a.type==="attribute_item"||a.type==="inner_attribute_item")r.push(a.text);else{if(a.type==="line_comment"||a.type==="block_comment")continue;break}}return r}var Be=[{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 je(e){return Be.find(({re:t})=>t.test(e))?.reason??null}var ze=[/\bSerialize\b/,/\bDeserialize\b/,/\bFromRow\b/,/\bsqlx::FromRow\b/,/\bDeriveEntityModel\b/,/\bIntoSchema\b/,/\bToSchema\b/,/\bDeriveValueType\b/,/\bError\b/,/\bthiserror::Error\b/];function We(e){return/#\[\s*derive\s*\(/.test(e)?ze.some(t=>t.test(e)):!1}function me(e){return/#\[\s*allow\s*\(\s*dead_code\s*\)/.test(e)}function Ue(e){return e.type==="const_item"||e.type==="type_item"||e.type==="static_item"||e.type==="associated_type"}function He(e){let t=Ze(e);if(t.size===0)return[];let n=[];for(let i of e.descendantsOfType("mod_item")){let r=i.childForFieldName("name")?.text;r&&t.has(r)&&n.push({startLine:i.startPosition.row,endLine:i.endPosition.row,reason:'serde `with = "..."` module \u2014 body invoked via reflection',containerName:r})}return n}function Ve(e){for(let t=0;t<Math.min(e.namedChildCount,12);t+=1){let n=e.namedChild(t);if(!n||n.type!=="line_comment"&&n.type!=="block_comment")break;if(/@generated\b/.test(n.text)||/This file is .*generated\b/i.test(n.text)||/Code generated by/i.test(n.text)||/Generated by:\s*https?:\/\/openapi-generator/i.test(n.text)||/openapi-generator/i.test(n.text)&&/Generated by/i.test(n.text))return!0}return!1}var Ke=/^#!?\[\s*serde\s*\(/,ce=/\bwith\s*=\s*"([^"]+)"/g;function Ze(e){let t=new Set;for(let n of e.descendantsOfType("attribute_item")){if(!Ke.test(n.text))continue;ce.lastIndex=0;let i;for(;(i=ce.exec(n.text))!==null;){let r=i[1],s=r.split("::").pop()??r;s&&t.add(s)}}return t}function pe(e){let t=new Map,n=i=>{let r=t.get(i);if(r)return r;let s=le(e,i);return r={ranges:s.map(a=>({startLine:a.startLine,endLine:a.endLine})),containers:new Set(s.map(a=>a.containerName).filter(a=>!!a))},t.set(i,r),r};return(i,r,s,a)=>{let u=n(i);for(let l of u.ranges)if(r>=l.startLine&&r<=l.endLine)return!0;if(a&&u.containers.has(a))return!0;for(let l of _(s))if(u.containers.has(l))return!0;return!1}}function gt(e,t={}){L(e,{groups:t.semanticProvider===!0?["whole-project","semantic-provider"]:["whole-project"]})}function be(e,t,n={}){L(e,{groups:n.definitions===!0?["source-file","definition-catalog"]:["source-file"],file:t.replace(/\\/g,"/")})}function ye(e,t){return t.isIgnoredPath(e.relativePath)?y("ignored-file"):K(e.symbol)?y("module-like-symbol"):E(e.symbol)?!e.isFunctionLike&&e.enclosingSymbol&&E(e.enclosingSymbol)?y("nested-non-callable-value"):!t.includeTests&&!S(e.relativePath)?y("test-file"):!t.includeTests&&t.isExcludedRegion(e.relativePath,e.startLine,e.symbol,e.parentTypeName)?y("excluded-file-region"):Z(e.symbol)?y("rust-trait-impl-member"):q(e.symbol)?y("rust-test-module"):!t.includeMembers&&!qe(e)?y("member"):e.endLine-e.startLine+1<t.minLoc?y("below-min-loc"):{accepted:!0}:y("non-value-symbol")}function S(e){return J(e)!=="test"}function y(e){return{accepted:!1,rejectionReason:e}}function E(e){return V(e)||e.endsWith("().")||e.endsWith(".")}function qe(e){return H(e.symbol)||_(e.symbol).length===0}function ge(){return new Map}function he(e,t,n){let i=new Map;for(let r of Y(e,n))e.isIgnored(r.relative_path)||t.has(r.relative_path)||v(i,r.symbol_id,r.relative_path,r.ref_count,"scip-mention");return i}function xe(e,t,n,i={}){let r=new Set;if(i.conservative||n.size===0){for(let s of te(e,t))r.add(s.symbol_id);return r}for(let s of ee(e,t))e.isIgnored(s.relative_path)||n.has(s.relative_path)||r.add(s.symbol_id);return r}function F(e,t){let n=e.get(t);if(!n)return!1;for(let i of n.values())if(i.occurrences>0)return!0;return!1}function C(e,t,n){let i=e.get(t);if(!i)return!1;for(let[r,s]of i)if(r!==n&&s.occurrences>0)return!0;return!1}function Se(e){return e?.occurrences??0}function v(e,t,n,i,r="source-fallback"){if(i<=0)return;let s=_e(e,t,n);s.occurrences+=i,s.sources.add(r)}function Re(e,t,n,i,r){if(i<=0)return;let s=_e(e,t,n);s.occurrences=Math.max(i,s.occurrences),s.sources.add(r)}function _e(e,t,n){let i=e.get(t);i||(i=new Map,e.set(t,i));let r=i.get(n);return r||(r={occurrences:0,sources:new Set},i.set(n,r)),r}var Je=3e3,$e=1e3;function Ut(e,t={}){let{scope:n,minLoc:i=1,includeTests:r=!1,skipBarrels:s=!1,includeMembers:a=!1,deadCodeOnly:u=!1,scanLimit:l,semantic:d=!0}=t,o=0,c=b("dead.candidates",()=>{let f=oe(Ge(e,{scope:n,minLoc:i,includeTests:r,includeMembers:a}),l);return o=f.length,f},()=>({definitions:o})),p=0,m=s?b("dead.inactive-barrels",()=>{let f=new Set($(e));return p=f.size,f},()=>({paths:p})):new Set,T=0,g=u?ge():b("dead.mention-reference-counts",()=>{let f=he(e,m,c.map(D=>D.symbolId));return T=f.size,f},()=>({definitions:c.length,symbolsWithReferences:T})),A=0,Ce=u?b("dead.mentioned-symbol-ids",()=>{let f=xe(e,c.map(D=>D.symbolId),m,{conservative:m.size===0});return A=f.size,f},()=>({definitions:c.length,referencedSymbols:A})):new Set,h=u?c.filter(f=>!Ce.has(f.symbolId)):c.filter(f=>!C(g,f.symbolId,f.relativePath));u?b("dead.source-fallback.dead-code-only",()=>tt(e,h,g,{includeTests:r,inactiveBarrelPaths:m}),()=>({definitions:h.length,includeTests:r})):b("dead.source-fallback.ast",()=>et(e,h,g,{includeTests:r,inactiveBarrelPaths:m}),()=>({definitions:h.length,includeTests:r}));let M=u?h.filter(f=>!F(g,f.symbolId)):h.filter(f=>!C(g,f.symbolId,f.relativePath));b("dead.caller-map-supplement",()=>ot(e,M,g,{includeTests:r,inactiveBarrelPaths:m,includeSemantic:!u&&d}),()=>({definitions:M.length,semantic:!u&&d}));let ve=u?h.filter(f=>!F(g,f.symbolId)):c;return Ye(e,Xe(ve,g))}function Ge(e,t){let n=pe(e),i=[];for(let r of Q(e,{scope:t.scope,symbolMatches:E,sqlPrefilter:"function-like"}))ye(r,{minLoc:t.minLoc,includeTests:t.includeTests,includeMembers:t.includeMembers,isIgnoredPath:a=>e.isIgnored(a),isExcludedRegion:n}).accepted&&i.push(r);return i}function Xe(e,t){return e.map(n=>Qe(n,t)).filter(n=>n.cross_file_refs===0).sort((n,i)=>i.loc-n.loc||n.relative_path.localeCompare(i.relative_path)||n.start_line-i.start_line)}function Qe(e,t){let n=t.get(e.symbolId)??new Map,i=Se(n.get(e.relativePath)),r=0;for(let[s,a]of n)s!==e.relativePath&&(r+=a.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 Ye(e,t){let n=[],i=0,r=0,s=0;for(let a of t){if(e.isIgnored(a.relative_path)||G(e,a.relative_path)||X(e,a.symbol,a.relative_path))continue;let u=a.same_file_refs===0?"dead-code":"file-internal";u==="dead-code"?i++:r++,s+=a.loc,n.push({relativePath:a.relative_path,startLine:a.start_line,endLine:a.end_line,loc:a.loc,symbol:a.symbol,shortName:U(a.symbol),sameFileRefs:a.same_file_refs,kind:u})}return{symbols:n,counts:{total:n.length,deadCode:i,fileInternal:r,loc:s},totalCount:n.length,deadCodeCount:i,fileInternalCount:r,totalLoc:s}}function et(e,t,n,i){if(t.length===0)return;let r=new N(e),s=new Set(t.map(l=>l.symbolId)),a=new Set(t.map(l=>l.leaf).filter(Boolean)),u=new Set(r.sourceFiles());for(let l of R(e))u.add(l);r.scanSourceReferences({paths:u,includeVueSfc:!0,includeCrossLanguageDispatchNames:!0,includeRustAttributeNames:!0,identifierResolution:"permissive",candidateNames:a,skipPath:l=>i.inactiveBarrelPaths.has(l)||!i.includeTests&&!S(l)},l=>{s.has(l.target.symbolId)&&(it(e,l)||v(n,l.target.symbolId,l.sourceFile,st(l),"source-fallback"))})}function tt(e,t,n,i){if(t.length===0)return;let r=new N(e),s=nt(t),a=new Set(r.sourceFiles());for(let o of R(e))a.add(o);let u=new Set(s.keys()),l=new Map,d=o=>{let c=l.get(o);return c||(c=ie(e,o),l.set(o,c)),c};r.scanSourceReferences({paths:a,includeVueSfc:!0,includeCrossLanguageDispatchNames:!0,includeRustAttributeNames:!0,identifierResolution:"permissive",candidateNames:u,skipPath:o=>i.inactiveBarrelPaths.has(o)||!i.includeTests&&!S(o),resolveTargets:({sourceFile:o,name:c,kind:p})=>{let m=s.get(c);return m?rt(o,c,m,()=>d(o),{permissive:p!=="cross-language-dispatch"}):[]},afterPath:o=>{l.delete(o),be(e,o)}},o=>{let c=o.kind==="identifier"&&o.sourceFile===o.target.relativePath?Math.max(0,o.occurrences-1):o.occurrences;o.kind==="identifier"&&Ee(e,{sourceFile:o.sourceFile,name:o.name,target:o.target,occurrences:c})||v(n,o.target.symbolId,o.sourceFile,c,"source-fallback")})}function nt(e){let t=new Map;for(let n of e){if(!n.leaf)continue;let i=t.get(n.leaf)??[];i.push(n),t.set(n.leaf,i)}return t}function rt(e,t,n,i,r){let s=n.filter(d=>d.relativePath===e);if(s.length>0)return s;if(!r.permissive&&n.length===1)return[...n];let a=i(),u=a.get(t);if(u)for(let d of u){let o=n.filter(c=>w(d,c.relativePath));if(o.length>0)return o}let l=new Set;for(let d of a.values())for(let o of d)l.add(o);for(let d of l){let o=n.filter(c=>w(d,c.relativePath));if(o.length>0&&o.length===n.length)return o}return r.permissive?[...n]:[]}function it(e,t){return t.kind==="cross-language-dispatch"&&t.target.relativePath===t.sourceFile?!0:t.kind==="identifier"&&Ee(e,t)}function st(e){return e.kind==="identifier"&&e.target.relativePath===e.sourceFile?Math.max(0,e.occurrences-1):e.occurrences}function Ee(e,t){return t.occurrences>1?!1:W(e,t.sourceFile).some(n=>n.used||n.sourcePath!==t.target.relativePath?!1:n.importedName===t.name||n.localName===t.name)}function ot(e,t,n,i){let r=i.includeSemantic!==!1,s=r&&t.length>=Je&&R(e).length>=$e,a=(o,c)=>{c===o.relativePath||e.isIgnored(c)||i.inactiveBarrelPaths.has(c)||!i.includeTests&&!S(c)||Re(n,o.symbolId,c,1,"caller-map")};if(s?b("dead.caller-map.mention-chunks",()=>at(e,t,a),()=>({definitions:t.length})):b("dead.caller-map.per-symbol",()=>{for(let o of t){let c=se(e,o,{semantic:r});if(c.length!==0)for(let p of c)a(o,p.file)}},()=>({definitions:t.length,semantic:r})),!s)return;let u=0,l=b("dead.caller-map.semantic-candidates",()=>{let o=t.filter(c=>!C(n,c.symbolId,c.relativePath));return u=o.length,o},()=>({definitions:t.length,semanticCandidates:u}));if(l.length===0)return;let d=re(e,l);for(let o of l){let c=d.get(o.symbolId);if(c)for(let p of c)a(o,p)}}function at(e,t,n){let i=new Map(t.map(r=>[r.symbolId,r]));for(let r of ne(e,[...i.keys()])){let s=i.get(r.symbol_id);s&&n(s,r.relative_path)}}export{gt as a,Ut as b};
2
+ //# sourceMappingURL=chunk-343O6EVV.js.map
@@ -0,0 +1,7 @@
1
+ import{a as j}from"./chunk-QARYU7R3.js";import{a as N,b as g,c as W}from"./chunk-VGMUFW3J.js";import{a as _}from"./chunk-K6UI6EBZ.js";import{a as E}from"./chunk-B75HZHUP.js";import{a as P}from"./chunk-X4O6K47U.js";import{a as k}from"./chunk-BGBBVSH4.js";import{g as C}from"./chunk-QJ3FK4TB.js";import{a as w}from"./chunk-WFGOH2UI.js";import{m as L}from"./chunk-R3JY4EZ4.js";import{d,e as y,k as v}from"./chunk-HXXMPYEF.js";import{g as x}from"./chunk-T2FQ4GHD.js";import{l as S}from"./chunk-WS3Z6W3M.js";import{basename as m,extname as b}from"path";function ae(t,n){let{scope:e,maxLoc:i=15,limit:a=30,scanLimit:o}=n??{},r=new P(t),s=z(r.fileDependencyGraph(e));return _({candidates:()=>B(t,r,e,i),orderCandidates:E,scanLimit:o,profile:{name:"wrapper-candidates"},prepare:l=>({callerFileMap:A(t,r,l,{semantic:n?.semantic!==!1}),reverseFanIn:s}),evaluate:(l,u)=>O(t,r,l,u),orderResults:(l,u)=>u.callerFanIn-l.callerFanIn||u.loc-l.loc,limit:a})}function A(t,n,e,i){let a=N(t,n),o=g(a.forDefinitions(e,{semantic:!1,sourceFallback:!1})),r=[];i.semantic&&S("wrapper.semantic-candidates",()=>{r=e.filter(c=>F(t,n,c,o).length<=1)},()=>({symbols:e.length,semanticCandidates:r.length}));let s=r.length===0?new Map:g(a.forDefinitions(r,{semantic:!0,sourceFallback:!1})),l=s.size===0?o:C(o,s),u=new Map(e.map(c=>[c.symbolId,c])),f=new Map;for(let c of e){let I=F(t,n,c,l);if(I.length>1||(f.set(c.symbolId,c),I.length!==1))continue;let D=I[0],M=R(t,c.symbolId,D);if(!M)continue;let p=T(n,t,D,c.symbol,M);p?.isFunctionLike&&u.has(p.symbolId)&&f.set(p.symbolId,u.get(p.symbolId))}let h=[...f.values()];return h.length===0?l:C(l,g(a.forDefinitions(h,{semantic:!1,sourceFallback:!0})))}function O(t,n,e,i){let a=F(t,n,e,i.callerFileMap);if(a.length!==1)return null;let o=a[0],r=R(t,e.symbolId,o);if(!r)return null;let s=T(n,t,o,e.symbol,r);if(s&&v(s.symbol))return null;let{fanIn:l,source:u}=J(i.callerFileMap,i.reverseFanIn,o,s);if(u==="function"?l<=3:l<=5)return null;let f=H(t,e,o,s);return{symbol:e.symbol,shortName:d(e.symbol),file:e.relativePath,startLine:e.startLine,endLine:e.endLine,loc:k(e),singleCaller:s?.symbol??"",singleCallerShort:s?.isFunctionLike?d(s.symbol):m(o),callerFanIn:l,actionTier:f.length>0?"signal":"direct",boundaryEvidence:f}}function B(t,n,e,i){return n.productionCallableDefinitions({scope:e,minLoc:2,maxLoc:i,requireFunctionLikeSymbol:!0,excludeRootedSymbols:!0}).filter(a=>!x(t,a))}function F(t,n,e,i){let a=m(e.relativePath,b(e.relativePath)),o=[...i.get(e.symbolId)??[]].filter(r=>r!==e.relativePath).filter(r=>m(r,b(r))!==a).filter(r=>{let s=n.fileKind(r);return s!=="barrel"&&s!=="entry"&&s!=="test"});return W(t,e,o).realConsumers}function R(t,n,e){return t.get(`SELECT c.start_line, c.end_line
2
+ FROM mentions m
3
+ JOIN chunks c ON m.chunk_id = c.id
4
+ JOIN documents d ON c.document_id = d.id
5
+ WHERE m.symbol_id = ? AND m.role != 1 AND d.relative_path = ?
6
+ LIMIT 1`,n,e)}function T(t,n,e,i,a){let o=t.definitionsForFile(e),r=q(n,e,i,a.start_line,a.end_line);return L(o,r)}function J(t,n,e,i){if(i?.isFunctionLike){let a=[...t.get(i.symbolId)??[]].filter(o=>o!==i.relativePath);if(a.length>0)return{fanIn:a.length,source:"function"}}return{fanIn:G(n,e),source:"file"}}function q(t,n,e,i,a){let o=y(e);if(!o)return i;let r=w(t,n).get(o);if(!r||r.length===0)return i;for(let s of r)if(s>=i&&s<=a)return s;return i}function z(t){let n=new Map;for(let[e,i]of t){n.has(e)||n.set(e,n.get(e)??0);for(let a of i)n.set(a,(n.get(a)??0)+1)}return n}function G(t,n){let e=t.get(n)??0;if(e>0)return e;let i=m(n,b(n)),a=0;for(let[o,r]of t)o!==n&&m(o,b(o))===i&&r>a&&(a=r);return a}function H(t,n,e,i){return j(t,n.relativePath,n.startLine,"wrapper","explicit ignore-wrapper comment",[{label:"wrapper name",value:d(n.symbol)},{label:"caller name",value:i?.symbol?d(i.symbol):m(e)},{label:"wrapper path",value:n.relativePath},{label:"caller path",value:e}])}export{ae as a};
7
+ //# sourceMappingURL=chunk-3KDUITBE.js.map
@@ -0,0 +1,2 @@
1
+ import{c as i}from"./chunk-B75HZHUP.js";import{a,c as m}from"./chunk-QJ3FK4TB.js";import{a as r}from"./chunk-WQHWIVA7.js";import{d as o}from"./chunk-HXXMPYEF.js";function S(s,n,c={}){let e=r(s,n);if(!e)return null;let t=c.semantic!==!1,y=m(s,e,{limit:50,semantic:t}),b=i(a(s,e,{limit:50,additive:!0,callableOnly:!0,semantic:t}));return{symbol:e.symbol,shortName:o(e.symbol),callers:y.map(l=>({symbol:l.symbol,shortName:o(l.symbol),file:l.file})),callees:b.map(l=>({symbol:l.symbol,shortName:o(l.symbol),file:l.file}))}}export{S as a};
2
+ //# sourceMappingURL=chunk-3T2FNHIU.js.map
@@ -0,0 +1,2 @@
1
+ import{a as f}from"./chunk-X4O6K47U.js";import{a as L}from"./chunk-WQHWIVA7.js";import{d as i,e as b,f as u,l as c}from"./chunk-HXXMPYEF.js";import{d as l}from"./chunk-T2FQ4GHD.js";import{x as a}from"./chunk-ISLWJ4PY.js";function S(o,s){let t=L(o,s);if(!t)return[];let e=new f(o).definitionsForFile(t.relativePath).filter(r=>r.symbol!==t.symbol).filter(r=>c(t.symbol,r.symbol)).sort((r,m)=>r.startLine-m.startLine||r.endLine-m.endLine).map(r=>({symbol:r.symbol,shortName:i(r.symbol),startLine:r.startLine,endLine:r.endLine,kind:u(r.symbol)??"unknown"}));return a(t.relativePath)!=="clojure"?e:d(e,y(o,t))}function y(o,s){let t=b(s.symbol);if(!t)return[];let n=i(s.symbol);return(l(o,s.relativePath)?.clojureMembers??[]).filter(e=>e.ownerName===t).map(e=>({symbol:`${s.symbol}${e.memberName}().`,shortName:`${n}:${e.memberName}()`,startLine:e.startLine,endLine:e.endLine,kind:e.memberKind}))}function d(o,s){let t=new Map;for(let n of[...o,...s])t.set(`${n.shortName}:${n.startLine}:${n.endLine}`,n);return[...t.values()].sort((n,e)=>n.startLine-e.startLine||n.endLine-e.endLine)}export{S as a};
2
+ //# sourceMappingURL=chunk-3V6JQQM5.js.map
@@ -0,0 +1,2 @@
1
+ import{a as R,b as P}from"./chunk-KJCDEDQW.js";import{a as C,c as B,e as a,f}from"./chunk-6XA4LDHY.js";import{a as v,b as h,c as k}from"./chunk-KMVGRIO2.js";import{F as g}from"./chunk-ISLWJ4PY.js";function D(e,o={}){let{minSimilarity:r=.62,minTokens:n=8,limit:l=20,scope:m,scanLimit:d,filePattern:p,focusFiles:u}=o,c=g(e).reactProfiles({scope:m,minJsxTokens:n,scanLimit:d}).filter(t=>t.kind==="component").map(t=>({file:t.file,component:t.name,tokens:t.jsxTokens,profile:t})),s=R(c,t=>t.tokens);return P({profiles:c,limit:l,filePattern:p,focusFiles:u,candidateIndex:s,profile:{name:"react-component-duplicates"},compare:(t,i)=>y(t,i,r),sort:(t,i)=>i.similarity-t.similarity||t.fileA.localeCompare(i.fileA)||t.componentA.localeCompare(i.componentA)||t.fileB.localeCompare(i.fileB)||t.componentB.localeCompare(i.componentB)})}function y(e,o,r){let n=v(e.tokens,o.tokens);if(n.size<6||!T(n))return null;let l=k(e.tokens,o.tokens);if(l<r)return null;let m=a(n,"component:"),d=a(n,"native:"),p=a(n,"prop:"),u=a(n,"event:"),c=a(n,"binding:"),s=b({sharedComponents:m,sharedNativeTags:d,sharedProps:p,sharedEvents:u,sharedBindings:c});return{fileA:e.file,componentA:e.component,fileB:o.file,componentB:o.component,similarity:l,sharedTokens:f(n),sharedComponents:m,sharedNativeTags:d,sharedProps:p,sharedEvents:u,sharedBindings:c,evidenceClass:s.evidenceClass,actionTier:s.actionTier,evidenceClassReasons:s.reasons,recommendation:s.recommendation,uniqueToA:f(h(e.tokens,o.tokens)).slice(0,25),uniqueToB:f(h(o.tokens,e.tokens)).slice(0,25),locA:e.profile.loc,locB:o.profile.loc}}function T(e){let o=0,r=0;for(let n of e)n.startsWith("component:")&&(o+=1),(n.startsWith("prop:")||n.startsWith("event:")||n.startsWith("native:")||n.startsWith("jsx:"))&&(r+=1);return B([{name:"component",count:o},{name:"shape",count:r}],[{min:{component:1},reason:"shared custom component"},{min:{shape:4},reason:"shared JSX structure"}]).pass}function b(e){return C({genericWords:x,primitiveGroups:[{values:e.sharedNativeTags,reasonPrefix:"shared native tags",bucket:"generic"},{values:e.sharedProps,reasonPrefix:"shared props",bucket:"generic"},{values:e.sharedEvents,reasonPrefix:"shared events",bucket:"generic"}],nameGroups:[{names:e.sharedComponents,label:"shared component",fallbackBucket:"generic"},{names:e.sharedBindings,label:"shared binding",fallbackBucket:"generic"}],recommendation:w})}function w(e){switch(e){case"domain-behavior":case"mixed":return"Review for a shared component or feature-specific UI primitive around the named domain structure.";case"shared-abstraction":return"Review the existing shared component usage first; extract only if duplicated structure remains outside it.";case"generic-workflow-scaffolding":return"Generic structural overlap \u2014 verify intent before consolidating."}}var x=new Set(["actions","app","button","card","children","content","container","dialog","field","form","header","input","item","label","layout","list","modal","page","panel","row","section","shell","table","text","toolbar","ui","value","view","wrapper"]);export{D as a};
2
+ //# sourceMappingURL=chunk-5AAAEZ2Z.js.map
@@ -0,0 +1,8 @@
1
+ import{a as T,c as E,g as L,h as D}from"./chunk-GHXRVCIY.js";import{j as O,o as A}from"./chunk-STBXCPKY.js";import{d as H}from"./chunk-KMVGRIO2.js";import{a as _}from"./chunk-X4O6K47U.js";import{d as C,e as F}from"./chunk-HXXMPYEF.js";import{a as w}from"./chunk-T2FQ4GHD.js";var J=5;function ae(e,t={}){let{base:a="HEAD",minContainment:o=.7,minCallees:r=3,minSiteCoverage:n=.4,maxHelpers:c=Number.POSITIVE_INFINITY,limit:m=20,scanLimit:g}=t,f=t.semantic!==!1,s=t.diffPlan??E(e,{base:a}),l={available:s.note!==T,base:a,changedFiles:s.changedFiles,helpersChecked:0,skipped:[],findings:[]};if(!l.available||s.changedFiles.length===0)return l;let x=new _(e),k=new Set(s.changedFiles),$=new Map(s.renamedFiles.map(i=>[i.to,i.from])),j=t.baseContentAt??L(e.config.projectRoot,a,D(s)),h=Z(x,k,$,j);if(h.length===0)return l;let R=h.slice(0,c);h.length>c&&(l.note=`helper scoring capped at ${c} of ${h.length} new symbols`);let q=x.calleeMap(R,{semantic:f}),B=R.map(i=>({def:i,callees:A((q.get(i.symbolId)??[]).map(p=>p.symbol))})),V=O(e),M,G=()=>(M??=V.calleeIndex({minCallees:Math.min(3,r),scanLimit:g,semantic:f}),M);for(let{def:i,callees:p}of B){let d=C(i.symbol);if(p.size<r){l.skipped.push({helperShortName:d,helperFile:i.relativePath,reason:`fewer than ${r} meaningful callees \u2014 too small to score`});continue}let P=G(),N=Y(p,P);if(N===0){l.skipped.push({helperShortName:d,helperFile:i.relativePath,reason:"helper callee pattern is all project-wide infrastructure \u2014 too generic to score"});continue}let b=Q(e,i.symbolId);if(b.length===0){l.skipped.push({helperShortName:d,helperFile:i.relativePath,reason:"no references yet \u2014 covered by the new-dead check"});continue}l.helpersChecked+=1;let I=K({candidateIndex:P,changed:k,helperCallees:p,helperFile:i.relativePath,helperSymbol:i.symbol,minContainment:o,minSiteCoverage:n,migratedFiles:b});I.length!==0&&(I.sort((u,S)=>z(S.migrationScope)-z(u.migrationScope)||S.containment-u.containment||S.siteCoverage-u.siteCoverage||u.file.localeCompare(S.file)),l.findings.push({helperSymbol:i.symbol,helperShortName:d,helperFile:i.relativePath,helperShape:"specific-callee-cluster",helperCalleeCount:p.size,specificHelperCalleeCount:N,migratedFiles:b.sort(),leftovers:I.slice(0,J)}))}return l.findings.sort((i,p)=>(p.leftovers[0]?.containment??0)-(i.leftovers[0]?.containment??0)||i.helperFile.localeCompare(p.helperFile)),l.findings=l.findings.slice(0,m),l}function K(e){let t=[],a=U(e.helperSymbol,e.helperFile,e.migratedFiles),o=new Set;for(let r of e.helperCallees)for(let n of e.candidateIndex.candidateIndexesByCallee.get(r)??[])o.add(n);for(let r of o){let n=e.candidateIndex.corpus[r];if(n.symbol===e.helperSymbol||e.changed.has(n.file)||n.callees.has(e.helperSymbol))continue;let c=H(e.helperCallees,n.callees);if(c<e.minContainment)continue;let m=[...e.helperCallees].filter(s=>n.callees.has(s)),g=n.callees.size===0?0:m.length/n.callees.size;if(g<e.minSiteCoverage||!m.some(s=>(e.candidateIndex.docFreq.get(s)??0)<=e.candidateIndex.ubiquityThreshold))continue;let f=W(a,n.symbol,n.file);t.push({symbol:n.symbol,shortName:C(n.symbol),file:n.file,...f,containment:c,siteCoverage:g,uniqueSiteCalleeCount:Math.max(0,n.callees.size-m.length),sharedCallees:m.map(C).sort()})}return t}function z(e){return e==="same-scope"?2:e==="unknown"?1:0}function U(e,t,a){let o=new Set([...y(t),...v(F(e))]);for(let r of a)for(let n of y(r))o.add(n);return o}function W(e,t,a){let o=new Set([...y(a),...v(F(t))]);if(e.size===0||o.size===0)return{migrationScope:"unknown",migrationScopeReasons:["insufficient path/name tokens to infer migration scope"]};let r=[...o].filter(n=>e.has(n)).sort();return r.length>0?{migrationScope:"same-scope",migrationScopeReasons:[`shares migration-scope token(s): ${r.slice(0,5).join(", ")}`]}:{migrationScope:"possible-subtype",migrationScopeReasons:["no path/name tokens shared with the helper or already migrated files"]}}var X=new Set(["app","apps","common","component","components","helper","helpers","index","lib","package","packages","page","pages","route","routes","service","services","shared","spec","src","test","tests","util","utils"]);function y(e){return v(e.replace(/\.[^.]+$/,""))}function v(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter(t=>t.length>1&&!X.has(t))}function Y(e,t){let a=0;for(let o of e)(t.docFreq.get(o)??0)<=t.ubiquityThreshold&&(a+=1);return a}function Z(e,t,a,o){return e.productionCallableDefinitions({files:[...t],requireFunctionLikeSymbol:!0}).filter(r=>{if(!t.has(r.relativePath))return!1;let n=a.get(r.relativePath)??r.relativePath,c=o(n);return c===null||!new RegExp(`\\b${w(r.leaf)}\\b`).test(c)})}function Q(e,t){return e.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
+ ${e.pathExclusionsFor("ref_d")}`,t).map(o=>o.relative_path)}export{ae as a};
8
+ //# sourceMappingURL=chunk-6Q6OFLFQ.js.map