scip-query 0.15.0 → 0.16.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 (321) hide show
  1. package/CHANGELOG.md +4 -1
  2. package/README.md +148 -66
  3. package/dist/augment-vue-worker.js +1 -1
  4. package/dist/chunk-2EU6WVR3.js +3 -0
  5. package/dist/chunk-2HFXPIBT.js +2 -0
  6. package/dist/chunk-2LGPMYS2.js +35 -0
  7. package/dist/chunk-2Y7YX54K.js +16 -0
  8. package/dist/chunk-363TZ64I.js +2 -0
  9. package/dist/chunk-3I34FZ6R.js +2 -0
  10. package/dist/chunk-3LAKH6BV.js +2 -0
  11. package/dist/chunk-3M2UCPFS.js +3 -0
  12. package/dist/chunk-3OPIMH42.js +2 -0
  13. package/dist/{chunk-QZOAOLLZ.js → chunk-3YAZH3JU.js} +2 -2
  14. package/dist/chunk-5P26M63Y.js +2 -0
  15. package/dist/{chunk-72FR7KEZ.js → chunk-5TVNLPUM.js} +14 -12
  16. package/dist/chunk-5UKDCXVC.js +5 -0
  17. package/dist/{chunk-R7U2I55B.js → chunk-5XDNFOAH.js} +2 -2
  18. package/dist/chunk-62Y3PC27.js +4 -0
  19. package/dist/chunk-6DNE65QS.js +40 -0
  20. package/dist/{chunk-N2OTJWC2.js → chunk-6EVORGCB.js} +2 -2
  21. package/dist/chunk-6GZ7LM7S.js +2 -0
  22. package/dist/chunk-753JWTUH.js +3 -0
  23. package/dist/chunk-7II7NFRV.js +4 -0
  24. package/dist/{chunk-M7EEHYSU.js → chunk-7RAS466A.js} +2 -2
  25. package/dist/chunk-A46JTKTM.js +5 -0
  26. package/dist/{chunk-2XRXEIRK.js → chunk-AAMZRDJT.js} +2 -2
  27. package/dist/chunk-AMPN2VMF.js +3 -0
  28. package/dist/{chunk-6XA4LDHY.js → chunk-B3X6KU75.js} +2 -2
  29. package/dist/chunk-BFWVHD2P.js +16 -0
  30. package/dist/chunk-BVHP2B4D.js +61 -0
  31. package/dist/{chunk-BUNDZ6K2.js → chunk-BVUA3GZC.js} +2 -2
  32. package/dist/{chunk-EDSD3VJK.js → chunk-CKIAEVGM.js} +2 -2
  33. package/dist/chunk-CM4EZLW4.js +2 -0
  34. package/dist/chunk-CS3FXTUC.js +2 -0
  35. package/dist/chunk-CVBS2FD4.js +2 -0
  36. package/dist/chunk-D5OXYOJP.js +7 -0
  37. package/dist/chunk-DA34GNNO.js +29 -0
  38. package/dist/chunk-DKK2H4D7.js +7 -0
  39. package/dist/chunk-EBSSCVR4.js +5 -0
  40. package/dist/{chunk-OXTM2RX3.js → chunk-EVCSXWER.js} +2 -2
  41. package/dist/chunk-FFIYGYQR.js +67 -0
  42. package/dist/chunk-G4KQ7S74.js +20 -0
  43. package/dist/{chunk-44P4SJFN.js → chunk-GWWYLYD3.js} +2 -2
  44. package/dist/chunk-HGUNWXJX.js +2 -0
  45. package/dist/chunk-HLRWOFXC.js +9 -0
  46. package/dist/{chunk-YQKECTPV.js → chunk-IRIM3SUR.js} +2 -2
  47. package/dist/chunk-JHK2DMUQ.js +4 -0
  48. package/dist/chunk-JQ2PCFZW.js +3 -0
  49. package/dist/chunk-JRFCWCOD.js +16 -0
  50. package/dist/chunk-JXAJDINF.js +2 -0
  51. package/dist/chunk-K32ZOW3P.js +2 -0
  52. package/dist/{chunk-3H5OSDF7.js → chunk-KI4WPR7Q.js} +2 -2
  53. package/dist/{chunk-43GKP6LI.js → chunk-KP2DJY7D.js} +2 -2
  54. package/dist/{chunk-YTVKPJXW.js → chunk-L27UIF3E.js} +2 -2
  55. package/dist/chunk-LT6AHYVY.js +18 -0
  56. package/dist/chunk-MCNWCJYL.js +11 -0
  57. package/dist/{chunk-K6UI6EBZ.js → chunk-MZB3DTHW.js} +2 -2
  58. package/dist/chunk-NLRWGGPY.js +8 -0
  59. package/dist/chunk-NLVKD45E.js +13 -0
  60. package/dist/chunk-OO6S4ECV.js +112 -0
  61. package/dist/{chunk-QYOPMTZ6.js → chunk-OYGKBDAD.js} +2 -2
  62. package/dist/chunk-P5QZILZ4.js +2 -0
  63. package/dist/chunk-P5XHIJHI.js +2 -0
  64. package/dist/chunk-PCCMMI2M.js +3 -0
  65. package/dist/{chunk-2TPCIPYA.js → chunk-Q65QYKU7.js} +2 -2
  66. package/dist/{chunk-K7SPOJHZ.js → chunk-QB7NRST4.js} +2 -2
  67. package/dist/{chunk-7JZRFDCU.js → chunk-QSNG3NHQ.js} +2 -2
  68. package/dist/chunk-QVZSWLLZ.js +2 -0
  69. package/dist/chunk-RLB7FZKR.js +10 -0
  70. package/dist/{chunk-KYB7FPXT.js → chunk-RPMT6MTX.js} +2 -2
  71. package/dist/chunk-RQWNF2RM.js +2 -0
  72. package/dist/chunk-RYFIRFYJ.js +4 -0
  73. package/dist/{chunk-QARYU7R3.js → chunk-S2FZILCF.js} +2 -2
  74. package/dist/{chunk-HV27H2V2.js → chunk-S3IXCXW2.js} +2 -2
  75. package/dist/{chunk-TYCZ7S4I.js → chunk-S5MTSES5.js} +2 -2
  76. package/dist/chunk-S5RZQA6V.js +2 -0
  77. package/dist/{chunk-PEHDARNC.js → chunk-SEEJPIWG.js} +2 -2
  78. package/dist/chunk-SOCS3467.js +2 -0
  79. package/dist/chunk-U6BJVXWQ.js +2 -0
  80. package/dist/chunk-UO4IADXJ.js +38 -0
  81. package/dist/{chunk-ZEO4CXQR.js → chunk-VLSI5MYU.js} +2 -2
  82. package/dist/chunk-VSQRU3AP.js +2 -0
  83. package/dist/chunk-VYQY75NA.js +2 -0
  84. package/dist/{chunk-NOKUZU56.js → chunk-VZCR3VQY.js} +2 -2
  85. package/dist/chunk-W3ZVRLCH.js +2 -0
  86. package/dist/chunk-WA64GKWB.js +20 -0
  87. package/dist/chunk-WFRZGMWJ.js +71 -0
  88. package/dist/chunk-WN6XEYVX.js +2 -0
  89. package/dist/chunk-XAEU4ROB.js +101 -0
  90. package/dist/chunk-XBPAJASV.js +2 -0
  91. package/dist/{chunk-GY3HAWUA.js → chunk-XC6PUFNN.js} +2 -2
  92. package/dist/chunk-Y42DMR6F.js +6 -0
  93. package/dist/chunk-YCVYOV4A.js +7 -0
  94. package/dist/{chunk-WPZPB42I.js → chunk-YD37KSEK.js} +2 -2
  95. package/dist/{chunk-V5W7H7V4.js → chunk-YFEJIYWH.js} +2 -2
  96. package/dist/chunk-YSUD2S7T.js +3 -0
  97. package/dist/{chunk-KJCDEDQW.js → chunk-ZEKBAMCN.js} +2 -2
  98. package/dist/chunk-ZHGUZKJL.js +2 -0
  99. package/dist/cli.js +587 -312
  100. package/dist/{config-types-aCgyLrvE.d.ts → config-types-SVkUIufk.d.ts} +8 -2
  101. package/dist/{db-DwCdT3rv.d.ts → db-CS0TuVH6.d.ts} +1 -1
  102. package/dist/{git-history-Dao3_Pu9.d.ts → git-history-ChNHbfZQ.d.ts} +2 -1
  103. package/dist/{health-nJUidasZ.d.ts → health-Btal3mQi.d.ts} +4 -4
  104. package/dist/index.d.ts +7 -5
  105. package/dist/index.js +1 -19
  106. package/dist/queries/affected.d.ts +2 -2
  107. package/dist/queries/affected.js +1 -1
  108. package/dist/queries/bottlenecks.d.ts +8 -2
  109. package/dist/queries/bottlenecks.js +1 -1
  110. package/dist/queries/by-kind.d.ts +2 -2
  111. package/dist/queries/by-kind.js +1 -1
  112. package/dist/queries/call-graph.d.ts +2 -2
  113. package/dist/queries/call-graph.js +1 -1
  114. package/dist/queries/change-surface.d.ts +2 -2
  115. package/dist/queries/change-surface.js +1 -1
  116. package/dist/queries/cleanup-plan.d.ts +2 -2
  117. package/dist/queries/cleanup-plan.js +1 -1
  118. package/dist/queries/co-change.d.ts +4 -3
  119. package/dist/queries/co-change.js +1 -1
  120. package/dist/queries/code.d.ts +2 -2
  121. package/dist/queries/code.js +1 -1
  122. package/dist/queries/complexity-hotspots.d.ts +3 -3
  123. package/dist/queries/complexity-hotspots.js +1 -1
  124. package/dist/queries/complexity.d.ts +5 -4
  125. package/dist/queries/complexity.js +1 -1
  126. package/dist/queries/convergence.d.ts +2 -2
  127. package/dist/queries/convergence.js +1 -1
  128. package/dist/queries/coupling.d.ts +2 -2
  129. package/dist/queries/coupling.js +1 -1
  130. package/dist/queries/cycles.d.ts +2 -2
  131. package/dist/queries/cycles.js +1 -1
  132. package/dist/queries/dataflow.d.ts +2 -2
  133. package/dist/queries/dataflow.js +1 -1
  134. package/dist/queries/dead.d.ts +12 -3
  135. package/dist/queries/dead.js +1 -1
  136. package/dist/queries/decorative-checkers.d.ts +2 -2
  137. package/dist/queries/decorative-checkers.js +1 -1
  138. package/dist/queries/deep-chains.d.ts +8 -3
  139. package/dist/queries/deep-chains.js +1 -1
  140. package/dist/queries/deps.d.ts +2 -2
  141. package/dist/queries/deps.js +1 -1
  142. package/dist/queries/diff-gate.d.ts +5 -4
  143. package/dist/queries/diff-gate.js +1 -1
  144. package/dist/queries/diff-impact.d.ts +3 -3
  145. package/dist/queries/diff-impact.js +1 -1
  146. package/dist/queries/doc-drift.d.ts +4 -2
  147. package/dist/queries/doc-drift.js +1 -1
  148. package/dist/queries/drift.d.ts +2 -2
  149. package/dist/queries/drift.js +1 -1
  150. package/dist/queries/duplicate-bodies.d.ts +3 -3
  151. package/dist/queries/duplicate-bodies.js +1 -1
  152. package/dist/queries/extract-candidates.d.ts +2 -2
  153. package/dist/queries/extract-candidates.js +1 -1
  154. package/dist/queries/fan.d.ts +11 -5
  155. package/dist/queries/fan.js +1 -1
  156. package/dist/queries/files.d.ts +2 -2
  157. package/dist/queries/health.d.ts +3 -3
  158. package/dist/queries/health.js +1 -1
  159. package/dist/queries/hierarchy.d.ts +2 -2
  160. package/dist/queries/hierarchy.js +1 -1
  161. package/dist/queries/hotspots.d.ts +2 -2
  162. package/dist/queries/hotspots.js +1 -1
  163. package/dist/queries/imports.d.ts +2 -2
  164. package/dist/queries/imports.js +1 -1
  165. package/dist/queries/incomplete-migration.d.ts +3 -3
  166. package/dist/queries/incomplete-migration.js +1 -1
  167. package/dist/queries/index.d.ts +5 -5
  168. package/dist/queries/index.js +1 -1
  169. package/dist/queries/isolated.d.ts +2 -2
  170. package/dist/queries/isolated.js +1 -1
  171. package/dist/queries/locality-candidates.d.ts +2 -2
  172. package/dist/queries/locality-candidates.js +1 -1
  173. package/dist/queries/members.d.ts +2 -2
  174. package/dist/queries/members.js +1 -1
  175. package/dist/queries/methods.d.ts +2 -2
  176. package/dist/queries/methods.js +1 -1
  177. package/dist/queries/not-implemented.d.ts +2 -2
  178. package/dist/queries/not-implemented.js +1 -1
  179. package/dist/queries/outline.d.ts +2 -2
  180. package/dist/queries/outline.js +1 -1
  181. package/dist/queries/passthrough-candidates.d.ts +3 -3
  182. package/dist/queries/passthrough-candidates.js +1 -1
  183. package/dist/queries/plan-context.d.ts +4 -4
  184. package/dist/queries/plan-context.js +1 -1
  185. package/dist/queries/react-component-duplicates.d.ts +4 -2
  186. package/dist/queries/react-component-duplicates.js +1 -1
  187. package/dist/queries/react-hook-candidates.d.ts +4 -2
  188. package/dist/queries/react-hook-candidates.js +1 -1
  189. package/dist/queries/react-large-component-pressure.d.ts +2 -2
  190. package/dist/queries/react-large-component-pressure.js +1 -1
  191. package/dist/queries/recent-duplicates.d.ts +4 -2
  192. package/dist/queries/recent-duplicates.js +1 -1
  193. package/dist/queries/redundant-reexports.d.ts +2 -2
  194. package/dist/queries/redundant-reexports.js +1 -1
  195. package/dist/queries/refs.d.ts +2 -2
  196. package/dist/queries/refs.js +1 -1
  197. package/dist/queries/self-audit.d.ts +2 -2
  198. package/dist/queries/self-audit.js +1 -1
  199. package/dist/queries/similar-chains.d.ts +2 -2
  200. package/dist/queries/similar-chains.js +1 -1
  201. package/dist/queries/similar-files.d.ts +2 -2
  202. package/dist/queries/similar-files.js +1 -1
  203. package/dist/queries/similar-signatures.d.ts +2 -2
  204. package/dist/queries/similar-signatures.js +1 -1
  205. package/dist/queries/similar.d.ts +2 -2
  206. package/dist/queries/similar.js +1 -1
  207. package/dist/queries/slice.d.ts +2 -2
  208. package/dist/queries/slice.js +1 -1
  209. package/dist/queries/stale-abstractions.d.ts +2 -2
  210. package/dist/queries/stale-abstractions.js +1 -1
  211. package/dist/queries/stats.d.ts +2 -2
  212. package/dist/queries/surface.d.ts +2 -2
  213. package/dist/queries/surface.js +1 -1
  214. package/dist/queries/symbols.d.ts +2 -2
  215. package/dist/queries/symbols.js +1 -1
  216. package/dist/queries/system.d.ts +2 -2
  217. package/dist/queries/system.js +1 -1
  218. package/dist/queries/test-quality.d.ts +2 -2
  219. package/dist/queries/test-quality.js +1 -1
  220. package/dist/queries/trace.d.ts +2 -2
  221. package/dist/queries/trace.js +1 -1
  222. package/dist/queries/twin-ab.d.ts +2 -2
  223. package/dist/queries/twin-ab.js +1 -1
  224. package/dist/queries/twin-drift.d.ts +2 -2
  225. package/dist/queries/twin-drift.js +1 -1
  226. package/dist/queries/unused-imports.d.ts +2 -2
  227. package/dist/queries/unused-imports.js +1 -1
  228. package/dist/queries/unused-params.d.ts +2 -2
  229. package/dist/queries/unused-params.js +1 -1
  230. package/dist/queries/vue-component-duplicates.d.ts +4 -2
  231. package/dist/queries/vue-component-duplicates.js +1 -1
  232. package/dist/queries/vue-composable-candidates.d.ts +4 -2
  233. package/dist/queries/vue-composable-candidates.js +1 -1
  234. package/dist/queries/vue-large-view-pressure.d.ts +2 -2
  235. package/dist/queries/vue-large-view-pressure.js +1 -1
  236. package/dist/queries/wrapper-candidates.d.ts +2 -2
  237. package/dist/queries/wrapper-candidates.js +1 -1
  238. package/dist/reindex-worker.js +256 -12
  239. package/dist/reindex.d.ts +29 -3
  240. package/dist/reindex.js +251 -22
  241. package/dist/runtime.d.ts +8 -4
  242. package/dist/runtime.js +2 -2
  243. package/dist/rust-semantic-session-server.js +2 -0
  244. package/dist/rust-semantic-session-worker.js +2 -0
  245. package/dist/rust-semantic-worker.js +2 -0
  246. package/dist/{scip-cli-DeAbuJ2b.d.ts → scip-cli-BKL-26TZ.d.ts} +2 -2
  247. package/dist/{symbol-types-DaoeXKUt.d.ts → symbol-types-BgWU6lhL.d.ts} +2 -0
  248. package/dist/watch-server.js +42 -0
  249. package/docs/AGENT_GUIDE.md +110 -34
  250. package/docs/AI_FAILURE_MODES.md +8 -3
  251. package/docs/COMMAND_REFERENCE.md +10 -6
  252. package/docs/REGEX_POLICY.md +3 -1
  253. package/docs/accuracy-audit-checklist.md +300 -0
  254. package/docs/accuracy-hardening-goal.md +493 -54
  255. package/docs/analyzer-inventory.md +31 -23
  256. package/docs/analyzer-validation-ledger.md +51 -21
  257. package/package.json +2 -1
  258. package/scripts/build-scip-windows.mjs +7 -7
  259. package/skills/_shared/SKILL.md +20 -19
  260. package/skills/scip-calibrate/SKILL.md +4 -2
  261. package/skills/scip-hyper-optimization/SKILL.md +5 -1
  262. package/skills/scip-query/SKILL.md +1 -1
  263. package/skills/scip-setup/SKILL.md +104 -4
  264. package/skills/scip-verify/SKILL.md +20 -14
  265. package/dist/chunk-27HMTUJE.js +0 -3
  266. package/dist/chunk-27XEGMCT.js +0 -7
  267. package/dist/chunk-3AMWF6V5.js +0 -3
  268. package/dist/chunk-4SCMYKD6.js +0 -2
  269. package/dist/chunk-5AAAEZ2Z.js +0 -2
  270. package/dist/chunk-5JRMZMLM.js +0 -2
  271. package/dist/chunk-5VY3RIEI.js +0 -38
  272. package/dist/chunk-6JUAGXR4.js +0 -4
  273. package/dist/chunk-6KDOYKCB.js +0 -40
  274. package/dist/chunk-6KMTPNZL.js +0 -3
  275. package/dist/chunk-7COVQPQQ.js +0 -9
  276. package/dist/chunk-7S5E7KWT.js +0 -2
  277. package/dist/chunk-7TVFPOD7.js +0 -102
  278. package/dist/chunk-A6KSEIRN.js +0 -61
  279. package/dist/chunk-AAMURYOK.js +0 -4
  280. package/dist/chunk-BP7S6V3M.js +0 -20
  281. package/dist/chunk-BRBF3E5X.js +0 -35
  282. package/dist/chunk-BZXE3HO4.js +0 -6
  283. package/dist/chunk-CXQQOXSI.js +0 -10
  284. package/dist/chunk-EVZSAR3S.js +0 -2
  285. package/dist/chunk-GMOEX7EV.js +0 -2
  286. package/dist/chunk-GNG622H3.js +0 -3
  287. package/dist/chunk-GUDKRIGW.js +0 -7
  288. package/dist/chunk-GULVO6NF.js +0 -43
  289. package/dist/chunk-HZZQKNVE.js +0 -2
  290. package/dist/chunk-I4R3SNMR.js +0 -2
  291. package/dist/chunk-IMQFJ53K.js +0 -2
  292. package/dist/chunk-ISLWJ4PY.js +0 -10
  293. package/dist/chunk-IUSSGHJO.js +0 -2
  294. package/dist/chunk-J5WVNZ6O.js +0 -2
  295. package/dist/chunk-JJUX2OAP.js +0 -2
  296. package/dist/chunk-JZBGTSAB.js +0 -13
  297. package/dist/chunk-K5N5RNGM.js +0 -2
  298. package/dist/chunk-KSJ544IV.js +0 -5
  299. package/dist/chunk-LY7NMOBW.js +0 -2
  300. package/dist/chunk-N23FT4EZ.js +0 -2
  301. package/dist/chunk-NCVFKOLB.js +0 -2
  302. package/dist/chunk-PESEPWZO.js +0 -2
  303. package/dist/chunk-PMY4UFGV.js +0 -2
  304. package/dist/chunk-Q7PWDXL5.js +0 -5
  305. package/dist/chunk-QVGFVRKD.js +0 -2
  306. package/dist/chunk-R5336VHZ.js +0 -2
  307. package/dist/chunk-RLB6SG25.js +0 -2
  308. package/dist/chunk-SFDVBARK.js +0 -2
  309. package/dist/chunk-TG7QSYCJ.js +0 -2
  310. package/dist/chunk-UHPWZCYQ.js +0 -3
  311. package/dist/chunk-URSSPS5H.js +0 -2
  312. package/dist/chunk-WIBFXSYB.js +0 -6
  313. package/dist/chunk-WMO2VZZK.js +0 -3
  314. package/dist/chunk-WS3Z6W3M.js +0 -65
  315. package/dist/chunk-X3DTIEMU.js +0 -18
  316. package/dist/chunk-X5C43YVI.js +0 -2
  317. package/dist/chunk-X7CHWTZ2.js +0 -72
  318. package/dist/chunk-XDESMVOL.js +0 -4
  319. package/dist/chunk-XZBLZHXL.js +0 -16
  320. package/dist/chunk-YBGC7HTY.js +0 -3
  321. package/dist/chunk-ZMGBWSFZ.js +0 -2
package/CHANGELOG.md CHANGED
@@ -10,8 +10,11 @@ All notable changes to `scip-query` are documented here. This file starts at 0.1
10
10
 
11
11
  ### Notable (new capabilities)
12
12
 
13
+ - **`setup` now completes automatic-indexing installation instead of only describing it.** A project with no prior watch decision gets `watch.enabled: true`; an existing explicit `false` remains an opt-out, and `setup --guided` presents enablement as a recommended consent choice. Setup starts or reuses the project service after reindexing, verifies its published clean-idle deadline, and reports Rust's final durable/worker transport, lifecycle state, and fallback after the health audit. The status read itself is passive; semantic health work may legitimately wake rust-analyzer. `init` now writes the same enabled demand-started default.
13
14
  - **Committed outcome-event ledger.** Hook-mode `diff-gate` runs now mirror finding transitions (caught / resolved / suppressed / reopened) into `.scipquery/ledger/events.jsonl` — an append-only, one-event-per-line log stamped with the HEAD commit and, when known, the finding's SCIP symbol. A scoped `.gitattributes` (`merge=union`) is written alongside it, so concurrent appends from different branches merge without conflict; read-side dedupe by `(check, findingId, event, commit)` absorbs replays. Unlike the per-machine `evidence.db` ledger, this file is meant to be committed: outcome history survives re-clones and aggregates across every machine and agent working the repo. Ledger writes never block the hook — failures degrade to a stderr note.
14
15
  - **New command: `effectiveness`.** Reads the committed event ledger and reports, per diff-gate check: findings caught, fixed by code changes (disappeared without a suppression), suppressed, still open, reopened, `moved` (rename noise — a resolved id whose symbol was re-caught under a new id at the same commit), precision (fixed ÷ concluded), and median days-to-fix. `--since 30d|12w|<ISO date>` windows by when the finding was caught, `--check <name>` filters, `--json` emits the standard envelope. This is the tool keeping score on itself: suppressions count against a detector's precision, fixes count for it.
16
+ - **Setup now reports and enforces ownership scopes.** Guided actions and setup results identify repository records to commit, checkout preferences to keep local, and user-environment changes. Project hooks always target `.codex/hooks.json` and `.claude/settings.local.json`, are excluded through `.git/info/exclude`, and refuse to alter an already tracked target. `--shared` remains accepted as a deprecated compatibility flag but no longer writes tracked Claude settings. Guided indexer consent now controls the installer, and the decorative parser-runtime question was removed.
17
+ - **Installed Stop hooks now update effectiveness history.** The normal `hook-stop` path shares the same caught/resolved/suppressed/reopened recorder as legacy `diff-gate --hook`, including clean runs that resolve earlier findings. Generated agent guidance requires committing suppression and outcome records while forbidding commits of checkout hook files; project uninstall names those shared records as intentionally preserved.
15
18
 
16
19
  ### Breaking (behavior change for one config key)
17
20
 
@@ -26,7 +29,7 @@ All notable changes to `scip-query` are documented here. This file starts at 0.1
26
29
  ### Breaking (one-way doors — read before upgrading)
27
30
 
28
31
  - **`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.
29
- - **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.
32
+ - **Project hooks are checkout-local.** `scip-query setup` (and `setup-hooks`) write Codex and Claude Code hooks to `.codex/hooks.json` and `.claude/settings.local.json`, exclude both through `.git/info/exclude`, and will not mutate a path Git already tracks. A teammate's agent tooling preferences therefore do not land in Git. The old `setup-hooks --shared` input is deprecated and now has the same local behavior. `setup-hooks --remove` writes an ignored decline tombstone so a later `setup` won't silently re-add hooks you removed; `--force` overrides it.
30
33
  - **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.
31
34
  - **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.
32
35
  - **`convergence` is deprecated.** Use `similar <symbol1> <symbol2> --plan` instead. `convergence` still works (as a thin alias) but is not the documented path going forward.
package/README.md CHANGED
@@ -20,11 +20,11 @@
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` 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.
23
+ Coding agents operate at too concrete a level of abstraction. They work in files and grep, while every decision that actually matters — does a helper for this already exist, what depends on the thing I'm about to change, is this migration finished or just started — lives one level up, in symbols, references, and history. `scip-query` raises agents to that level: 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
- 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.
25
+ The failure mode it targets is specific. Agents are genuinely good at editing the code in front of them; what they lose is the whole-repository model across a long task. They re-implement helpers they never saw, plan from partial context, migrate three call sites and abandon the other two, miss the file that always changes with the one they touched, and declare a diff finished while it quietly adds duplication, dead code, and docs that now lie. None of that is a syntax error, so nothing stops it — it just accumulates until complexity nukes your development momentum.
26
26
 
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.
27
+ So the loop this tool enforces is evidence at every step: map the target and its blast radius, plan from repository facts, check for reuse before adding a concept, detect unfinished migrations and hidden coupling, and gate the finished diff. It does not replace the compiler, tests, or review. The point is to make structural evidence so cheap to ask for that agents actually ask and to make "done" something the repository gets a vote on.
28
28
 
29
29
  ## How Agents Use It
30
30
 
@@ -34,14 +34,14 @@ Two layers, wired by `scip-query setup`:
34
34
 
35
35
  **Invoked** — the agent routes work through skills, each carrying its own short command list so it never navigates the full CLI:
36
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` |
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
45
 
46
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.
47
47
 
@@ -53,12 +53,21 @@ React and Vue repositories get additional framework-aware checks for repeated co
53
53
 
54
54
  ```bash
55
55
  npm install -g scip-query@latest
56
- scip-query setup # opt-in: skills, project hooks, first index, health dossier
57
- scip-query check-deps
58
- scip-query reindex
56
+ scip-query setup # interactive checklist in a terminal
59
57
  ```
60
58
 
61
- Or without a global install: `npx scip-query@latest reindex`.
59
+ The setup checklist detects the repository's languages and offers to install or
60
+ repair the matching SCIP indexers, Tree-sitter AST parsers, agent skills, and
61
+ checkout-local hooks. It enables demand-started automatic incremental indexing,
62
+ builds the first index, verifies semantic and checker capabilities, and can run
63
+ the optional full health audit. Use the arrow keys and Space to change the
64
+ selection, then Enter to continue.
65
+
66
+ For automation, use `scip-query setup --yes` to accept recommended defaults or
67
+ `scip-query setup --json` for a non-interactive machine-readable report. Use
68
+ `--no-hooks`, `--no-skills`, `--no-parsers`, or `--no-health` only when that
69
+ scope is intentionally managed elsewhere. Or run without a global install:
70
+ `npx scip-query@latest setup`.
62
71
 
63
72
  ### If npm warns about install scripts
64
73
 
@@ -70,7 +79,7 @@ which leaves the native modules unbuilt. Every script on that list is expected:
70
79
  - `better-sqlite3` — builds/downloads the native SQLite binding that backs the index
71
80
  - `tree-sitter` + the per-language grammars — native parsers behind multi-language source facts
72
81
 
73
- Approve them and re-run the builds (`--allow-scripts-pending` only *lists* — the approving forms
82
+ Approve them and re-run the builds (`--allow-scripts-pending` only _lists_ — the approving forms
74
83
  are `npm approve-scripts <pkg> ...` or `--all`):
75
84
 
76
85
  ```bash
@@ -110,7 +119,7 @@ scip-query health --write-baseline
110
119
 
111
120
  ## Evidence and Confidence
112
121
 
113
- `scip-query` keeps the source and strength of each answer visible:
122
+ A claim you can't trace to evidence is a vibe. `scip-query` labels every answer with where it came from and how much weight it deserves:
114
123
 
115
124
  ```mermaid
116
125
  flowchart LR
@@ -127,17 +136,24 @@ flowchart LR
127
136
  4. **Git-history signals** for churn, co-change, recency, and documentation drift.
128
137
  5. **Repository-toolchain verification** for supported cleanup plans.
129
138
 
130
- Heuristic findings are candidates for inspection, not proof of equivalence or bad design. Run `scip-query capabilities` to see which evidence and verification layers are available for the current repository and language.
139
+ Heuristic findings are candidates for inspection, not verdicts the finding always sounds right, because it was generated to; only the code knows. Run `scip-query capabilities` to see which evidence and verification layers are available for the current repository and language.
131
140
 
132
141
  ## Language and Framework Coverage
133
142
 
134
143
  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.
135
144
 
145
+ Rust projects are indexed through rust-analyzer's SCIP output. Compiler-backed
146
+ Rust reference, callee, signature, and module/use evidence runs through a
147
+ demand-started durable rust-analyzer session with bounded worker fallback.
148
+ Capability and status output distinguish indexer readiness, semantic readiness,
149
+ the selected transport, and whether the idle helper is currently stopped or
150
+ live.
151
+
136
152
  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.
137
153
 
138
154
  ## Cleaning Up AI-Generated Code
139
155
 
140
- 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):
156
+ Every check here exists because I watched the failure mode happen — in AI-generated codebases I inherited and rebuilt, and in my own agent sessions. AI-assisted development doesn't rot a codebase in general; it rots it in specific, recurring shapes, and each shape gets its own detector. The full catalog, with prevention wiring for each one, is in [docs/AI_FAILURE_MODES.md](docs/AI_FAILURE_MODES.md):
141
157
 
142
158
  **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.
143
159
 
@@ -226,19 +242,19 @@ scip-query suppress SQABC123DEF456 --check echo --reason "intentional compatibil
226
242
 
227
243
  This writes one file per suppression under `.scipquery/suppressions/` — commit it with your change. One-file-per-suppression means two branches suppressing different findings merge without conflict; the legacy `suppressions[]` array in `.scipquery.json` is still honored (read-only). Every suppression requires a reason plus either a stable finding id or a `check` (optionally narrowed by `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.
228
244
 
229
- **12. Measure whether the gate is earning its keep.** Every hook-mode `diff-gate` run appends finding transitions to a committed, merge-conflict-free ledger (`.scipquery/ledger/events.jsonl`, one JSON event per line under a scoped `merge=union` gitattribute). A finding that disappears without a suppression was fixed; a suppressed finding was noise or an accepted trade-off — the tool keeps score on itself:
245
+ **12. Measure whether the gate is earning its keep.** Every completed `diff-gate` run, including JSON and installed Stop-hook runs, appends finding transitions to a committed, merge-conflict-free ledger (`.scipquery/ledger/events.jsonl`, one JSON event per line under a scoped `merge=union` gitattribute). A finding that disappears on a later run against the same non-null HEAD is a verified fix. If HEAD changed or Git evidence is unavailable, the disappearance is reported as `unverified` rather than credited as a fix. A suppressed finding was noise or an accepted trade-off:
230
246
 
231
247
  ```bash
232
248
  scip-query effectiveness --since 30d
233
249
  ```
234
250
 
235
251
  ```
236
- check caught fixed suppressed open moved precision median-days-to-fix
237
- echo 14 11 2 1 0 85% 0.8
238
- new-dead 6 5 0 1 0 100% 0.3
252
+ check caught fixed suppressed open moved unverified precision median-days-to-fix
253
+ echo 14 10 2 1 0 1 83% 0.8
254
+ new-dead 6 5 0 1 0 0 100% 0.3
239
255
  ```
240
256
 
241
- `precision` is fixed ÷ (fixed + suppressed) how often acting on the check was the right call. `moved` separates rename churn from real fixes. Filter with `--check <name>`, window with `--since 30d|12w|<ISO date>`, and get machine-readable output with `--json`. Because the ledger is committed, the numbers survive re-clones and aggregate across every machine and agent working the repo.
257
+ `precision` is verified fixed ÷ (verified fixed + suppressed). `moved` separates rename churn, while `unverified` prevents a commit or missing Git identity from masquerading as a confirmed repair. Run diff-gate once to record the finding and again after the repair, before committing, to earn same-HEAD verification. Filter with `--check <name>`, window with `--since 30d|12w|<ISO date>`, and get machine-readable output with `--json`. Because the ledger is committed, the numbers survive re-clones and aggregate across every machine and agent working the repo. Standalone health/cleanup commands are not yet outcome-tracked because they do not all expose a complete-scan contract.
242
258
 
243
259
  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").
244
260
 
@@ -295,40 +311,66 @@ Heuristic detectors carry guardrails learned from real codebases: published `pac
295
311
 
296
312
  One-line "essential difference" per skill — read this table before the Routes table in `skills/scip-query/SKILL.md` if two names sound alike.
297
313
 
298
- | Skill | Essential difference |
299
- | --- | --- |
300
- | `scip-query` | Router: dispatches codebase work to the specialist skill below. |
301
- | `scip-explore` | Understand before touching. |
302
- | `scip-concrete-plan` | Specify ONE change so an executor can't guess. |
303
- | `scip-conductor` | Run a multi-phase program (delegate, verify handoffs, pre-registered benchmarks). |
304
- | `scip-debug` | Root-cause a failure. |
305
- | `scip-triage-issue` | Package a report into an actionable issue+fix plan. |
306
- | `scip-verify` | Post-change closeout gate. |
307
- | `scip-cleanup-audit` | Rank findings, no edits. |
308
- | `scip-cleanup-improve` | Autonomously fix confirmed findings. |
309
- | `scip-maintainability` | Is this well-organized (scattered concepts, accidental variation)? |
310
- | `scip-integrity-audit` | Is this real (decorative checkers, faked implementations, dead fallback-hidden paths)? |
311
- | `scip-calibrate` | Measure detector precision on a repo before trusting scores or gating anyone. |
312
- | `scip-twin-drift` | Same-name implementations that drifted apart. |
313
- | `scip-claim-audit` | Status words derived vs asserted. |
314
- | `scip-probe-reachability` | Prove parser/AST branches actually fire. |
315
- | `scip-api-impact` | Blast radius before changing public surfaces. |
316
- | `scip-directory-architecture` | Folder/ownership layout. |
317
- | `scip-doc-reconcile` | Docs vs code drift. |
318
- | `scip-diagram` | Visual artifacts. |
319
- | `scip-react-maintainability` | Framework-specific reuse lens (React). |
320
- | `scip-vue-maintainability` | Framework-specific reuse lens (Vue). |
321
- | `scip-language-playbook` | Which commands per language. |
322
- | `scip-hyper-optimization` | Performance campaigns without output changes. |
323
- | `scip-tla-model-system` | Formal models tied to code evidence. |
324
- | `scip-setup` | Adopt or repair scip-query in a repo. |
325
- | `_shared` | Reference loaded by other skills, not user-invoked. |
314
+ | Skill | Essential difference |
315
+ | ----------------------------- | -------------------------------------------------------------------------------------- |
316
+ | `scip-query` | Router: dispatches codebase work to the specialist skill below. |
317
+ | `scip-explore` | Understand before touching. |
318
+ | `scip-concrete-plan` | Specify ONE change so an executor can't guess. |
319
+ | `scip-conductor` | Run a multi-phase program (delegate, verify handoffs, pre-registered benchmarks). |
320
+ | `scip-debug` | Root-cause a failure. |
321
+ | `scip-triage-issue` | Package a report into an actionable issue+fix plan. |
322
+ | `scip-verify` | Post-change closeout gate. |
323
+ | `scip-cleanup-audit` | Rank findings, no edits. |
324
+ | `scip-cleanup-improve` | Autonomously fix confirmed findings. |
325
+ | `scip-maintainability` | Is this well-organized (scattered concepts, accidental variation)? |
326
+ | `scip-integrity-audit` | Is this real (decorative checkers, faked implementations, dead fallback-hidden paths)? |
327
+ | `scip-calibrate` | Measure detector precision on a repo before trusting scores or gating anyone. |
328
+ | `scip-twin-drift` | Same-name implementations that drifted apart. |
329
+ | `scip-claim-audit` | Status words derived vs asserted. |
330
+ | `scip-probe-reachability` | Prove parser/AST branches actually fire. |
331
+ | `scip-api-impact` | Blast radius before changing public surfaces. |
332
+ | `scip-directory-architecture` | Folder/ownership layout. |
333
+ | `scip-doc-reconcile` | Docs vs code drift. |
334
+ | `scip-diagram` | Visual artifacts. |
335
+ | `scip-react-maintainability` | Framework-specific reuse lens (React). |
336
+ | `scip-vue-maintainability` | Framework-specific reuse lens (Vue). |
337
+ | `scip-language-playbook` | Which commands per language. |
338
+ | `scip-hyper-optimization` | Performance campaigns without output changes. |
339
+ | `scip-tla-model-system` | Formal models tied to code evidence. |
340
+ | `scip-setup` | Adopt or repair scip-query in a repo. |
341
+ | `_shared` | Reference loaded by other skills, not user-invoked. |
326
342
 
327
343
  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.
328
344
 
329
- 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.
330
-
331
- 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.
345
+ Project setup writes reviewable checkout-local lifecycle hooks for Codex and Claude Code (`.codex/hooks.json` and `.claude/settings.local.json`). A checkout-local hook is an agent-tool preference whose defining trait is that it applies to one clone rather than expressing team policy. Setup adds both paths to that clone's `.git/info/exclude`, so they do not appear in commits, and refuses to rewrite either path if it is already tracked. `setup-hooks --shared` remains accepted only as a deprecated compatibility flag; it no longer writes `.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 checkout's hooks.
346
+
347
+ For a project, run `scip-query setup`. It enables demand-started automatic
348
+ indexing unless the project already has an explicit `watch.enabled: false`,
349
+ starts or reuses the project service, verifies its clean-idle deadline, and
350
+ reports Rust's final durable/worker semantic selection and lifecycle state.
351
+ The status read is passive; the setup health audit may make a semantic request
352
+ that wakes rust-analyzer, after which the helper exits on clean idle.
353
+ It also installs/refreshes skills, configures project-local hooks unless
354
+ skipped, checks indexer readiness, attempts configured indexer remediation,
355
+ refreshes the index, smoke-tests representative command families, writes
356
+ `docs/scip-query/health-dossier.md` and `.json` when the optional health pass is
357
+ selected, reports the health score and items needing attention, and seeds
358
+ AGENTS.md/CLAUDE.md guidance. Use
359
+ the default terminal checklist to accept or decline the recommended automatic
360
+ indexing action and other project-local changes (`--guided` reopens it
361
+ explicitly). After setup,
362
+ `scip-cleanup-audit` confirms raw signals and `scip-cleanup-improve` keeps
363
+ fixing the worst confirmed items until no safe confirmed cleanup remains. Use
364
+ `scip-query setup --git-hook` when you also want a local pre-commit diff gate.
365
+ CI setup is intentionally separate.
366
+
367
+ Setup classifies every change by where its facts belong:
368
+
369
+ - **Repository records (commit):** shared project policy and history whose value comes from surviving clones and branches, including `.scipquery.json`, AGENTS/CLAUDE guidance, health dossiers, `.scipquery/suppressions/*.json`, and `.scipquery/ledger/`.
370
+ - **Checkout preferences (do not commit):** integration settings for one clone, including `.codex/hooks.json`, `.claude/settings.local.json`, `.git/info/exclude`, and an optional `.git/hooks/pre-commit` backstop.
371
+ - **User environment:** installed skills and language indexers used across checkouts on that machine.
372
+
373
+ Rebuildable indexes, caches, and service state are runtime state: generated working data whose defining trait is that source plus configuration can reproduce it. They remain outside the repository by default. `setup --guided` labels each question with its scope, and both human and JSON setup reports return the resulting scope buckets.
332
374
 
333
375
  ## Formal Models (TLA+)
334
376
 
@@ -347,7 +389,8 @@ scip-query tla fetch-tools # download the pinned tla2t
347
389
  ## Quick Start
348
390
 
349
391
  ```bash
350
- scip-query setup --json # bootstrap local skills, index, capabilities, guidance, and health dossier
392
+ scip-query setup # interactive: languages, indexers, parsers, hooks, indexing, capabilities
393
+ scip-query status --capabilities
351
394
 
352
395
  scip-query stats
353
396
  scip-query system src/auth
@@ -394,9 +437,23 @@ Vue single-file components are handled through the JavaScript/TypeScript indexer
394
437
 
395
438
  By default, indexes live in `~/.cache/scip-query/projects/<hash>/`, keeping project directories clean. Override paths with `.scipquery.json` or `SCIP_QUERY_*` environment variables. Reindexing writes per-language SCIP shards next to the SQLite index, so a mixed-language repo can reuse unchanged language outputs and rerun only the languages whose source/config inputs changed.
396
439
 
440
+ Each rebuilt generation also records an affected-set shadow beside the index:
441
+ the files a future incremental writer would recompute, the normalized
442
+ documents/facts that the authoritative full rebuild actually changed, recall,
443
+ and any conservative fallback reason. `scip-query status` shows a compact
444
+ summary and telemetry path; `status --json` exposes the structured
445
+ `affectedSetShadow` object. Shadow results are observational in this phase and
446
+ never decide which indexer runs or which generation publishes.
447
+
397
448
  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. When `projects` is set to a non-empty list, it is authoritative: only the listed projects are indexed, automatic discovery does not run, and the repo root is not re-added alongside them (even if the root tsconfig covers subdirectories) — files that are only covered by an excluded root tsconfig (e.g. shared ambient `.d.ts` files) drop out of the index, so pick the list deliberately. An empty or absent `projects` falls back to full discovery, unchanged. Workspace mode also caches each project shard: reindexing after an edit reruns only the changed projects and their dependents (workspace `package.json` dependencies and tsconfig `paths`/`references` targets count as dependencies), serves untouched projects from `language-indexes/typescript-projects/`, and reports every reuse decision in `reindex --json` shard diagnostics. Set `indexerConcurrency` when a repo needs a persistent worker cap; CLI `--indexer-concurrency` and `SCIP_QUERY_INDEXER_CONCURRENCY` still override ad hoc runs.
398
449
  Use `indexer.typescript.pnpmWorkspaces` only with the default single-project mode; workspace mode passes explicit projects instead.
399
450
 
451
+ Do not enable workspace mode merely because a repository uses TypeScript. Use
452
+ it when the repository has multiple real tsconfig/project boundaries and the
453
+ setup/readiness evidence confirms them. Single-project repositories already
454
+ reuse unchanged TypeScript documents and keep a persistent ts-morph Project in
455
+ the demand-started service.
456
+
400
457
  Clojure projects can pass a project-local `scip-clojure` config file through `.scipquery.json`:
401
458
 
402
459
  ```json
@@ -430,10 +487,11 @@ It creates a minimal `.scipquery.json`:
430
487
  {
431
488
  "languages": ["typescript"],
432
489
  "watch": {
433
- "enabled": false,
434
- "debounceMs": 30000,
435
- "cooldownMs": 60000,
490
+ "enabled": true,
491
+ "debounceMs": 250,
492
+ "cooldownMs": 0,
436
493
  "gitPollMs": 2000,
494
+ "idleTimeoutMs": 600000,
437
495
  "autoRefresh": true
438
496
  }
439
497
  }
@@ -442,7 +500,31 @@ It creates a minimal `.scipquery.json`:
442
500
  Add optional fields such as `indexerConcurrency`, `indexer`, `entryRoots`,
443
501
  `declaredCouplings`, and `suppressions` only when the project needs them.
444
502
 
445
- `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.
503
+ `scip-query init` and a first `scip-query setup` enable this lifecycle. An
504
+ existing explicit `watch.enabled: false` remains an opt-out unless guided setup
505
+ selects the recommended enable action. With `watch.enabled`, normal commands
506
+ and agent hooks wake one per-project
507
+ background service. Relevant file/Git activity keeps it alive; it exits after
508
+ `idleTimeoutMs` of clean inactivity and wakes on the next command. Set the idle
509
+ timeout to `0` to keep it running. `scip-query watch` still provides foreground
510
+ mode, while `watch --daemon`, `watch --status`, and `watch --stop` expose the
511
+ background lifecycle. Both modes share one project lock, so only one can own an
512
+ index cache.
513
+
514
+ The same demand-started service lazily owns TypeScript compiler Projects after
515
+ the first command that needs ts-morph semantics. Separate CLI processes reuse
516
+ that session through a repository-local atomic mailbox; source-only index
517
+ generations refresh the existing Projects, while configuration or uncertain
518
+ changes replace them. `watch --status` reports Project/session/request counts.
519
+ If the service is stopped, incompatible, busy beyond its bound, or returns an
520
+ invalid response, the command falls back to the existing in-process ts-morph
521
+ provider.
522
+
523
+ Rust semantic requests use a separate demand-started durable rust-analyzer
524
+ session by default. It remains stopped until a Rust semantic request needs it,
525
+ exits after its clean idle period, and automatically falls back to the
526
+ per-command worker on helper/readiness/timeout/request failure. Set
527
+ `SCIP_RUST_SEMANTIC_DURABLE_SESSION=0` for an explicit worker-only opt-out.
446
528
 
447
529
  Use `declaredCouplings` for files that intentionally form one maintenance unit.
448
530
  These pairs are treated as structurally linked by `co-change` and health, while
@@ -473,12 +555,12 @@ dead and isolated cleanup detectors.
473
555
 
474
556
  Useful environment variables:
475
557
 
476
- | Variable | Purpose |
477
- | ------------------------- | --------------------------------------------------------------------- |
478
- | `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory |
479
- | `SCIP_QUERY_INDEX_DB` | Override the SQLite database path |
480
- | `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path |
481
- | `SCIP_QUERY_CACHE_DIR` | Override the cache directory |
558
+ | Variable | Purpose |
559
+ | ------------------------- | ---------------------------------------------------------------------- |
560
+ | `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory |
561
+ | `SCIP_QUERY_INDEX_DB` | Override the SQLite database path |
562
+ | `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path |
563
+ | `SCIP_QUERY_CACHE_DIR` | Override the cache directory |
482
564
  | `SCIP_QUERY_SCIP_BIN` | Path to a local `scip` binary (overrides PATH and the Windows sidecar) |
483
565
 
484
566
  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.
@@ -1,2 +1,2 @@
1
- import{e as t}from"./chunk-X7CHWTZ2.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{c as t}from"./chunk-JRFCWCOD.js";import"./chunk-FFIYGYQR.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,3 @@
1
+ import{a as S}from"./chunk-S2FZILCF.js";import{a as y}from"./chunk-MZB3DTHW.js";import{a as P}from"./chunk-B75HZHUP.js";import{a as x}from"./chunk-3I34FZ6R.js";import{a as h,g as b}from"./chunk-NLRWGGPY.js";import{a as v}from"./chunk-BGBBVSH4.js";import{d as l,e as p,h as d}from"./chunk-OO6S4ECV.js";import{a as u,h as m,i as g}from"./chunk-NLVKD45E.js";import{z as f}from"./chunk-WFRZGMWJ.js";import{basename as L,extname as D}from"path";function K(n,e){let{scope:i,maxLoc:t=15,limit:r=30,scanLimit:a}=e??{},s=new x(n);return y({candidates:()=>A(n,s,i,t),orderCandidates:P,scanLimit:a,profile:{name:"passthrough-candidates"},prepare:o=>s.calleeMap(o,{semantic:e?.semantic!==!1}),evaluate:(o,c)=>w(n,o,c.get(o.symbolId)??[]),orderResults:(o,c)=>o.loc-c.loc||o.file.localeCompare(c.file),limit:r})}function w(n,e,i){let t=j(i);if(t.size!==1||!m(n,e.relativePath,e.startLine,e.endLine))return null;let[,r]=[...t.entries()][0],a=I(n,e,r),s=T(n,e),o=a.length>0||s.length>0?"signal":"direct";return{symbol:e.symbol,shortName:l(e.symbol),file:e.relativePath,startLine:e.startLine,endLine:e.endLine,loc:v(e),forwardsTo:r.symbol,forwardsToShort:l(r.symbol),forwardsToFile:r.file,actionTier:o,boundaryEvidence:a,publicFacadeEvidence:s,recommendation:E(o,a,s)}}function I(n,e,i){return S(n,e.relativePath,e.startLine,"passthrough","explicit ignore-passthrough comment",[{label:"passthrough name",value:l(e.symbol)},{label:"callee name",value:l(i.symbol)},{label:"passthrough module",value:L(e.relativePath,D(e.relativePath))},{label:"callee module",value:L(i.file,D(i.file))}])}function E(n,e,i){if(n==="signal"){if(i.length>0)return`Review the public API before inlining; public-facade evidence: ${i.slice(0,2).join("; ")}.`;let t=e.filter(F);return t.length>0?`Review the public API before inlining; public-surface evidence: ${t.slice(0,2).join("; ")}.`:`Review the boundary before inlining; boundary evidence: ${e.slice(0,2).join("; ")}.`}return"Inline or remove this passthrough unless an external API or runtime registration depends on the forwarding name."}function T(n,e){return C(n,e)?h(n,e.relativePath)?["exported passthrough is declared on the package public surface"]:b(n,e.symbol,e.relativePath)?["exported passthrough matches configured or framework public entry surface"]:[]:[]}function C(n,e){let i=f(n,e.relativePath);if(i.length===0)return!1;let t=p(e.symbol);if(!t)return!1;let r=i.slice(Math.max(0,e.startLine-2),e.startLine+1).join(`
2
+ `),a=u(t);return new RegExp(`^\\s*export\\s+(?:default\\s+)?(?:(?:async\\s+)?function\\s+${a}\\b|(?:const|let|var)\\s+${a}\\b)`,"m").test(r)?!0:R(i,t)}function R(n,e){if(!e)return!1;let i=new RegExp(`^\\s*export\\s*\\{[^}\\n]*\\b${u(e)}\\b`);return n.some(t=>i.test(t))}function F(n){return n.includes("public surface")}function j(n){let e=n.some(t=>d(t.symbol))?n.filter(t=>d(t.symbol)):n,i=new Map;for(let t of e)i.has(t.symbol)||i.set(t.symbol,t);return i}function A(n,e,i,t){return e.productionCallableDefinitions({scope:i,minLoc:3,maxLoc:t,requireFunctionLikeSymbol:!0,excludeRustTraitImplMembers:!0}).filter(r=>!g(n,r))}export{K as a,C as b};
3
+ //# sourceMappingURL=chunk-2EU6WVR3.js.map
@@ -0,0 +1,2 @@
1
+ import{E as s}from"./chunk-MCNWCJYL.js";var p=new Set(["componentDidCatch","componentDidMount","componentDidUpdate","componentWillUnmount","getDerivedStateFromError","getDerivedStateFromProps","getSnapshotBeforeUpdate","render","shouldComponentUpdate","UNSAFE_componentWillMount","UNSAFE_componentWillReceiveProps","UNSAFE_componentWillUpdate"]);function l(i,t){if(!t.parentTypeName||!/\.[cm]?[jt]sx?$/.test(t.relativePath))return!1;let r=s(i,t.relativePath);if(!r)return!1;let n=r.rootNode.descendantsOfType("method_definition").find(a=>a.startPosition.row<=t.startLine&&a.endPosition.row>=t.endLine);if(!n)return!1;if(/\boverride\b/.test(n.text.slice(0,Math.max(0,n.text.indexOf("{")))))return!0;let e=n.parent;for(;e&&e.type!=="class_declaration"&&e.type!=="class";)e=e.parent;if(!e)return!1;let o=e.text.slice(0,Math.max(0,e.text.indexOf("{")));return/\bimplements\b/.test(o)||/\bextends\b/.test(o)?!0:p.has(t.leaf)&&/\bextends\s+(?:React\.)?(?:Component|PureComponent)\b/.test(o)}export{l as a};
2
+ //# sourceMappingURL=chunk-2HFXPIBT.js.map
@@ -0,0 +1,35 @@
1
+ import{a as g}from"./chunk-QB7NRST4.js";import{h as p}from"./chunk-DA34GNNO.js";import{a as f}from"./chunk-YSUD2S7T.js";import{d as u,e as _,i as N}from"./chunk-OO6S4ECV.js";import{p as d}from"./chunk-NLVKD45E.js";import{B as l,b as c}from"./chunk-MCNWCJYL.js";import{a as I}from"./chunk-64MNV6AB.js";import{y as b}from"./chunk-WFRZGMWJ.js";function Y(e,t,r={}){return T(e,t,r)?.map(s=>({symbol:s.symbol,shortName:s.shortName,fromFile:s.fromFile}))??[]}function Z(e,t){let r=f(e,t),s=O(e,t);if(s.length>0&&!x(r))return s;let o=k(e,t,r);return h(t)&&o.length>0?o:D([...s,...o])}function G(e,t,r={}){let s=g(e,t);if(!s)return[];let o=S(e,s),n=r.semantic===!1?null:E(e,s);return(n?R(n,o):o).filter(m=>!m.used).map(m=>({symbol:m.symbol,shortName:m.shortName,importedIn:m.importer}))}function R(e,t){let r=new Map;for(let o of t){let n=r.get(o.shortName);n?n.push(o):r.set(o.shortName,[o])}let s=e.map(o=>{let n=r.get(o.shortName),i=n?.shift();return n?.length===0&&r.delete(o.shortName),i?{...o,used:o.used||i.used}:o});return s.push(...[...r.values()].flat()),s}function O(e,t){return e.all(`SELECT DISTINCT gs.symbol, d.relative_path AS importer
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
+ JOIN global_symbols gs ON m.symbol_id = gs.id
6
+ WHERE gs.symbol LIKE ?
7
+ AND m.role = 2
8
+ ORDER BY d.relative_path`,`%${t}%`).filter(s=>!e.isIgnored(s.importer)).map(s=>({symbol:s.symbol,shortName:u(s.symbol),fromFile:s.importer}))}function k(e,t,r=f(e,t)){let s=r?.relativePath??null,o=r?_(r.symbol):t.replace(/\(\)$/,""),n=r?N(r.symbol):!1,i=new Set;for(let a of I(e,{includeIgnored:!1}))for(let F of d(e,a))M(F,a,{targetFile:s,targetLeaf:o,targetIsModule:n,targetPattern:t})&&i.add(a);let m=h(t)?t.trim():null;return[...i].sort().map(a=>({symbol:m??r?.symbol??o,shortName:m??(r?u(r.symbol):o),fromFile:a}))}function x(e){return!!(e&&(e.symbol.startsWith("scip-clojure ")||l(e.relativePath)==="clojure"))}function D(e){let t=new Set,r=[];for(let s of e){let o=`${s.symbol}|${s.fromFile}`;t.has(o)||(t.add(o),r.push(s))}return r.sort((s,o)=>s.fromFile.localeCompare(o.fromFile)||s.shortName.localeCompare(o.shortName))}function M(e,t,r){return!e.sourcePath||r.targetFile&&c(e.sourcePath)!==c(r.targetFile)?!1:e.kind==="side-effect"||r.targetFile&&$(t)||e.kind==="namespace"&&P(e,r.targetPattern)||r.targetIsModule||e.kind==="named"&&e.importedName===r.targetLeaf?!0:e.kind==="namespace"&&e.usedMembers.includes(r.targetLeaf)}function P(e,t){let r=t.trim().replace(/\(\)$/,"");return h(r)?e.importedName===r||e.localName===r:!1}function h(e){let t=e.trim().replace(/\(\)$/,"");return t.includes(".")&&!t.includes("/")&&!t.includes(":")}function T(e,t,r={}){let s=g(e,t);return s?L(e,s,r)??(r.semantic===!1?null:E(e,s))??S(e,s):null}function L(e,t,r){let o=e.all(`SELECT DISTINCT
9
+ gs.symbol,
10
+ def_d.relative_path AS from_file,
11
+ imp_d.relative_path AS importer,
12
+ EXISTS (
13
+ SELECT 1
14
+ FROM mentions ref_m
15
+ JOIN chunks ref_c ON ref_m.chunk_id = ref_c.id
16
+ WHERE ref_m.symbol_id = gs.id
17
+ AND ref_m.role != 1
18
+ AND ref_c.document_id = imp_d.id
19
+ ) AS used
20
+ FROM mentions m
21
+ JOIN chunks c ON m.chunk_id = c.id
22
+ JOIN documents imp_d ON c.document_id = imp_d.id
23
+ JOIN global_symbols gs ON m.symbol_id = gs.id
24
+ LEFT JOIN (
25
+ SELECT m2.symbol_id, c2.document_id
26
+ FROM mentions m2
27
+ JOIN chunks c2 ON m2.chunk_id = c2.id
28
+ WHERE m2.role = 1
29
+ GROUP BY m2.symbol_id
30
+ ) sym_def ON sym_def.symbol_id = gs.id
31
+ LEFT JOIN documents def_d ON sym_def.document_id = def_d.id
32
+ WHERE imp_d.relative_path = ?
33
+ AND m.role = 2
34
+ ORDER BY def_d.relative_path, gs.symbol`,t).filter(n=>!e.isIgnored(n.importer));if(o.length>0){let n=r.semantic===!1?[]:p(e,t);return o.map(i=>({symbol:i.symbol,shortName:u(i.symbol),fromFile:i.from_file??"(external)",importer:i.importer,used:i.used!==0||n.some(m=>m.isUsed&&m.sourcePath===i.from_file)}))}return null}function E(e,t){let r=p(e,t);return r.length>0?r.map(s=>{let o=y(s.importedName,s.localName,s.kind);return{symbol:o,shortName:o,fromFile:s.sourcePath??"(external)",importer:t,used:s.kind==="side-effect"?!0:s.isUsed}}):null}function S(e,t){let r=A(t,b(e,t));return d(e,t).map(s=>{let o=y(s.importedName,s.localName,s.kind),n=s.kind==="side-effect"||v(t,s)||r.has(s.localName??s.importedName)?!0:s.used;return{symbol:o,shortName:o,fromFile:s.sourcePath??"(external)",importer:t,used:n}})}function A(e,t){let r=new Set;if(l(e)!=="python")return r;let s=/(?:^|\n)\s*__all__\s*(?:\+?=)\s*[[(]([\s\S]*?)[\])]/g;for(let o of t.matchAll(s)){let n=o[1]??"";for(let i of n.matchAll(/(['"])([A-Za-z_]\w*)\1/g))r.add(i[2])}return r}function v(e,t){if(l(e)!=="rust"||t.used||t.kind==="side-effect")return!1;let r=t.localName??t.importedName;return r==="_"||/^[A-Z]/.test(r)}function y(e,t,r){return r==="namespace"&&e==="*"&&t?`* as ${t}`:r==="default"&&t?`default as ${t}`:r==="side-effect"?"(side effect import)":t&&t!==e?`${e} as ${t}`:e}function $(e){return/\.(?:c|h|cc|cpp|cxx|hpp|hh|hxx)$/i.test(e)}export{Y as a,Z as b,G as c};
35
+ //# sourceMappingURL=chunk-2LGPMYS2.js.map
@@ -0,0 +1,16 @@
1
+ import{d as A,i as T}from"./chunk-DA34GNNO.js";import{d as I}from"./chunk-YSUD2S7T.js";import{e as d,s as w,z as P}from"./chunk-OO6S4ECV.js";import{a as v,b as F,f as h,p as y}from"./chunk-NLVKD45E.js";import{B as k,L as R,a as D,c as p}from"./chunk-MCNWCJYL.js";import{c as u,d as M,y as m}from"./chunk-WFRZGMWJ.js";function L(e,r,n,t={}){if(!n)return[];let i=m(e,r);return i?i.indexOf(n)===-1?[]:(x(e,r).get(n)??[]).filter(o=>!J(o,t)):[]}function J(e,r){return typeof r.excludeStartLine=="number"&&typeof r.excludeEndLine=="number"&&e>=r.excludeStartLine&&e<=r.excludeEndLine}var Y=u("file-identifiers",{clearGroups:["whole-project","source-file"]});function O(e,r){let n=h(e,r);return n?n.fileIdentifiers:Y.get(e,r,()=>new Set(x(e,r).keys()))}var W=u("file-ident-lines",{clearGroups:["whole-project","source-file"]});function x(e,r){let n=h(e,r);return n?n.identifierLineMap:W.get(e,r,()=>X(e,r))}var V=u("file-idents-by-line",{clearGroups:["whole-project","source-file"]});function pe(e,r){let n=h(e,r);return n?n.identifiersByLine:V.get(e,r,()=>{let t=x(e,r),i=0;for(let o of t.values()){let c=o[o.length-1];c!==void 0&&c>i&&(i=c)}let a=new Array(i+1);for(let o=0;o<=i;o+=1)a[o]=new Set;for(let[o,c]of t)for(let s of c)a[s].add(o);return a})}function X(e,r){let n=new Map,t=(c,s)=>{let l=n.get(c);if(!l){n.set(c,[s]);return}l[l.length-1]!==s&&l.push(s)},i=m(e,r);if(!i)return n;let a=F(i).split(/\r?\n/),o=/\b([A-Za-z_$][\w$]*)\b/g;for(let c=0;c<a.length;c+=1){let s=a[c]??"";for(let l of s.matchAll(o))l[1]&&t(l[1],c)}return n}function Le(e,r){let n=z(e);return n?r.filter(t=>z(t.file)===n):r}function _e(e,r,n,t){let i=n.find(a=>a.file===r);if(i)return i;if(t){let a=new Set(y(e,r).map(o=>o.sourcePath).filter(o=>!!o));for(let o of n)for(let c of a)if(p(c,o.file))return o;return null}return n.length===1?n[0]:null}function z(e){let r=k(e);return r?r==="typescript"||r==="tsx"||r==="javascript"?"javascript-family":r:null}var q=M("global-leaf-index",{clearGroups:["whole-project"]});function E(e){return q.get(e,()=>{let r=e.all(`SELECT gs.id, gs.symbol,
2
+ COALESCE(der_doc.relative_path, mention_doc.relative_path) AS relative_path
3
+ FROM global_symbols gs
4
+ LEFT JOIN defn_enclosing_ranges der ON der.symbol_id = gs.id
5
+ LEFT JOIN documents der_doc ON der_doc.id = der.document_id
6
+ LEFT JOIN (
7
+ SELECT m.symbol_id, MIN(d.relative_path) AS relative_path
8
+ FROM mentions m
9
+ JOIN chunks c ON m.chunk_id = c.id
10
+ JOIN documents d ON c.document_id = d.id
11
+ WHERE m.role = 1
12
+ GROUP BY m.symbol_id
13
+ ) mention_doc ON mention_doc.symbol_id = gs.id
14
+ WHERE 1 = 1
15
+ ${e.symbolNoiseFor("gs")}`),n=new Map;for(let t of r){if(!t.relative_path||e.isIgnored(t.relative_path))continue;let i=d(t.symbol);if(!i)continue;let a=n.get(i);a||(a=[],n.set(i,a)),a.some(o=>o.symbolId===t.id)||a.push({symbol:t.symbol,symbolId:t.id,file:t.relative_path})}return n})}var K=u("source-import-paths-by-local-name",{clearGroups:["whole-project","source-file"]});function $(e,r){let n=D(r);return K.get(e,n,()=>Q(e,n))}function Q(e,r){let n=new Map;for(let t of y(e,r)){if(!t.sourcePath)continue;let i=t.localName??t.importedName;if(i&&j(n,i,t.sourcePath),t.kind==="namespace")for(let a of t.usedMembers)j(n,a,t.sourcePath)}return n}function j(e,r,n){let t=e.get(r);t||(t=new Set,e.set(r,t)),t.add(n)}var B=/[A-Za-z_$][A-Za-z0-9_$]*/g,G=/^[A-Za-z_$][A-Za-z0-9_$]*$/,ee=512;function C(e){let r=[],n=!1;for(let t of e)t&&(n=!0,G.test(t)||r.push(t));return{candidateNames:e,hasUsableCandidate:n,nonIdentifierNames:r}}function H(e,r){let n=te(r)?r:C(r);if(n.candidateNames.size===0||!n.hasUsableCandidate)return!0;if(n.candidateNames.size<=ee){for(let i of n.candidateNames)if(i){if(G.test(i)){if(ne(i).test(e))return!0;continue}if(e.includes(i))return!0}return!1}B.lastIndex=0;let t;for(;(t=B.exec(e))!==null;)if(n.candidateNames.has(t[0]))return!0;for(let i of n.nonIdentifierNames)if(e.includes(i))return!0;return!1}function te(e){return"candidateNames"in e}function ne(e){return new RegExp(`(?<![A-Za-z_$0-9])${v(e)}(?![A-Za-z_$0-9])`)}function N(e,r,n){let t=E(e).get(n);if(!t||t.length===0)return[];if(t.length===1)return[g(t[0])];let i=t.filter(s=>s.file===r);if(i.length>0)return i.map(g);let a=$(e,r),o=a.get(n);if(o)for(let s of o){let l=t.filter(f=>p(s,f.file));if(l.length>0)return l.map(g)}let c=new Set;for(let s of a.values())for(let l of s)c.add(l);for(let s of c){let l=t.filter(f=>p(s,f.file));if(l.length>0&&l.length===t.length)return l.map(g)}return[]}function Be(e,r,n){let t=N(e,r,n);if(t.length>0)return t;let i=E(e).get(n);return!i||i.length===0?[]:i.map(g)}function U(e,r,n={}){let t=I(e,r);if(!t)return[];let i=d(t.symbol);if(!i)return[];if(n.semantic!==!1){let o=T(e,{...t,leaf:i,parentTypeName:null,isFunctionLike:!1,isTypeLike:!1,kind:null,documentation:null,enclosingSymbol:null});if(o.length>0){let c=new Map;for(let s of o){let l=c.get(s.file)??[];l.push(s.line),c.set(s.file,l)}return _(e,c)}}let a=new Map;for(let o of R(e)){let c=m(e,o);if(!c||c.indexOf(i)===-1||o!==t.relativePath&&!N(e,o,i).some(f=>f.symbolId===t.symbolId))continue;let s=L(e,o,i,o===t.relativePath?{excludeStartLine:t.startLine,excludeEndLine:t.endLine}:{});s.length>0&&a.set(o,s)}return _(e,a)}function Ge(e,r,n={}){let t=new Map;for(let s of r){if(!s.leaf)continue;let l=t.get(s.leaf)??[];l.push(s),t.set(s.leaf,l)}if(t.size===0)return new Map;let i=new Set(r.map(s=>s.symbolId)),a=new Set(t.keys()),o=C(a),c=new Map;for(let s of R(e)){if(n.skipPath?.(s)||!H(m(e,s),o))continue;let l=O(e,s);if(l.size!==0){for(let f of l)if(t.has(f))for(let b of N(e,s,f)){if(!i.has(b.symbolId)||s===b.relativePath)continue;let S=c.get(b.symbolId);S||(S=new Set,c.set(b.symbolId,S)),S.add(s)}}}return c}function g(e){return{symbolId:e.symbolId,symbol:e.symbol,relativePath:e.file}}function _(e,r){let n=[],t=new Set;for(let[i,a]of r){let o=w(e,i);for(let c of a){let s=P(o,c),l=`${i}|${c}|${s?.symbol??""}`;t.has(l)||(t.add(l),n.push({file:i,line:c,enclosingSymbol:s?.symbol??null}))}}return n}function re(e,r){let n=le(e,r);return n?_(e,oe(e,n.match,n.identifier)):[]}function Ve(e,r,n={}){return ie(e,r,n).map(t=>({file:t.file,line:t.line,enclosingSymbol:t.enclosingSymbol}))}function ie(e,r,n={}){let t=U(e,r,{semantic:n.semantic}),i=t.length>0?Z(t,"source-attribution"):Z(re(e,r),"scip-reference-chunk");return n.includeIgnored===!0?i:i.filter(a=>!e.isIgnored(a.file))}function Z(e,r){return e.map(n=>({...n,provenance:r}))}function oe(e,r,n){let t=new Map;for(let[i,a]of se(e,r.symbolId))t.set(i,ae(e,i,a,r,n));return t}function se(e,r){let n=new Map;for(let t of A(e,[r])){if(e.isIgnored(t.relative_path))continue;let i=n.get(t.relative_path);i||(i=[],n.set(t.relative_path,i)),i.push({start_line:t.chunk_start,end_line:t.chunk_end})}return n}function ae(e,r,n,t,i){let a=r===t.relativePath?{excludeStartLine:t.startLine,excludeEndLine:t.endLine}:{},o=i?L(e,r,i,a):[];return n.flatMap(c=>ce(o,c))}function ce(e,r){let n=e.filter(t=>t>=r.start_line&&t<=r.end_line);return n.length>0?n:[r.start_line]}function le(e,r){let n=I(e,r);return n?{match:n,identifier:d(n.symbol)||null}:null}export{x as a,pe as b,Le as c,_e as d,E as e,C as f,H as g,$ as h,N as i,Be as j,Ge as k,re as l,Ve as m};
16
+ //# sourceMappingURL=chunk-2Y7YX54K.js.map
@@ -0,0 +1,2 @@
1
+ import{a as u}from"./chunk-3I34FZ6R.js";import{a as h}from"./chunk-UO4IADXJ.js";import{m as S}from"./chunk-2Y7YX54K.js";import{a as d,c as b}from"./chunk-YSUD2S7T.js";import{d as m,z as y}from"./chunk-OO6S4ECV.js";function v(e,o,l={}){let{direction:c="backward",maxDepth:s=3}=l,r=d(e,o);return r?c==="backward"?w(e,r,s,{semantic:l.semantic!==!1}):M(e,r,{semantic:l.semantic!==!1}):null}function w(e,o,l,c){let s=[],r=new Set([o.symbol]),t=[o];for(let n=1;n<=l&&t.length!==0;n++){let i=[];for(let p of t){let g=h(e,p,{semantic:c.semantic});for(let a of g){if(r.has(a.symbol))continue;r.add(a.symbol),s.push({symbol:a.symbol,shortName:m(a.symbol),file:a.file,relationship:n===1?"referenced within definition (callee)":`depth ${n} callee`});let f=b(e,a.symbol);f&&!e.isIgnored(f.relativePath)&&i.push(f)}}t=i}return{symbol:o.symbol,shortName:m(o.symbol),direction:"backward",connectedSymbols:s}}function M(e,o,l){let c=new Set,s=[],r=new u(e);for(let t of S(e,o,{semantic:l.semantic})){if(s.length>=30)break;let n=t.enclosingSymbol??y(r.definitionsForFile(t.file),t.line)?.symbol??null;if(!n||n===o.symbol)continue;let i=b(e,n);!i||e.isIgnored(i.relativePath)||c.has(i.symbol)||(c.add(i.symbol),s.push({symbol:i.symbol,shortName:m(i.symbol),file:i.relativePath,relationship:`references target at ${t.file}:${t.line+1}`}))}return s.sort((t,n)=>t.file.localeCompare(n.file)),{symbol:o.symbol,shortName:m(o.symbol),direction:"forward",connectedSymbols:s}}export{v as a};
2
+ //# sourceMappingURL=chunk-363TZ64I.js.map
@@ -0,0 +1,2 @@
1
+ import{b as I,f as W,g as Y}from"./chunk-NLRWGGPY.js";import{a as x}from"./chunk-BGBBVSH4.js";import{b as U,d as X,e as Z,f as $}from"./chunk-UO4IADXJ.js";import{a as _,f as z,g as J,i as N,j as Q}from"./chunk-2Y7YX54K.js";import{a as B}from"./chunk-G4KQ7S74.js";import{a as j,g as k,h as T,j as V,k as G,s as D,u as H,v as O,w as P}from"./chunk-OO6S4ECV.js";import{m as F}from"./chunk-NLVKD45E.js";import{B as R,C as E,L as K}from"./chunk-MCNWCJYL.js";import{a as q}from"./chunk-64MNV6AB.js";import{B as h,s as w,y as A}from"./chunk-WFRZGMWJ.js";function ee(n,e,t){let r=e.identifierResolution==="strict"?N:Q,l=e.candidateNames?z(e.candidateNames):null,o=0,f=0,m=0,p=0,y="";for(let a of e.paths)if(o+=1,y=a,!(!R(a)&&!(e.includeVueSfc&&E(a)))&&!n.isIgnored(a)&&!e.skipPath?.(a))try{if(l&&!J(A(n,a),l))continue;f+=1;let S=(s,u,v,b)=>{if(e.candidateNames&&!e.candidateNames.has(s))return;m+=1;let g=e.resolveTargets?e.resolveTargets({sourceFile:a,name:s,kind:u,defaultTargets:b}):b();for(let L of g)p+=1,t({sourceFile:a,name:s,target:L,occurrences:v,kind:u})},M=_(n,a);for(let[s,u]of M)S(s,"identifier",u.length,()=>r(n,a,s));for(let s of F(n,a,{includeCrossLanguageDispatchNames:e.includeCrossLanguageDispatchNames,includeRustAttributeNames:e.includeRustAttributeNames})){let u=s.kind==="cross-language-dispatch"?()=>N(n,a,s.name):()=>r(n,a,s.name);S(s.name,s.kind,s.occurrences,u)}}finally{e.afterPath?.(a),o%10===0&&w("source-reference-scan.progress",()=>{},()=>({scannedPaths:o,currentPath:y,candidateMatchedPaths:f,visitedNames:m,visitedHits:p}))}}function ne(n,e={}){let{scope:t,files:r,minLoc:l=1,maxLoc:o=Number.POSITIVE_INFINITY,excludeSymbol:f,excludeEntrySurfaces:m=!1,excludeTypesFiles:p=!1,excludeRootedSymbols:y=!1,requireFunctionLikeSymbol:a=!1,requireCallableSymbol:C=!1,excludeRustTraitImplMembers:S=!1,includeSuppressed:M=!1,sortByLocDesc:s=!1}=e,u=[],v=re(n,{scope:t,files:r,requireFunctionLikeSymbol:a,requireCallableSymbol:C}),b=new Map,g=new Map,L=i=>{let c=b.get(i);if(c!==void 0)return c;let d=W(n,i);return b.set(i,d),d},ie=i=>{let c=g.get(i);if(c!==void 0)return c;let d=I(i);return g.set(i,d),d};for(let i of v){let c=i.relativePath;if(n.isIgnored(c)||m&&L(c)||!oe(i,{requireFunctionLikeSymbol:a,requireCallableSymbol:C})||f!==void 0&&i.symbol===f)continue;let d=x(i);d<l||d>o||p&&ae(c)||y&&Y(n,i.symbol,c)||S&&V(i.symbol)||ie(c)!=="test"&&(G(i.symbol)||!M&&h(n,c,i.startLine)||u.push(i))}return s?u.sort((i,c)=>x(c)-x(i)):u}function re(n,e){return e.files!==void 0?[...new Set(e.files.map(r=>r.replace(/\\/g,"/")))].sort().filter(r=>!e.scope||r.includes(e.scope)).flatMap(r=>D(n,r)):e.requireCallableSymbol?P(n,{scope:e.scope,symbolMatches:k,sqlPrefilter:"callable"}):e.requireFunctionLikeSymbol?P(n,{scope:e.scope,symbolMatches:T,sqlPrefilter:"function-like"}):O(n,e.scope)}function oe(n,e){return e.requireCallableSymbol?k(n.symbol):e.requireFunctionLikeSymbol?T(n.symbol):n.isFunctionLike}function ae(n){return(n.split("/").pop()??"").includes("types")}var te=class{constructor(e){this.db=e}db;scopedDefinitions(e){return H(this.db,e)}definitionsForFile(e){return D(this.db,e)}productionCallableDefinitions(e={}){return ne(this.db,e)}calleeMap(e,t={}){return U(this.db,e,t)}crossFileCallerMap(e,t={}){return X(this.db,e,t)}sourceFallbackCallerFiles(e,t={}){return Z(this.db,e,t)}callerFileMap(e,t={}){return $(this.db,e,t)}frameworkReferencedSymbolIds(e){let t=new Map;for(let l of e){if(!l.leaf)continue;let o=t.get(l.leaf)??[];o.push(l.symbolId),t.set(l.leaf,o)}let r=new Set;for(let l of q(this.db,{includeIgnored:!1}))if(R(l)==="rust")for(let{name:o}of F(this.db,l,{includeRustAttributeNames:!0}))for(let f of t.get(o)??[])r.add(f);return r}symbolsWithNonSelfCallees(e,t={}){if(e.length===0)return new Set;let r=new Map(e.map(o=>[o.symbolId,o.symbol])),l=this.calleeMap(e,t);return new Set([...l.entries()].filter(([o,f])=>{let m=r.get(o);return f.some(p=>p.symbol!==m)}).map(([o])=>o))}fileDependencyGraph(e){return B(this.db,e)}fileKind(e){return I(e)}hasSuppressionComment(e){return h(this.db,e.relativePath,e.startLine)}sourceFiles(){return K(this.db)}scanSourceReferences(e,t){ee(this.db,e,t)}callableSignature(e){let t=j(this.db).forFile(e.relativePath,{facts:!0}).facts?.callables.find(r=>r.startLine===e.startLine&&r.endLine===e.endLine);return t?{paramCount:t.paramCount}:null}};export{te as a};
2
+ //# sourceMappingURL=chunk-3I34FZ6R.js.map
@@ -0,0 +1,2 @@
1
+ import{a as R,b as H}from"./chunk-ZEKBAMCN.js";import{a as B,b,c as y,e as h,f as k}from"./chunk-B3X6KU75.js";import{a as p,b as g}from"./chunk-KMVGRIO2.js";import{N as v}from"./chunk-MCNWCJYL.js";function V(e,s={}){let{minSimilarity:m=.45,minSharedBehaviors:i=6,limit:o=20,scope:c,scanLimit:n,filePattern:d,focusFiles:f}=s,l=v(e).reactProfiles({scope:c,minBehaviorTokens:Math.max(3,i),scanLimit:n}).map(r=>({file:r.file,component:r.name,tokens:r.behaviorTokens,profile:r})),t=R(l,r=>r.tokens);return H({profiles:l,limit:o,filePattern:d,focusFiles:f,candidateIndex:t,profile:{name:"react-hook-candidates"},compare:(r,a)=>C(r,a,m,i),sort:(r,a)=>a.similarity-r.similarity||r.fileA.localeCompare(a.fileA)||r.componentA.localeCompare(a.componentA)||r.fileB.localeCompare(a.fileB)||r.componentB.localeCompare(a.componentB)})}function C(e,s,m,i){let o=p(e.tokens,s.tokens);if(o.size<i||!E(o))return null;let c=b(e.tokens,s.tokens);if(c<m)return null;let n=h(o,"hook:"),d=h(o,"react-hook:"),f=h(o,"effect:"),l=h(o,"state:"),t=h(o,"request:"),r=h(o,"handler:"),a=h(o,"handler-verb:"),u=A({sharedHooks:n,sharedReactHooks:d,sharedEffects:f,sharedState:l,sharedRequests:t,sharedHandlers:r,sharedHandlerVerbs:a});return{fileA:e.file,componentA:e.component,fileB:s.file,componentB:s.component,similarity:c,tokenCountA:e.tokens.size,tokenCountB:s.tokens.size,sharedTokens:k(o),sharedHooks:n,sharedReactHooks:d,sharedEffects:f,sharedState:l,sharedRequests:t,sharedHandlers:r,sharedHandlerVerbs:a,evidenceClass:u.evidenceClass,actionTier:u.actionTier,evidenceClassReasons:u.reasons,recommendation:u.recommendation,uniqueToA:k(g(e.tokens,s.tokens)).slice(0,25),uniqueToB:k(g(s.tokens,e.tokens)).slice(0,25),reason:P({sharedHooks:n,sharedReactHooks:d,sharedEffects:f,sharedState:l,sharedRequests:t,sharedHandlers:r,sharedHandlerVerbs:a}),locA:e.profile.loc,locB:s.profile.loc}}function A(e){return B({genericWords:q,stripPrefixes:w,primitiveGroups:[{values:e.sharedReactHooks,reasonPrefix:"shared React primitives",bucket:"generic"},{values:e.sharedEffects,reasonPrefix:"shared lifecycle primitive",bucket:"generic"}],nameGroups:[{names:e.sharedHooks,label:"shared hook",fallbackBucket:"shared-abstraction"},{names:e.sharedRequests,label:"shared request",fallbackBucket:"generic"},{names:e.sharedState,label:"shared state",fallbackBucket:"generic"},{names:e.sharedHandlers,label:"shared handler",fallbackBucket:"generic"},{names:e.sharedHandlerVerbs,label:"shared action verb",fallbackBucket:"generic"}],recommendation:S})}function S(e){switch(e){case"domain-behavior":return"Review for a shared hook, controller, or feature module around the named domain behavior.";case"mixed":return"Separate generic React mechanics from domain-specific behavior before extracting a shared hook.";case"shared-abstraction":return"Review the existing shared hook usage first; extract only if duplicated behavior remains outside it.";case"generic-workflow-scaffolding":return"Treat as support evidence for a repeated workflow shape, not direct hook-extraction evidence."}}function E(e){let s=0,m=0,i=0,o=0,c=0,n=0,d=0;for(let t of e)t.startsWith("hook:")?s+=1:t.startsWith("react-hook:")?m+=1:t.startsWith("effect:")?i+=1:t.startsWith("request:")?o+=1:t.startsWith("handler:")||t.startsWith("handler-verb:")?c+=1:t.startsWith("state:")?n+=1:t.startsWith("state-hook:")&&(d+=1);let f=n+d,l=s+m+i+o+c+f;return y([{name:"requests",count:o},{name:"customHooks",count:s},{name:"namedStates",count:n},{name:"handlers",count:c},{name:"effects",count:i},{name:"reactHooks",count:m},{name:"namedBehavior",count:l}],[{min:{requests:1,namedBehavior:4},reason:"shared request workflow"},{min:{customHooks:1,requests:1,namedBehavior:5},reason:"shared custom hook and request workflow"},{min:{customHooks:1,namedStates:1,namedBehavior:5},reason:"shared custom hook and state"},{min:{customHooks:1,handlers:2,namedBehavior:5},reason:"shared custom hook and handlers"},{min:{namedStates:1,handlers:2,effects:1,namedBehavior:5},reason:"shared stateful effects"},{min:{namedStates:1,handlers:2,reactHooks:2,namedBehavior:5},reason:"shared stateful React primitives"}]).pass}function P(e){let s=[];return e.sharedHooks.length&&s.push(`shared hooks: ${e.sharedHooks.join(", ")}`),e.sharedReactHooks.length&&s.push(`shared React hooks: ${e.sharedReactHooks.join(", ")}`),e.sharedEffects.length&&s.push(`shared effects: ${e.sharedEffects.join(", ")}`),e.sharedState.length&&s.push(`shared state: ${e.sharedState.join(", ")}`),e.sharedRequests.length&&s.push(`shared requests: ${e.sharedRequests.join(", ")}`),e.sharedHandlers.length&&s.push(`shared handlers: ${e.sharedHandlers.slice(0,6).join(", ")}`),e.sharedHandlerVerbs.length&&s.push(`shared action verbs: ${e.sharedHandlerVerbs.slice(0,6).join(", ")}`),s.join("; ")||"shared React behavior profile"}var q=new Set(["add","apply","async","callback","cancel","change","clear","close","create","data","delete","draft","edit","effect","error","fetch","filter","form","handle","has","is","item","items","load","loader","loading","memo","name","open","reducer","refresh","ref","remove","request","reset","resource","row","rows","save","saving","search","select","selected","state","store","submit","toggle","update","use","value"]),w=[/^use(?=[A-Z])/,/^handle(?=[A-Z])/,/^is(?=[A-Z])/,/^has(?=[A-Z])/];export{V as a};
2
+ //# sourceMappingURL=chunk-3LAKH6BV.js.map
@@ -0,0 +1,3 @@
1
+ function m(e){try{return process.kill(e,0),!0}catch(n){return typeof n=="object"&&n!==null&&"code"in n&&n.code==="EPERM"}}import{mkdirSync as t,renameSync as c,writeFileSync as s}from"fs";import{dirname as l}from"path";function d(e,n,r={}){t(l(e),{recursive:!0});let o=`${e}.${process.pid}.${Date.now()}.tmp`,i=JSON.stringify(n,null,r.spacing);s(o,r.trailingNewline?`${i}
2
+ `:i),c(o,e)}export{m as a,d as b};
3
+ //# sourceMappingURL=chunk-3M2UCPFS.js.map
@@ -0,0 +1,2 @@
1
+ import{a as C,b}from"./chunk-ZEKBAMCN.js";import{a as P,c as y,e as r,f}from"./chunk-B3X6KU75.js";import{a as g,b as h,c as k}from"./chunk-KMVGRIO2.js";import{N as v}from"./chunk-MCNWCJYL.js";function L(e,i={}){let{minSimilarity:o=.62,minTokens:n=8,limit:c=20,scope:l,scanLimit:u,filePattern:m,focusFiles:d}=i,s=B(e,{scope:l,minTokens:n,scanLimit:u}),p=C(s,t=>t.tokens);return b({profiles:s,limit:c,filePattern:m,focusFiles:d,candidateIndex:p,profile:{name:"vue-component-duplicates"},compare:(t,a)=>V(t,a,o),sort:(t,a)=>a.similarity-t.similarity||t.fileA.localeCompare(a.fileA)||t.fileB.localeCompare(a.fileB)})}function B(e,i){return v(e).vueProfiles({scope:i.scope,minTemplateTokens:i.minTokens,scanLimit:i.scanLimit}).map(o=>({file:o.file,tokens:o.templateTokens,loc:T(o)}))}function T(e){return e.totalLines}function V(e,i,o){let n=g(e.tokens,i.tokens);if(n.size<6||!R(n))return null;let c=k(e.tokens,i.tokens);if(c<o)return null;let l=r(n,"component:"),u=r(n,"prop:"),m=r(n,"event:"),d=r(n,"directive:"),s=r(n,"slot:"),p=r(n,"id:"),t=S({sharedComponents:l,sharedProps:u,sharedEvents:m,sharedDirectives:d,sharedSlots:s,sharedIdentifiers:p});return{fileA:e.file,fileB:i.file,similarity:c,tokenCountA:e.tokens.size,tokenCountB:i.tokens.size,sharedTokens:f(n),sharedComponents:l,sharedProps:u,sharedEvents:m,sharedDirectives:d,sharedSlots:s,sharedIdentifiers:p,evidenceClass:t.evidenceClass,actionTier:t.actionTier,evidenceClassReasons:t.reasons,recommendation:t.recommendation,uniqueToA:f(h(e.tokens,i.tokens)).slice(0,25),uniqueToB:f(h(i.tokens,e.tokens)).slice(0,25),locA:e.loc,locB:i.loc}}function R(e){let i=0,o=0;for(let n of e)n.startsWith("component:")&&(i+=1),(n.startsWith("prop:")||n.startsWith("event:")||n.startsWith("directive:")||n.startsWith("slot:"))&&(o+=1);return y([{name:"component",count:i},{name:"behavior",count:o}],[{min:{component:1},reason:"shared custom component"},{min:{behavior:3},reason:"shared Vue template structure"}]).pass}function S(e){return P({genericWords:x,primitiveGroups:[{values:e.sharedProps,reasonPrefix:"shared props",bucket:"generic"},{values:e.sharedEvents,reasonPrefix:"shared events",bucket:"generic"},{values:e.sharedDirectives,reasonPrefix:"shared directives",bucket:"generic"},{values:e.sharedSlots,reasonPrefix:"shared slots",bucket:"generic"}],nameGroups:[{names:e.sharedComponents,label:"shared component",fallbackBucket:"generic"},{names:e.sharedIdentifiers,label:"shared identifier",fallbackBucket:"generic"}],recommendation:w})}function w(e){switch(e){case"domain-behavior":case"mixed":return"Review for a shared component or feature-specific Vue 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","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{L as a};
2
+ //# sourceMappingURL=chunk-3OPIMH42.js.map
@@ -1,2 +1,2 @@
1
- import{a as d,b as m}from"./chunk-KJCDEDQW.js";import{c as u}from"./chunk-KMVGRIO2.js";import{a as c}from"./chunk-BP7S6V3M.js";function y(t,e={}){let{minSimilarity:o=.5,limit:l=20,scope:n,filePattern:p}=e,r=e.minDeps??(p?1:3),{profiles:i,distinctiveDeps:f}=D(t,{scope:n,minDeps:r}),s=d(i,a=>a.deps);return m({profiles:i,limit:l,filePattern:p,overrunFactor:5,candidateIndex:s,profile:{name:"similar-files"},compare:(a,g)=>F(a,g,o,f)})}function D(t,e){let{scope:o,minDeps:l}=e,n=c(t,o),{universalDeps:p,distinctiveDeps:r}=S(n),i=[];for(let[f,s]of n)s.size>=l&&i.push({file:f,deps:new Set([...s].filter(a=>!p.has(a)))});return{profiles:i,distinctiveDeps:r}}function S(t){let e=new Set,o=new Set,l=t.size;if(l===0)return{universalDeps:e,distinctiveDeps:o};let n=new Map;for(let r of t.values())for(let i of r)n.set(i,(n.get(i)??0)+1);let p=Math.max(3,Math.ceil(l*.03));for(let[r,i]of n)i>=5&&i/l>.3?e.add(r):i<=p&&o.add(r);return{universalDeps:e,distinctiveDeps:o}}function F(t,e,o,l){let n=new Set;for(let s of t.deps)e.deps.has(s)&&n.add(s);if(n.size<3||t.deps.size<4||e.deps.size<4)return null;let p=0;for(let s of n)l.has(s)&&p++;if(p<2)return null;let r=u(t.deps,e.deps);if(r<o)return null;let i=[];for(let s of t.deps)e.deps.has(s)||i.push(s);let f=[];for(let s of e.deps)t.deps.has(s)||f.push(s);return{fileA:t.file,fileB:e.file,similarity:r,sharedDeps:[...n],uniqueToA:i,uniqueToB:f}}export{y as a};
2
- //# sourceMappingURL=chunk-QZOAOLLZ.js.map
1
+ import{a as d,b as m}from"./chunk-ZEKBAMCN.js";import{c as u}from"./chunk-KMVGRIO2.js";import{a as c}from"./chunk-G4KQ7S74.js";function y(t,e={}){let{minSimilarity:o=.5,limit:l=20,scope:n,filePattern:p}=e,r=e.minDeps??(p?1:3),{profiles:i,distinctiveDeps:f}=D(t,{scope:n,minDeps:r}),s=d(i,a=>a.deps);return m({profiles:i,limit:l,filePattern:p,overrunFactor:5,candidateIndex:s,profile:{name:"similar-files"},compare:(a,g)=>F(a,g,o,f)})}function D(t,e){let{scope:o,minDeps:l}=e,n=c(t,o),{universalDeps:p,distinctiveDeps:r}=S(n),i=[];for(let[f,s]of n)s.size>=l&&i.push({file:f,deps:new Set([...s].filter(a=>!p.has(a)))});return{profiles:i,distinctiveDeps:r}}function S(t){let e=new Set,o=new Set,l=t.size;if(l===0)return{universalDeps:e,distinctiveDeps:o};let n=new Map;for(let r of t.values())for(let i of r)n.set(i,(n.get(i)??0)+1);let p=Math.max(3,Math.ceil(l*.03));for(let[r,i]of n)i>=5&&i/l>.3?e.add(r):i<=p&&o.add(r);return{universalDeps:e,distinctiveDeps:o}}function F(t,e,o,l){let n=new Set;for(let s of t.deps)e.deps.has(s)&&n.add(s);if(n.size<3||t.deps.size<4||e.deps.size<4)return null;let p=0;for(let s of n)l.has(s)&&p++;if(p<2)return null;let r=u(t.deps,e.deps);if(r<o)return null;let i=[];for(let s of t.deps)e.deps.has(s)||i.push(s);let f=[];for(let s of e.deps)t.deps.has(s)||f.push(s);return{fileA:t.file,fileB:e.file,similarity:r,sharedDeps:[...n],uniqueToA:i,uniqueToB:f}}export{y as a};
2
+ //# sourceMappingURL=chunk-3YAZH3JU.js.map
@@ -0,0 +1,2 @@
1
+ import{b as r}from"./chunk-QB7NRST4.js";import{x as e}from"./chunk-OO6S4ECV.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-5P26M63Y.js.map