scip-query 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/IMPROVEMENTS.md +143 -0
  2. package/PLAN.md +320 -0
  3. package/README.md +1213 -0
  4. package/dist/chunk-2QZ23IBN.js +55 -0
  5. package/dist/chunk-2QZ23IBN.js.map +1 -0
  6. package/dist/chunk-36OMT7ZJ.js +144 -0
  7. package/dist/chunk-36OMT7ZJ.js.map +1 -0
  8. package/dist/chunk-3E2X7RIE.js +101 -0
  9. package/dist/chunk-3E2X7RIE.js.map +1 -0
  10. package/dist/chunk-3UOUTZQT.js +45 -0
  11. package/dist/chunk-3UOUTZQT.js.map +1 -0
  12. package/dist/chunk-3ZZJVBIO.js +88 -0
  13. package/dist/chunk-3ZZJVBIO.js.map +1 -0
  14. package/dist/chunk-4TYLS5XX.js +10 -0
  15. package/dist/chunk-4TYLS5XX.js.map +1 -0
  16. package/dist/chunk-5FGUEU7N.js +101 -0
  17. package/dist/chunk-5FGUEU7N.js.map +1 -0
  18. package/dist/chunk-5WTJAXY2.js +61 -0
  19. package/dist/chunk-5WTJAXY2.js.map +1 -0
  20. package/dist/chunk-6NBLIDF4.js +24 -0
  21. package/dist/chunk-6NBLIDF4.js.map +1 -0
  22. package/dist/chunk-6SXADWLW.js +43 -0
  23. package/dist/chunk-6SXADWLW.js.map +1 -0
  24. package/dist/chunk-6VJ6Q7IE.js +65 -0
  25. package/dist/chunk-6VJ6Q7IE.js.map +1 -0
  26. package/dist/chunk-7OZPA5OO.js +258 -0
  27. package/dist/chunk-7OZPA5OO.js.map +1 -0
  28. package/dist/chunk-BEPIEVLR.js +76 -0
  29. package/dist/chunk-BEPIEVLR.js.map +1 -0
  30. package/dist/chunk-BFSCMC22.js +42 -0
  31. package/dist/chunk-BFSCMC22.js.map +1 -0
  32. package/dist/chunk-BP2ATLK2.js +110 -0
  33. package/dist/chunk-BP2ATLK2.js.map +1 -0
  34. package/dist/chunk-CM454WL3.js +114 -0
  35. package/dist/chunk-CM454WL3.js.map +1 -0
  36. package/dist/chunk-DCKMSTJ4.js +74 -0
  37. package/dist/chunk-DCKMSTJ4.js.map +1 -0
  38. package/dist/chunk-DEZKCZXD.js +40 -0
  39. package/dist/chunk-DEZKCZXD.js.map +1 -0
  40. package/dist/chunk-DVWGWHFW.js +99 -0
  41. package/dist/chunk-DVWGWHFW.js.map +1 -0
  42. package/dist/chunk-EMDQWNYR.js +102 -0
  43. package/dist/chunk-EMDQWNYR.js.map +1 -0
  44. package/dist/chunk-FFSWWE5O.js +33 -0
  45. package/dist/chunk-FFSWWE5O.js.map +1 -0
  46. package/dist/chunk-FGXRVW7G.js +73 -0
  47. package/dist/chunk-FGXRVW7G.js.map +1 -0
  48. package/dist/chunk-FUHJCHS4.js +158 -0
  49. package/dist/chunk-FUHJCHS4.js.map +1 -0
  50. package/dist/chunk-GJFURBEW.js +64 -0
  51. package/dist/chunk-GJFURBEW.js.map +1 -0
  52. package/dist/chunk-GTILYBH6.js +102 -0
  53. package/dist/chunk-GTILYBH6.js.map +1 -0
  54. package/dist/chunk-JJP7KQND.js +1 -0
  55. package/dist/chunk-JJP7KQND.js.map +1 -0
  56. package/dist/chunk-JKP5GH6T.js +213 -0
  57. package/dist/chunk-JKP5GH6T.js.map +1 -0
  58. package/dist/chunk-KCBMVQL5.js +38 -0
  59. package/dist/chunk-KCBMVQL5.js.map +1 -0
  60. package/dist/chunk-KVSW5KYP.js +78 -0
  61. package/dist/chunk-KVSW5KYP.js.map +1 -0
  62. package/dist/chunk-LAWMH22O.js +172 -0
  63. package/dist/chunk-LAWMH22O.js.map +1 -0
  64. package/dist/chunk-LB7OS35Q.js +72 -0
  65. package/dist/chunk-LB7OS35Q.js.map +1 -0
  66. package/dist/chunk-LUSIFBXO.js +57 -0
  67. package/dist/chunk-LUSIFBXO.js.map +1 -0
  68. package/dist/chunk-MBVNHJVN.js +44 -0
  69. package/dist/chunk-MBVNHJVN.js.map +1 -0
  70. package/dist/chunk-MGNMHKX3.js +15 -0
  71. package/dist/chunk-MGNMHKX3.js.map +1 -0
  72. package/dist/chunk-N5KEREIA.js +41 -0
  73. package/dist/chunk-N5KEREIA.js.map +1 -0
  74. package/dist/chunk-NDSQYIWT.js +71 -0
  75. package/dist/chunk-NDSQYIWT.js.map +1 -0
  76. package/dist/chunk-NUZ4OMU3.js +28 -0
  77. package/dist/chunk-NUZ4OMU3.js.map +1 -0
  78. package/dist/chunk-QOV2R2WT.js +170 -0
  79. package/dist/chunk-QOV2R2WT.js.map +1 -0
  80. package/dist/chunk-SEFSL2GF.js +78 -0
  81. package/dist/chunk-SEFSL2GF.js.map +1 -0
  82. package/dist/chunk-T6ARFSBZ.js +103 -0
  83. package/dist/chunk-T6ARFSBZ.js.map +1 -0
  84. package/dist/chunk-TBP6BICL.js +46 -0
  85. package/dist/chunk-TBP6BICL.js.map +1 -0
  86. package/dist/chunk-TDNNOR6D.js +97 -0
  87. package/dist/chunk-TDNNOR6D.js.map +1 -0
  88. package/dist/chunk-TSPZOMHC.js +195 -0
  89. package/dist/chunk-TSPZOMHC.js.map +1 -0
  90. package/dist/chunk-UNTPVD36.js +55 -0
  91. package/dist/chunk-UNTPVD36.js.map +1 -0
  92. package/dist/chunk-VRUJH4BO.js +88 -0
  93. package/dist/chunk-VRUJH4BO.js.map +1 -0
  94. package/dist/chunk-VZ7AMAFL.js +76 -0
  95. package/dist/chunk-VZ7AMAFL.js.map +1 -0
  96. package/dist/chunk-XFXDXEUN.js +24 -0
  97. package/dist/chunk-XFXDXEUN.js.map +1 -0
  98. package/dist/chunk-YZAA4LYG.js +169 -0
  99. package/dist/chunk-YZAA4LYG.js.map +1 -0
  100. package/dist/chunk-Z73NYSBZ.js +92 -0
  101. package/dist/chunk-Z73NYSBZ.js.map +1 -0
  102. package/dist/chunk-ZJRYBOEE.js +125 -0
  103. package/dist/chunk-ZJRYBOEE.js.map +1 -0
  104. package/dist/cli.js +5798 -0
  105. package/dist/cli.js.map +1 -0
  106. package/dist/db-BxaevAyc.d.ts +683 -0
  107. package/dist/index.d.ts +254 -0
  108. package/dist/index.js +1271 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/postinstall.js +167 -0
  111. package/dist/postinstall.js.map +1 -0
  112. package/dist/queries/affected.d.ts +14 -0
  113. package/dist/queries/affected.js +9 -0
  114. package/dist/queries/affected.js.map +1 -0
  115. package/dist/queries/bottlenecks.d.ts +18 -0
  116. package/dist/queries/bottlenecks.js +8 -0
  117. package/dist/queries/bottlenecks.js.map +1 -0
  118. package/dist/queries/by-kind.d.ts +20 -0
  119. package/dist/queries/by-kind.js +10 -0
  120. package/dist/queries/by-kind.js.map +1 -0
  121. package/dist/queries/call-graph.d.ts +13 -0
  122. package/dist/queries/call-graph.js +9 -0
  123. package/dist/queries/call-graph.js.map +1 -0
  124. package/dist/queries/change-surface.d.ts +10 -0
  125. package/dist/queries/change-surface.js +9 -0
  126. package/dist/queries/change-surface.js.map +1 -0
  127. package/dist/queries/clean-signature.d.ts +9 -0
  128. package/dist/queries/clean-signature.js +7 -0
  129. package/dist/queries/clean-signature.js.map +1 -0
  130. package/dist/queries/code.d.ts +17 -0
  131. package/dist/queries/code.js +9 -0
  132. package/dist/queries/code.js.map +1 -0
  133. package/dist/queries/complexity-hotspots.d.ts +19 -0
  134. package/dist/queries/complexity-hotspots.js +9 -0
  135. package/dist/queries/complexity-hotspots.js.map +1 -0
  136. package/dist/queries/complexity.d.ts +13 -0
  137. package/dist/queries/complexity.js +9 -0
  138. package/dist/queries/complexity.js.map +1 -0
  139. package/dist/queries/convergence.d.ts +11 -0
  140. package/dist/queries/convergence.js +9 -0
  141. package/dist/queries/convergence.js.map +1 -0
  142. package/dist/queries/coupling.d.ts +17 -0
  143. package/dist/queries/coupling.js +9 -0
  144. package/dist/queries/coupling.js.map +1 -0
  145. package/dist/queries/cycles.d.ts +16 -0
  146. package/dist/queries/cycles.js +8 -0
  147. package/dist/queries/cycles.js.map +1 -0
  148. package/dist/queries/dataflow.d.ts +19 -0
  149. package/dist/queries/dataflow.js +9 -0
  150. package/dist/queries/dataflow.js.map +1 -0
  151. package/dist/queries/dead.d.ts +10 -0
  152. package/dist/queries/dead.js +9 -0
  153. package/dist/queries/dead.js.map +1 -0
  154. package/dist/queries/deep-chains.d.ts +16 -0
  155. package/dist/queries/deep-chains.js +8 -0
  156. package/dist/queries/deep-chains.js.map +1 -0
  157. package/dist/queries/deps.d.ts +9 -0
  158. package/dist/queries/deps.js +9 -0
  159. package/dist/queries/deps.js.map +1 -0
  160. package/dist/queries/diff-impact.d.ts +13 -0
  161. package/dist/queries/diff-impact.js +9 -0
  162. package/dist/queries/diff-impact.js.map +1 -0
  163. package/dist/queries/doc-coverage.d.ts +14 -0
  164. package/dist/queries/doc-coverage.js +8 -0
  165. package/dist/queries/doc-coverage.js.map +1 -0
  166. package/dist/queries/drift.d.ts +25 -0
  167. package/dist/queries/drift.js +8 -0
  168. package/dist/queries/drift.js.map +1 -0
  169. package/dist/queries/extract-candidates.d.ts +25 -0
  170. package/dist/queries/extract-candidates.js +9 -0
  171. package/dist/queries/extract-candidates.js.map +1 -0
  172. package/dist/queries/fan.d.ts +29 -0
  173. package/dist/queries/fan.js +14 -0
  174. package/dist/queries/fan.js.map +1 -0
  175. package/dist/queries/files.d.ts +6 -0
  176. package/dist/queries/files.js +7 -0
  177. package/dist/queries/files.js.map +1 -0
  178. package/dist/queries/health.d.ts +18 -0
  179. package/dist/queries/health.js +21 -0
  180. package/dist/queries/health.js.map +1 -0
  181. package/dist/queries/hierarchy.d.ts +13 -0
  182. package/dist/queries/hierarchy.js +8 -0
  183. package/dist/queries/hierarchy.js.map +1 -0
  184. package/dist/queries/hotspots.d.ts +13 -0
  185. package/dist/queries/hotspots.js +8 -0
  186. package/dist/queries/hotspots.js.map +1 -0
  187. package/dist/queries/imports.d.ts +19 -0
  188. package/dist/queries/imports.js +12 -0
  189. package/dist/queries/imports.js.map +1 -0
  190. package/dist/queries/index.d.ts +47 -0
  191. package/dist/queries/index.js +207 -0
  192. package/dist/queries/index.js.map +1 -0
  193. package/dist/queries/isolated.d.ts +14 -0
  194. package/dist/queries/isolated.js +9 -0
  195. package/dist/queries/isolated.js.map +1 -0
  196. package/dist/queries/members.d.ts +10 -0
  197. package/dist/queries/members.js +8 -0
  198. package/dist/queries/members.js.map +1 -0
  199. package/dist/queries/methods.d.ts +6 -0
  200. package/dist/queries/methods.js +8 -0
  201. package/dist/queries/methods.js.map +1 -0
  202. package/dist/queries/outline.d.ts +10 -0
  203. package/dist/queries/outline.js +8 -0
  204. package/dist/queries/outline.js.map +1 -0
  205. package/dist/queries/passthrough-candidates.d.ts +18 -0
  206. package/dist/queries/passthrough-candidates.js +9 -0
  207. package/dist/queries/passthrough-candidates.js.map +1 -0
  208. package/dist/queries/redundant-reexports.d.ts +22 -0
  209. package/dist/queries/redundant-reexports.js +8 -0
  210. package/dist/queries/redundant-reexports.js.map +1 -0
  211. package/dist/queries/refs.d.ts +6 -0
  212. package/dist/queries/refs.js +7 -0
  213. package/dist/queries/refs.js.map +1 -0
  214. package/dist/queries/similar-chains.d.ts +29 -0
  215. package/dist/queries/similar-chains.js +8 -0
  216. package/dist/queries/similar-chains.js.map +1 -0
  217. package/dist/queries/similar-files.d.ts +19 -0
  218. package/dist/queries/similar-files.js +8 -0
  219. package/dist/queries/similar-files.js.map +1 -0
  220. package/dist/queries/similar-signatures.d.ts +21 -0
  221. package/dist/queries/similar-signatures.js +8 -0
  222. package/dist/queries/similar-signatures.js.map +1 -0
  223. package/dist/queries/similar.d.ts +34 -0
  224. package/dist/queries/similar.js +11 -0
  225. package/dist/queries/similar.js.map +1 -0
  226. package/dist/queries/slice.d.ts +21 -0
  227. package/dist/queries/slice.js +9 -0
  228. package/dist/queries/slice.js.map +1 -0
  229. package/dist/queries/stale-abstractions.d.ts +18 -0
  230. package/dist/queries/stale-abstractions.js +9 -0
  231. package/dist/queries/stale-abstractions.js.map +1 -0
  232. package/dist/queries/stats.d.ts +6 -0
  233. package/dist/queries/stats.js +7 -0
  234. package/dist/queries/stats.js.map +1 -0
  235. package/dist/queries/surface.d.ts +7 -0
  236. package/dist/queries/surface.js +8 -0
  237. package/dist/queries/surface.js.map +1 -0
  238. package/dist/queries/symbols.d.ts +6 -0
  239. package/dist/queries/symbols.js +9 -0
  240. package/dist/queries/symbols.js.map +1 -0
  241. package/dist/queries/system.d.ts +7 -0
  242. package/dist/queries/system.js +9 -0
  243. package/dist/queries/system.js.map +1 -0
  244. package/dist/queries/test-coverage.d.ts +22 -0
  245. package/dist/queries/test-coverage.js +11 -0
  246. package/dist/queries/test-coverage.js.map +1 -0
  247. package/dist/queries/trace.d.ts +6 -0
  248. package/dist/queries/trace.js +8 -0
  249. package/dist/queries/trace.js.map +1 -0
  250. package/dist/queries/wrapper-candidates.d.ts +17 -0
  251. package/dist/queries/wrapper-candidates.js +9 -0
  252. package/dist/queries/wrapper-candidates.js.map +1 -0
  253. package/dist/reindex-worker.js +368 -0
  254. package/dist/reindex-worker.js.map +1 -0
  255. package/docs/AGENT_GUIDE.md +359 -0
  256. package/package.json +70 -0
  257. package/reports/debloat/2026-04-10-scip-query-self-audit.md +161 -0
  258. package/skills/concrete-plan/SKILL.md +318 -0
  259. package/skills/scip-debloat/SKILL.md +413 -0
  260. package/skills/scip-explore/SKILL.md +235 -0
  261. package/skills/scip-verify/SKILL.md +323 -0
  262. package/src/cli.ts +1480 -0
  263. package/src/config.ts +117 -0
  264. package/src/db.ts +127 -0
  265. package/src/gitignore-filter.ts +143 -0
  266. package/src/index.ts +11 -0
  267. package/src/postinstall.ts +8 -0
  268. package/src/queries/affected.ts +86 -0
  269. package/src/queries/bottlenecks.ts +67 -0
  270. package/src/queries/by-kind.ts +204 -0
  271. package/src/queries/call-graph.ts +66 -0
  272. package/src/queries/change-surface.ts +110 -0
  273. package/src/queries/clean-signature.ts +22 -0
  274. package/src/queries/code.ts +101 -0
  275. package/src/queries/complexity-hotspots.ts +119 -0
  276. package/src/queries/complexity.ts +152 -0
  277. package/src/queries/convergence.ts +82 -0
  278. package/src/queries/coupling.ts +99 -0
  279. package/src/queries/cycles.ts +78 -0
  280. package/src/queries/dataflow.ts +128 -0
  281. package/src/queries/dead.ts +122 -0
  282. package/src/queries/deep-chains.ts +59 -0
  283. package/src/queries/deps.ts +46 -0
  284. package/src/queries/diff-impact.ts +204 -0
  285. package/src/queries/doc-coverage.ts +86 -0
  286. package/src/queries/drift.ts +224 -0
  287. package/src/queries/extract-candidates.ts +167 -0
  288. package/src/queries/fan.ts +148 -0
  289. package/src/queries/files.ts +16 -0
  290. package/src/queries/health.ts +324 -0
  291. package/src/queries/hierarchy.ts +49 -0
  292. package/src/queries/hotspots.ts +53 -0
  293. package/src/queries/imports.ts +95 -0
  294. package/src/queries/index.ts +45 -0
  295. package/src/queries/isolated.ts +67 -0
  296. package/src/queries/members.ts +54 -0
  297. package/src/queries/methods.ts +27 -0
  298. package/src/queries/outline.ts +52 -0
  299. package/src/queries/passthrough-candidates.ts +94 -0
  300. package/src/queries/redundant-reexports.ts +170 -0
  301. package/src/queries/refs.ts +27 -0
  302. package/src/queries/similar-chains.ts +314 -0
  303. package/src/queries/similar-files.ts +140 -0
  304. package/src/queries/similar-signatures.ts +151 -0
  305. package/src/queries/similar.ts +305 -0
  306. package/src/queries/slice.ts +154 -0
  307. package/src/queries/stale-abstractions.ts +82 -0
  308. package/src/queries/stats.ts +22 -0
  309. package/src/queries/surface.ts +34 -0
  310. package/src/queries/symbols.ts +39 -0
  311. package/src/queries/system.ts +86 -0
  312. package/src/queries/test-coverage.ts +106 -0
  313. package/src/queries/trace.ts +55 -0
  314. package/src/queries/wrapper-candidates.ts +112 -0
  315. package/src/query-support.ts +226 -0
  316. package/src/reindex/detect.ts +58 -0
  317. package/src/reindex/index.ts +153 -0
  318. package/src/reindex/indexers.ts +220 -0
  319. package/src/reindex/install.ts +125 -0
  320. package/src/reindex-worker.ts +35 -0
  321. package/src/setup.ts +202 -0
  322. package/src/symbol-parser.ts +278 -0
  323. package/src/types.ts +654 -0
  324. package/src/watch.ts +274 -0
  325. package/tests/gitignore-filter.test.ts +48 -0
  326. package/tests/queries.test.ts +300 -0
  327. package/tests/symbol-parser.test.ts +157 -0
  328. package/tsconfig.json +20 -0
  329. package/tsup.config.ts +40 -0
  330. package/vitest.config.ts +7 -0
package/README.md ADDED
@@ -0,0 +1,1213 @@
1
+ # scip-query
2
+
3
+ Language-agnostic code intelligence CLI powered by [SCIP](https://github.com/sourcegraph/scip) indexes. Index any codebase, then query it for references, dependencies, dead code, similarity, coupling, and more — without an IDE or language server running.
4
+
5
+ Works with every language that has a SCIP indexer: TypeScript, JavaScript, Java, Scala, Kotlin, Rust, Python, Ruby, Go, C/C++, C#, Dart, PHP.
6
+
7
+ ## Workflows
8
+
9
+ For goal-oriented usage guides (not just command reference), see **[Agent Guide](docs/AGENT_GUIDE.md)**:
10
+
11
+ - **[Understand a system](docs/AGENT_GUIDE.md#workflow-1-understand-a-system-before-making-changes)** — map a module, trace symbols, check blast radius
12
+ - **[Write an implementation plan](docs/AGENT_GUIDE.md#workflow-2-write-a-concrete-implementation-plan)** — identify contracts, map dependencies, find reusable code
13
+ - **[De-bloat a codebase](docs/AGENT_GUIDE.md#workflow-3-clean-up-and-de-bloat-a-codebase)** — prioritized cleanup from dead code to pattern drift
14
+ - **[Assess code quality](docs/AGENT_GUIDE.md#workflow-4-assess-code-quality-and-risk)** — health score, complexity hotspots, coupling risks
15
+ - **[Verify change impact](docs/AGENT_GUIDE.md#workflow-5-understand-impact-after-making-changes)** — diff impact, transitive blast radius, test gaps
16
+
17
+ ## Quick Start
18
+
19
+ ```bash
20
+ # Install
21
+ npm install -g scip-query
22
+
23
+ # Index your project (auto-detects language)
24
+ scip-query reindex
25
+
26
+ # Start querying
27
+ scip-query stats
28
+ scip-query health # full codebase health report
29
+ scip-query symbols src/auth.service.ts
30
+ scip-query refs login
31
+ scip-query affected login # transitive blast radius
32
+ scip-query dead --min-loc 10
33
+ scip-query similar --min-similarity 0.5
34
+ scip-query diff-impact # what did my changes affect?
35
+ ```
36
+
37
+ ## Prerequisites
38
+
39
+ - **Node.js** >= 18
40
+ - **scip** CLI — [Install from releases](https://github.com/sourcegraph/scip/releases) (converts index to SQLite)
41
+ - A language-specific SCIP indexer for your project:
42
+
43
+ | Language | Indexer | Install |
44
+ |---|---|---|
45
+ | TypeScript / JavaScript | scip-typescript | `npm install -g @sourcegraph/scip-typescript` |
46
+ | Java / Scala / Kotlin | scip-java | [releases](https://github.com/sourcegraph/scip-java/releases) |
47
+ | Rust | rust-analyzer | Ships with rust-analyzer (`rust-analyzer scip`) |
48
+ | Python | scip-python-plus | `npm install -g scip-python-plus` |
49
+ | Go | scip-go | `go install github.com/sourcegraph/scip-go@latest` |
50
+ | Ruby | scip-ruby | [releases](https://github.com/sourcegraph/scip-ruby/releases) |
51
+ | C / C++ | scip-clang | [releases](https://github.com/sourcegraph/scip-clang/releases) |
52
+ | C# / VB | scip-dotnet | [releases](https://github.com/sourcegraph/scip-dotnet/releases) |
53
+ | Dart | scip-dart | [releases](https://github.com/nicovince/scip-dart/releases) |
54
+ | PHP | scip-php | [releases](https://github.com/nicovince/scip-php/releases) |
55
+
56
+ ## How It Works
57
+
58
+ 1. A SCIP indexer analyzes your source code using the actual compiler/type checker and produces a `index.scip` protobuf file containing every symbol, definition, and reference — fully type-resolved.
59
+ 2. The `scip` CLI converts the protobuf to a SQLite database (`index.db`).
60
+ 3. `scip-query` runs SQL queries against that database to answer questions about your codebase.
61
+
62
+ Because the index comes from the real compiler, results are precise — not grep-based approximations. A reference to `login()` in file A is provably the same `login()` defined in file B, not just a string match.
63
+
64
+ ## Configuration
65
+
66
+ ### Per-project config
67
+
68
+ Run `scip-query init` to generate a `.scipquery.json` in your project root:
69
+
70
+ ```json
71
+ {
72
+ "languages": ["typescript"],
73
+ "watch": {
74
+ "enabled": false,
75
+ "debounceMs": 30000,
76
+ "cooldownMs": 60000
77
+ },
78
+ "indexer": {
79
+ "typescript": {
80
+ "pnpmWorkspaces": true
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ ### Environment variables
87
+
88
+ | Variable | Purpose |
89
+ |---|---|
90
+ | `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory |
91
+ | `SCIP_QUERY_INDEX_DB` | Override the SQLite database path |
92
+ | `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path |
93
+ | `SCIP_QUERY_CACHE_DIR` | Override the cache directory |
94
+
95
+ ### Index storage
96
+
97
+ By default, indexes are stored in `~/.cache/scip-query/projects/<hash>/` (following XDG conventions). This keeps your project directory clean. Override with the `dbPath` field in `.scipquery.json` or the `SCIP_QUERY_CACHE_DIR` environment variable.
98
+
99
+ ### Gitignore integration
100
+
101
+ All query results are filtered through your project's `.gitignore`. Build artifacts (`dist/`, `target/`, `__pycache__/`), dependency directories (`node_modules/`, `vendor/`), and virtual environments (`.venv/`) are automatically excluded. If no `.gitignore` exists, sensible defaults are applied.
102
+
103
+ ---
104
+
105
+ ## Command Reference
106
+
107
+ ### Index Management
108
+
109
+ #### `reindex`
110
+
111
+ Index (or re-index) the codebase. Auto-detects which languages are present, runs the appropriate SCIP indexer, and converts the output to SQLite.
112
+
113
+ ```bash
114
+ scip-query reindex
115
+ scip-query reindex --language typescript
116
+ scip-query reindex --pnpm-workspaces # for pnpm monorepos
117
+ ```
118
+
119
+ **Options:**
120
+ - `-l, --language <lang>` — Index only this language (can repeat)
121
+ - `--pnpm-workspaces` — Enable pnpm workspace support (TypeScript)
122
+
123
+ **When to use:** After significant code changes, after pulling, or before running analysis commands for the first time.
124
+
125
+ ---
126
+
127
+ #### `watch`
128
+
129
+ Watch the project for file changes and automatically reindex in the background. Uses a single-flight model: only one reindex runs at a time, changes during reindex set a dirty flag for one follow-up run.
130
+
131
+ ```bash
132
+ scip-query watch
133
+ scip-query watch --debounce 60000 # wait 60s after last change
134
+ ```
135
+
136
+ **Options:**
137
+ - `--debounce <ms>` — Milliseconds to wait after the last file change before reindexing (default: 30000)
138
+ - `--cooldown <ms>` — Minimum milliseconds between reindex completions (default: 60000)
139
+
140
+ **How it works:** Watches for file changes (respecting `.gitignore`), debounces, runs reindex in a child process writing to a temp file, then atomically swaps the database. Queries against the old index continue working during reindex — no downtime.
141
+
142
+ ---
143
+
144
+ #### `status`
145
+
146
+ Show the current index status: where it's stored, how big it is, when it was built.
147
+
148
+ ```bash
149
+ scip-query status
150
+ ```
151
+
152
+ ---
153
+
154
+ #### `stats`
155
+
156
+ Show index statistics: document count, symbol count, definition count, reference count, database size.
157
+
158
+ ```bash
159
+ scip-query stats
160
+ # Documents: 42
161
+ # Symbols: 1111
162
+ # Definitions: 803
163
+ # References: 2094
164
+ # Index size: 660 KB
165
+ # Last built: 2026-04-10 16:12:58
166
+ ```
167
+
168
+ **Value:** Quick sanity check that your index is healthy and up to date.
169
+
170
+ ---
171
+
172
+ #### `init`
173
+
174
+ Create a `.scipquery.json` config file in the project root with auto-detected languages and default settings.
175
+
176
+ ```bash
177
+ scip-query init
178
+ ```
179
+
180
+ ---
181
+
182
+ ### Navigation
183
+
184
+ These commands help you understand and navigate the codebase — find where things are defined, where they're used, and how files relate to each other.
185
+
186
+ #### `files <pattern>`
187
+
188
+ Find indexed files matching a path pattern.
189
+
190
+ ```bash
191
+ scip-query files auth # all files with "auth" in the path
192
+ scip-query files .service.ts # all service files
193
+ ```
194
+
195
+ **Value:** Quick file discovery without leaving the terminal. Respects gitignore.
196
+
197
+ ---
198
+
199
+ #### `symbols <file>`
200
+
201
+ List all symbols defined in a file with their line ranges and type signatures.
202
+
203
+ ```bash
204
+ scip-query symbols auth.service.ts
205
+ # 1-50 AuthService — class AuthService
206
+ # 5-20 AuthService:login() — login(email: string): Promise<Token>
207
+ # 22-35 AuthService:logout() — logout(): void
208
+ ```
209
+
210
+ **Value:** Instant overview of a file's API surface — like a table of contents with type information. Faster than reading the file.
211
+
212
+ ---
213
+
214
+ #### `methods <className>`
215
+
216
+ List all methods of a class with their line ranges.
217
+
218
+ ```bash
219
+ scip-query methods AuthService
220
+ # 5-20 login
221
+ # 22-35 logout
222
+ ```
223
+
224
+ **Value:** Quick method inventory for a class. Useful when you need to know what a class can do without reading its full source.
225
+
226
+ ---
227
+
228
+ #### `refs <symbol>`
229
+
230
+ Find every file that references a symbol, grouped by file with line numbers.
231
+
232
+ ```bash
233
+ scip-query refs login
234
+ # src/controllers/auth.controller.ts
235
+ # line 15
236
+ # src/__tests__/auth.test.ts
237
+ # line 8
238
+ ```
239
+
240
+ **Value:** "Who uses this?" — the most fundamental code intelligence question. Compiler-resolved, so no false positives from string matches.
241
+
242
+ ---
243
+
244
+ #### `trace <symbol>`
245
+
246
+ Show a symbol's definition (with signature) and every file that references it. Like `refs` but also shows you where the symbol is defined.
247
+
248
+ ```bash
249
+ scip-query trace parseSymbol
250
+ # ═══ DEFINITION ═══
251
+ # src/symbol-parser.ts:35-99 — parseSymbol(raw: string): ScipSymbol | ScipLocalSymbol
252
+ #
253
+ # ═══ REFERENCED BY ═══
254
+ # src/index.ts
255
+ # src/symbol-parser.ts
256
+ ```
257
+
258
+ **Value:** End-to-end symbol investigation. Answers "where is this defined, what's its signature, and who uses it?" in one command.
259
+
260
+ ---
261
+
262
+ #### `outline <file>`
263
+
264
+ Tree-structured view of all symbols in a file, using parent-child nesting when the indexer provides `enclosing_symbol` data.
265
+
266
+ ```bash
267
+ scip-query outline db.ts
268
+ # 0-111 src:db
269
+ # 19-110 src:db:ScipDatabase
270
+ # 24-29 src:db:ScipDatabase:constructor()
271
+ # 32-34 src:db:ScipDatabase:setPathFilter()
272
+ ```
273
+
274
+ **Value:** Visual file structure at a glance — like an IDE's outline panel but in the terminal.
275
+
276
+ ---
277
+
278
+ #### `hierarchy <symbol>`
279
+
280
+ Show a symbol's ancestry chain — from the symbol up through its enclosing scopes (method → class → module → file).
281
+
282
+ ```bash
283
+ scip-query hierarchy login
284
+ # src:auth:AuthService:login()
285
+ # src:auth:AuthService
286
+ ```
287
+
288
+ **Value:** Understand where a symbol lives in the nesting hierarchy. Requires the indexer to populate `enclosing_symbol`.
289
+
290
+ ---
291
+
292
+ #### `members <symbol>`
293
+
294
+ Find all direct children of a symbol (methods, fields, nested types) using the enclosing_symbol relationship.
295
+
296
+ ```bash
297
+ scip-query members AuthService
298
+ # 5-20 [method] login
299
+ # 22-35 [method] logout
300
+ # 37-37 [term] tokenSecret
301
+ ```
302
+
303
+ **Value:** Like `methods` but includes fields, nested types, and anything else directly inside a symbol. Requires `enclosing_symbol` support from the indexer.
304
+
305
+ ---
306
+
307
+ #### `call-graph <symbol>`
308
+
309
+ Show what calls a symbol (incoming) and what the symbol calls (outgoing).
310
+
311
+ ```bash
312
+ scip-query call-graph shortenSymbol
313
+ # Symbol: src:symbol-parser:shortenSymbol()
314
+ #
315
+ # ═══ CALLERS (16) ═══
316
+ # src/queries/dead.ts src:queries:dead
317
+ # src/queries/hotspots.ts src:queries:hotspots
318
+ # ...
319
+ #
320
+ # ═══ CALLEES (0) ═══
321
+ ```
322
+
323
+ **Value:** Understand a function's role in the call chain. High caller count = widely used, be careful changing it. Many callees = complex function, may need decomposition.
324
+
325
+ ---
326
+
327
+ ### Dependency Analysis
328
+
329
+ These commands map how files and modules depend on each other — forward deps, reverse deps, and full module maps.
330
+
331
+ #### `deps <file>`
332
+
333
+ List all internal files that this file depends on (forward dependencies).
334
+
335
+ ```bash
336
+ scip-query deps cli.ts
337
+ # src/config.ts
338
+ # src/db.ts
339
+ # src/queries/index.ts
340
+ # src/reindex/index.ts
341
+ ```
342
+
343
+ **Value:** "What does this file need to work?" Useful before refactoring — tells you what you're coupled to.
344
+
345
+ ---
346
+
347
+ #### `rdeps <file>`
348
+
349
+ List all files that depend on this file (reverse dependencies).
350
+
351
+ ```bash
352
+ scip-query rdeps symbol-parser
353
+ # src/index.ts
354
+ # src/queries/dead.ts
355
+ # src/queries/hotspots.ts
356
+ # ...
357
+ ```
358
+
359
+ **Value:** "Who breaks if I change this?" The blast radius of a modification. High rdeps count = be very careful with changes.
360
+
361
+ ---
362
+
363
+ #### `system <module>`
364
+
365
+ Full module map: all files in the module, all exported symbols, all inbound and outbound dependencies.
366
+
367
+ ```bash
368
+ scip-query system queries
369
+ # ═══ FILES ═══
370
+ # src/queries/dead.ts
371
+ # src/queries/deps.ts
372
+ # ...
373
+ #
374
+ # ═══ EXPORTED SYMBOLS ═══
375
+ # 8-124 dead()
376
+ # 4-23 deps()
377
+ # ...
378
+ #
379
+ # ═══ DEPENDS ON (internal) ═══
380
+ # src/db.ts
381
+ # src/symbol-parser.ts
382
+ #
383
+ # ═══ DEPENDED ON BY ═══
384
+ # src/cli.ts
385
+ # src/index.ts
386
+ ```
387
+
388
+ **Value:** Complete module overview in one command. Shows the module's interface, its internal structure, and its position in the dependency graph.
389
+
390
+ ---
391
+
392
+ #### `surface <module>`
393
+
394
+ What symbols do external consumers actually use from this module? The true public API — not what's exported, but what's actually imported and referenced by other modules.
395
+
396
+ ```bash
397
+ scip-query surface db.ts
398
+ # src/cli.ts → ScipDatabase
399
+ # src/cli.ts → ScipDatabase:close()
400
+ # src/queries/dead.ts → ScipDatabase:all()
401
+ # src/queries/dead.ts → ScipDatabase:isIgnored()
402
+ ```
403
+
404
+ **Value:** Distinguish "exported" from "actually used." If you export 20 symbols but only 5 are referenced externally, the other 15 are candidates for removal or making private.
405
+
406
+ ---
407
+
408
+ #### `imports <file>`
409
+
410
+ What symbols does this file import? Uses SCIP `role=2` (import) mentions.
411
+
412
+ ```bash
413
+ scip-query imports auth.controller.ts
414
+ # AuthService:login() ← src/services/auth.service.ts
415
+ # validateInput() ← src/utils/validation.ts
416
+ ```
417
+
418
+ **Value:** Quick import inventory. Note: depends on the indexer emitting `role=2` — not all do (e.g., `scip-typescript` currently doesn't).
419
+
420
+ ---
421
+
422
+ #### `imported-by <symbol>`
423
+
424
+ Which files import this symbol?
425
+
426
+ ```bash
427
+ scip-query imported-by AuthService
428
+ # src/controllers/auth.controller.ts
429
+ # src/__tests__/auth.test.ts
430
+ ```
431
+
432
+ ---
433
+
434
+ #### `unused-imports <file>`
435
+
436
+ Find imports in a file that are never referenced in the same file — likely unused imports that should be cleaned up.
437
+
438
+ ```bash
439
+ scip-query unused-imports auth.controller.ts
440
+ # formatDate in src/controllers/auth.controller.ts
441
+ # 1 unused import(s)
442
+ ```
443
+
444
+ **Value:** Automated unused import detection. Note: same `role=2` limitation as `imports`.
445
+
446
+ ---
447
+
448
+ ### Code Quality & Dead Code
449
+
450
+ These commands find code that can be removed, consolidated, or cleaned up.
451
+
452
+ #### `dead [scope]`
453
+
454
+ Find dead exports: symbols defined locally with no cross-file references. Distinguishes between "dead code" (not referenced anywhere, even in the same file) and "dead exports" (used locally but never imported by other files).
455
+
456
+ ```bash
457
+ scip-query dead --min-loc 10
458
+ scip-query dead src/utils --skip-barrels --include-members
459
+ ```
460
+
461
+ **Options:**
462
+ - `--min-loc <n>` — Only show symbols >= N lines (default: 1)
463
+ - `--include-tests` — Include test files in results (excluded by default)
464
+ - `--skip-barrels` — Ignore references from barrel re-export files (index.ts)
465
+ - `--include-members` — Include class members (module-level only by default)
466
+
467
+ **Value:** Find code you can delete. The `--skip-barrels` flag is key — without it, symbols re-exported through index.ts appear "referenced" even if no real consumer uses them.
468
+
469
+ ---
470
+
471
+ #### `isolated`
472
+
473
+ Find completely orphaned symbols: defined locally, not referenced by anything (not even in the same file), and not referencing anything external. These are truly disconnected from the codebase graph.
474
+
475
+ ```bash
476
+ scip-query isolated --min-loc 5
477
+ scip-query isolated --scope src/utils
478
+ ```
479
+
480
+ **Options:**
481
+ - `-s, --scope <path>` — Limit to files matching path
482
+ - `--min-loc <n>` — Minimum lines of code (default: 3)
483
+
484
+ **Value:** Stricter than `dead` — these symbols serve no purpose at all. Safe deletion candidates.
485
+
486
+ ---
487
+
488
+ #### `doc-coverage`
489
+
490
+ Check what percentage of symbols have documentation strings. Lists undocumented symbols.
491
+
492
+ ```bash
493
+ scip-query doc-coverage --min-loc 5
494
+ # Documentation coverage: 78%
495
+ # Total symbols: 122
496
+ # Documented: 95
497
+ # Undocumented: 27
498
+ #
499
+ # Undocumented:
500
+ # src/utils/format.ts:15 formatCurrency
501
+ # src/utils/format.ts:28 formatDate
502
+ ```
503
+
504
+ **Options:**
505
+ - `-s, --scope <path>` — Limit to files matching path
506
+ - `--min-loc <n>` — Minimum LOC to consider (default: 3)
507
+ - `-n, --limit <n>` — Max undocumented symbols to show (default: 50)
508
+
509
+ **Value:** Documentation health check. Focus efforts on the undocumented list.
510
+
511
+ ---
512
+
513
+ #### `test-coverage [symbol]`
514
+
515
+ Check if symbols are referenced by test files. Without a symbol argument, shows a summary percentage. With a symbol, shows which specific test files cover it.
516
+
517
+ ```bash
518
+ scip-query test-coverage
519
+ # Test coverage: 45%
520
+ # Total symbols: 95
521
+ # Covered: 43
522
+ # Not covered: 52
523
+
524
+ scip-query test-coverage AuthService
525
+ # [covered] AuthService (src/services/auth.service.ts)
526
+ # ← src/__tests__/auth.test.ts
527
+ # [NOT COVERED] AuthService:logout() (src/services/auth.service.ts)
528
+ ```
529
+
530
+ **Options:**
531
+ - `-s, --scope <path>` — Limit to files matching path
532
+ - `--min-loc <n>` — Minimum LOC for summary mode (default: 3)
533
+
534
+ **Value:** Reference-based test coverage — which symbols does your test suite actually exercise? Not execution coverage, but structural coverage: "do tests at least reference this code?"
535
+
536
+ ---
537
+
538
+ ### Codebase Metrics
539
+
540
+ These commands measure structural properties of the codebase — hotspots, coupling, bottlenecks, fan-in/out.
541
+
542
+ #### `hotspots`
543
+
544
+ Find the most-referenced symbols in the codebase. These are the choke points where changes have the widest blast radius.
545
+
546
+ ```bash
547
+ scip-query hotspots -n 15
548
+ # refs files symbol
549
+ # ──── ───── ──────
550
+ # 39 39 src:types
551
+ # 33 31 src:db:ScipDatabase
552
+ # 27 27 src:db:ScipDatabase:all()
553
+ ```
554
+
555
+ **Options:**
556
+ - `-n, --limit <n>` — Number of results (default: 30)
557
+ - `-s, --scope <path>` — Limit to files matching path
558
+
559
+ **Value:** Identify the symbols where a bug or breaking change would affect the most consumers. Hotspots deserve the most careful review, the best test coverage, and the most stable interfaces.
560
+
561
+ ---
562
+
563
+ #### `fan-in [symbol]`
564
+
565
+ How many distinct files reference a symbol. Without an argument, shows the top N symbols by fan-in across the codebase.
566
+
567
+ ```bash
568
+ scip-query fan-in ScipDatabase
569
+ # 19 files ScipDatabase
570
+ # 16 files ScipDatabase:all()
571
+ # 13 files ScipDatabase:isIgnored()
572
+
573
+ scip-query fan-in -n 10
574
+ # files symbol
575
+ # ───── ──────
576
+ # 31 ScipDatabase
577
+ # 27 ScipDatabase:all()
578
+ ```
579
+
580
+ **Options:**
581
+ - `-n, --limit <n>` — Number of results for top mode (default: 30)
582
+ - `-s, --scope <path>` — Limit to files matching path
583
+
584
+ **Value:** High fan-in = widely depended upon. Changes to high fan-in symbols have large blast radius. These symbols should have stable interfaces and thorough tests.
585
+
586
+ ---
587
+
588
+ #### `fan-out [file]`
589
+
590
+ How many external symbols a file references. Without an argument, shows the top N files by fan-out. High fan-out files are fragile — they depend on many things, so upstream changes are more likely to break them.
591
+
592
+ ```bash
593
+ scip-query fan-out cli.ts
594
+ # 23 symbols src/cli.ts
595
+
596
+ scip-query fan-out -n 10
597
+ # symbols file
598
+ # ─────── ────
599
+ # 68 src/queries/index.ts
600
+ # 23 src/cli.ts
601
+ ```
602
+
603
+ **Options:**
604
+ - `-n, --limit <n>` — Number of results for top mode (default: 30)
605
+ - `-s, --scope <path>` — Limit to files matching path
606
+
607
+ **Value:** Identify files that are tightly coupled to the rest of the codebase. High fan-out files are the first to break when dependencies change.
608
+
609
+ ---
610
+
611
+ #### `bottlenecks`
612
+
613
+ Find coupling hubs: symbols with both high fan-in (many consumers) AND high fan-out (many dependencies). Score = fan-in × fan-out. These are the most dangerous symbols to change — they sit at the intersection of many dependency paths.
614
+
615
+ ```bash
616
+ scip-query bottlenecks -n 10
617
+ # score fan-in fan-out symbol
618
+ # ───── ────── ─────── ──────
619
+ # 136 2 68 src:queries:index
620
+ # 124 31 4 src:db:ScipDatabase
621
+ ```
622
+
623
+ **Options:**
624
+ - `-n, --limit <n>` — Number of results (default: 20)
625
+ - `-s, --scope <path>` — Limit to files matching path
626
+ - `--min-fan-in <n>` — Minimum fan-in (default: 2)
627
+ - `--min-fan-out <n>` — Minimum fan-out (default: 2)
628
+
629
+ **Value:** These are the architectural pressure points. A symbol with fan-in=20 and fan-out=5 is both heavily depended upon and heavily dependent — changes to it are risky in both directions.
630
+
631
+ ---
632
+
633
+ #### `coupling [file1] [file2]`
634
+
635
+ Measure coupling between two specific files (how many symbols they share), or find the most coupled file pairs across the codebase.
636
+
637
+ ```bash
638
+ scip-query coupling db.ts cli.ts
639
+ # db.ts ↔ cli.ts: 4 shared symbols
640
+
641
+ scip-query coupling -n 10
642
+ # shared file1 → file2
643
+ # ────── ─────────────
644
+ # 5 src/db.ts → src/queries/stats.ts
645
+ ```
646
+
647
+ **Options:**
648
+ - `-n, --limit <n>` — Number of results for top mode (default: 20)
649
+ - `-s, --scope <path>` — Limit to files matching path
650
+
651
+ **Value:** Quantify how tightly two files are linked. High coupling between files that shouldn't be related is a design smell. Useful for identifying candidates for interface extraction.
652
+
653
+ ---
654
+
655
+ #### `cycles`
656
+
657
+ Detect circular dependency chains between files. A cycle exists when file A depends on B, B on C, and C on A.
658
+
659
+ ```bash
660
+ scip-query cycles
661
+ # No circular dependencies found.
662
+
663
+ scip-query cycles --scope src/services
664
+ # Cycle 1 (3 files):
665
+ # src/services/auth.ts →
666
+ # src/services/user.ts →
667
+ # src/services/auth.ts (cycle)
668
+ ```
669
+
670
+ **Options:**
671
+ - `-s, --scope <path>` — Limit to files matching path
672
+ - `--max-depth <n>` — Maximum cycle depth (default: 10)
673
+
674
+ **Value:** Circular dependencies make code harder to test, harder to understand, and harder to refactor. This command finds them so you can break the cycles.
675
+
676
+ ---
677
+
678
+ #### `deep-chains`
679
+
680
+ Find the longest transitive dependency chains in the codebase. A chain A → B → C → D means A depends on B, B on C, C on D.
681
+
682
+ ```bash
683
+ scip-query deep-chains -n 5 --min-depth 4
684
+ # Chain 1 (depth 5):
685
+ # → src/cli.ts
686
+ # → src/queries/index.ts
687
+ # → src/queries/surface.ts
688
+ # → src/db.ts
689
+ # → src/types.ts
690
+ ```
691
+
692
+ **Options:**
693
+ - `-n, --limit <n>` — Number of chains to show (default: 10)
694
+ - `-s, --scope <path>` — Limit to files matching path
695
+ - `--min-depth <n>` — Minimum chain depth (default: 3)
696
+
697
+ **Value:** Long dependency chains mean changes at the bottom ripple through many layers. If chains are excessively deep, it may indicate that the architecture needs flattening or that intermediate layers aren't adding value.
698
+
699
+ ---
700
+
701
+ #### `by-kind <kind>`
702
+
703
+ Find symbols by their SCIP symbol kind (class, interface, enum, function, struct, method, etc.).
704
+
705
+ ```bash
706
+ scip-query by-kind class
707
+ scip-query by-kind interface --scope src/types
708
+ scip-query by-kind 68 # kind number for Struct
709
+ ```
710
+
711
+ **Options:**
712
+ - `-s, --scope <path>` — Limit to files matching path
713
+ - `-n, --limit <n>` — Number of results (default: 100)
714
+
715
+ **Value:** Structural inventory — "how many classes do we have?", "where are all the interfaces?", "list every enum." Requires the indexer to populate the `kind` field.
716
+
717
+ ---
718
+
719
+ #### `kind-counts`
720
+
721
+ Show a histogram of symbol kinds in the codebase.
722
+
723
+ ```bash
724
+ scip-query kind-counts
725
+ # count kind
726
+ # ───── ────
727
+ # 45 Class (9)
728
+ # 23 Interface (27)
729
+ # 12 Enum (16)
730
+ ```
731
+
732
+ **Options:**
733
+ - `-s, --scope <path>` — Limit to files matching path
734
+
735
+ **Value:** Architectural overview — what types of symbols make up the codebase? Useful for understanding whether a codebase is class-heavy, function-heavy, interface-driven, etc.
736
+
737
+ ---
738
+
739
+ ### Similarity & Consolidation
740
+
741
+ These commands find duplication, redundancy, and extraction opportunities — the tools for de-bloating a codebase.
742
+
743
+ #### `similar [symbol]`
744
+
745
+ Find functions with similar callee fingerprints using Jaccard similarity. Two functions that call the same set of symbols are likely doing the same work and are candidates for consolidation.
746
+
747
+ Without a symbol argument, finds the top N most similar pairs across the codebase. With a symbol, finds what's most similar to that specific function.
748
+
749
+ ```bash
750
+ scip-query similar --min-similarity 0.5
751
+ # 80% similar:
752
+ # A: by-kind (src/queries/by-kind.ts)
753
+ # B: call-graph (src/queries/call-graph.ts)
754
+ # Shared: ScipDatabase, db.all(), db.get(), db.isIgnored(), shortenSymbol()
755
+
756
+ scip-query similar dead --min-similarity 0.3
757
+ # 64% similar:
758
+ # A: dead (src/queries/dead.ts)
759
+ # B: bottlenecks (src/queries/bottlenecks.ts)
760
+ # Shared callees: db, ScipDatabase, db.all(), db.isIgnored(), shortenSymbol()
761
+ # Only in A: DeadOptions, DeadSummary, DeadSymbolResult
762
+ # Only in B: BottleneckResult
763
+ ```
764
+
765
+ **Options:**
766
+ - `--min-similarity <n>` — Minimum Jaccard similarity 0-1 (default: 0.4)
767
+ - `-n, --limit <n>` — Number of results (default: 20)
768
+ - `-s, --scope <path>` — Limit to files matching path
769
+ - `--min-callees <n>` — Minimum callees to consider a symbol (default: 4)
770
+
771
+ **Value:** Finds "these two functions do basically the same thing" at scale. The shared callee list shows exactly what's duplicated. The unique callees show where they diverge — that's the parameterization point for a consolidated version.
772
+
773
+ ---
774
+
775
+ #### `similar-files [file]`
776
+
777
+ Find files with similar dependency profiles using Jaccard similarity on their dependency sets. Files that import the same modules are structurally doing similar work.
778
+
779
+ ```bash
780
+ scip-query similar-files --min-similarity 0.7
781
+ # 100% similar:
782
+ # src/queries/symbols.ts
783
+ # src/queries/system.ts
784
+ # Shared deps (4): db.ts, types.ts, symbol-parser.ts, clean-signature.ts
785
+
786
+ scip-query similar-files auth.controller.ts
787
+ ```
788
+
789
+ **Options:**
790
+ - `--min-similarity <n>` — Minimum Jaccard similarity 0-1 (default: 0.5)
791
+ - `-n, --limit <n>` — Number of results (default: 20)
792
+ - `-s, --scope <path>` — Limit to files matching path
793
+ - `--min-deps <n>` — Minimum dependencies to consider (default: 3)
794
+
795
+ **Value:** Finds copy-paste file variants and structurally redundant modules. When two files have 90%+ dependency overlap, they're likely doing similar jobs and should share code or be merged.
796
+
797
+ ---
798
+
799
+ #### `similar-chains`
800
+
801
+ Find end-to-end dependency flows through the codebase that are structurally similar but diverge at a few points. Uses edit distance on the file-node sequences.
802
+
803
+ ```bash
804
+ scip-query similar-chains --min-similarity 0.5
805
+ # ── Chain pair 1 (67% similar, 1 divergence point) ──
806
+ # Chain A: auth.controller.ts → auth.service.ts → user.repo.ts
807
+ # Chain B: org.controller.ts → org.service.ts → user.repo.ts
808
+ # Common suffix: user.repo.ts
809
+ # Divergence points (consolidation targets):
810
+ # [0] auth.controller.ts ↔ org.controller.ts
811
+ # [1] auth.service.ts ↔ org.service.ts
812
+ ```
813
+
814
+ **Options:**
815
+ - `--min-similarity <n>` — Minimum chain similarity 0-1 (default: 0.5)
816
+ - `-n, --limit <n>` — Number of results (default: 15)
817
+ - `-s, --scope <path>` — Limit to files matching path
818
+ - `--min-length <n>` — Minimum chain length (default: 3)
819
+ - `--max-length <n>` — Maximum chain length (default: 8)
820
+
821
+ **Value:** This is the most powerful consolidation finder. It detects "you have two parallel end-to-end mechanisms doing the same thing through different code paths." The divergence points are exactly where to extract a shared abstraction. Unlike function-level similarity, this catches architectural-level duplication.
822
+
823
+ ---
824
+
825
+ #### `extract-candidates`
826
+
827
+ Find large functions with natural extraction seams — isolated groups of callees that form distinct clusters within a single function. When a function calls symbols A, B, C together and separately calls D, E, F, that's two potential extracted functions.
828
+
829
+ ```bash
830
+ scip-query extract-candidates --min-loc 20 --min-callees 6
831
+ # src/services/auth.ts:10-85 processAuth (75 LOC, 12 callees)
832
+ # Cluster 1 (92% isolated, 4 callees):
833
+ # validateToken, parseJwt, checkExpiry, refreshToken
834
+ # Cluster 2 (88% isolated, 3 callees):
835
+ # formatUser, enrichProfile, cacheResult
836
+ ```
837
+
838
+ **Options:**
839
+ - `-s, --scope <path>` — Limit to files matching path
840
+ - `--min-loc <n>` — Minimum function LOC (default: 10)
841
+ - `--min-callees <n>` — Minimum callees to analyze (default: 6)
842
+ - `-n, --limit <n>` — Number of results (default: 20)
843
+
844
+ **Value:** Identifies concrete extraction opportunities within large functions. Each cluster is a group of callees that are used together but independently from the rest of the function — a natural candidate for "Extract Method" refactoring. The isolation score tells you how cleanly the extraction would separate.
845
+
846
+ ---
847
+
848
+ ### Impact & Planning
849
+
850
+ #### `affected <symbol>`
851
+
852
+ Full transitive closure of symbols that could break if this symbol changes. BFS through the mention graph at configurable depth.
853
+
854
+ ```bash
855
+ scip-query affected login --max-depth 3
856
+ # ── Depth 1 ──
857
+ # src/controllers/auth.controller.ts handleLogin
858
+ # src/__tests__/auth.test.ts authTests
859
+ #
860
+ # ── Depth 2 ──
861
+ # src/routes/index.ts routes
862
+ ```
863
+
864
+ **Options:**
865
+ - `--max-depth <n>` — Maximum traversal depth (default: 5)
866
+ - `-s, --scope <path>` — Limit to files matching path
867
+
868
+ **Value:** "If I change this, what's the full blast wave?" Goes beyond direct `rdeps` to show consumers-of-consumers.
869
+
870
+ ---
871
+
872
+ #### `change-surface <file>`
873
+
874
+ Pre-change briefing for a file: every exported symbol, consumer count, test coverage, and risk level.
875
+
876
+ ```bash
877
+ scip-query change-surface auth.service.ts
878
+ # File: src/services/auth.service.ts
879
+ # Test coverage: 60% | External consumers: 45
880
+ #
881
+ # 1-50 AuthService [12 consumers] (2 test files) * medium risk *
882
+ # 5-20 login() [8 consumers] (1 test file)
883
+ # 22-35 logout() [3 consumers] (no tests) *** HIGH RISK ***
884
+ ```
885
+
886
+ **Value:** One command before modifying any file. Shows what's exported, who uses it, what's tested, and what's dangerous.
887
+
888
+ ---
889
+
890
+ #### `diff-impact`
891
+
892
+ Compute affected symbols from the current git diff.
893
+
894
+ ```bash
895
+ scip-query diff-impact
896
+ scip-query diff-impact --base main
897
+ # Changed files: 3
898
+ # Changed symbols: 12
899
+ # Affected consumer files: 28
900
+ # Test coverage: 67%
901
+ ```
902
+
903
+ **Options:**
904
+ - `--base <ref>` — Git ref to diff against (default: HEAD)
905
+
906
+ **Value:** Run before committing. Shows everything your changes affect, which consumer files are impacted, and where test gaps exist.
907
+
908
+ ---
909
+
910
+ ### De-bloating
911
+
912
+ #### `drift [module]`
913
+
914
+ Detect files that deviate from their directory's typical dependency pattern.
915
+
916
+ ```bash
917
+ scip-query drift --min-deviation 30
918
+ # src/services/legacy-auth.ts (65% deviation from src/services)
919
+ # Missing expected: validator.ts, logger.ts
920
+ # Unexpected: raw-sql.ts, deprecated-crypto.ts
921
+ ```
922
+
923
+ **Options:**
924
+ - `--min-deviation <n>` — Minimum deviation % to report (default: 30)
925
+
926
+ **Value:** Finds files that don't follow their neighbors' conventions. The outliers are either legacy code needing migration or intentional exceptions needing documentation.
927
+
928
+ ---
929
+
930
+ #### `wrapper-candidates`
931
+
932
+ Find symbols only called by one consumer — potential premature abstractions.
933
+
934
+ ```bash
935
+ scip-query wrapper-candidates --max-loc 15
936
+ # src/utils/format.ts:10-18 formatCurrency (8 LOC)
937
+ # Only called by: formatInvoice (fan-in: 12)
938
+ ```
939
+
940
+ **Options:**
941
+ - `-s, --scope <path>` — Limit to files matching path
942
+ - `--max-loc <n>` — Maximum LOC (default: 15)
943
+ - `-n, --limit <n>` — Number of results (default: 30)
944
+
945
+ **Value:** If a function is only called by one other function, it might be inlineable. The smaller it is, the stronger the signal.
946
+
947
+ ---
948
+
949
+ #### `passthrough-candidates`
950
+
951
+ Find functions that forward to exactly one callee — pure indirection.
952
+
953
+ ```bash
954
+ scip-query passthrough-candidates
955
+ # src/services/user.ts:5-10 getUser (5 LOC)
956
+ # Forwards to: userRepo.findById (src/repos/user.repo.ts)
957
+ ```
958
+
959
+ **Options:**
960
+ - `-s, --scope <path>` — Limit to files matching path
961
+ - `--max-loc <n>` — Maximum LOC (default: 15)
962
+ - `-n, --limit <n>` — Number of results (default: 30)
963
+
964
+ **Value:** Functions that just call one other function without adding logic. Either inline them or verify they serve a purpose (testing boundary, dependency inversion).
965
+
966
+ ---
967
+
968
+ #### `stale-abstractions`
969
+
970
+ Find types, interfaces, and classes with 0-1 cross-file consumers.
971
+
972
+ ```bash
973
+ scip-query stale-abstractions --min-loc 5
974
+ # src/types/deprecated.ts:1-25 OldUserType (25 LOC, unused)
975
+ # src/interfaces/single.ts:1-15 ISingleUse (15 LOC, 1 consumer)
976
+ ```
977
+
978
+ **Options:**
979
+ - `-s, --scope <path>` — Limit to files matching path
980
+ - `--min-loc <n>` — Minimum LOC (default: 3)
981
+ - `-n, --limit <n>` — Number of results (default: 30)
982
+
983
+ **Value:** An interface with one implementation isn't an abstraction — it's indirection. Finds over-engineering.
984
+
985
+ ---
986
+
987
+ #### `complexity-hotspots`
988
+
989
+ Composite complexity score per symbol: LOC x fan-in x fan-out.
990
+
991
+ ```bash
992
+ scip-query complexity-hotspots -n 10
993
+ # score LOC fan-in fan-out callees symbol
994
+ # ───── ──── ────── ─────── ─────── ──────
995
+ # 101.7 541 47 0 16 types
996
+ # 31.3 279 28 5 33 symbol-parser
997
+ ```
998
+
999
+ **Options:**
1000
+ - `-s, --scope <path>` — Limit to files matching path
1001
+ - `--min-loc <n>` — Minimum LOC (default: 10)
1002
+ - `-n, --limit <n>` — Number of results (default: 20)
1003
+
1004
+ **Value:** The symbols most likely to contain bugs and be hardest to modify. High score = high LOC + many consumers + many dependencies.
1005
+
1006
+ ---
1007
+
1008
+ ### Composite Reports
1009
+
1010
+ #### `health`
1011
+
1012
+ Single command that runs all analyses and produces a prioritized action list with a health score.
1013
+
1014
+ ```bash
1015
+ scip-query health
1016
+ # Codebase Health Score: 72/100
1017
+ # 54 files | 1501 symbols | 900 KB
1018
+ #
1019
+ # Findings:
1020
+ # Dead code: 12 symbols (340 LOC)
1021
+ # Similar pairs: 8
1022
+ # Stale abstractions: 5
1023
+ #
1024
+ # Prioritized Actions:
1025
+ # 1. [low effort / high impact] 12 symbols with zero references — safe to delete (~340 LOC)
1026
+ # 2. [low effort / medium impact] 5 types with 0-1 consumers — premature abstraction
1027
+ # 3. [medium effort / medium impact] 8 pairs with >60% callee overlap — consolidation candidates
1028
+
1029
+ scip-query health --json # JSON output for programmatic use
1030
+ ```
1031
+
1032
+ **Options:**
1033
+ - `-s, --scope <path>` — Limit to files matching path
1034
+ - `--json` — Output as JSON
1035
+
1036
+ **Value:** The one command to rule them all. Runs every cleanup analysis, scores the codebase, and tells you exactly what to fix and in what order.
1037
+
1038
+ ---
1039
+
1040
+ #### `convergence <symbol1> <symbol2>`
1041
+
1042
+ Given two similar functions (from `similar`), show what a consolidated version would look like.
1043
+
1044
+ ```bash
1045
+ scip-query convergence bottlenecks hotspots
1046
+ # 82% callee overlap
1047
+ #
1048
+ # A: bottlenecks (src/queries/bottlenecks.ts, 68 LOC)
1049
+ # B: hotspots (src/queries/hotspots.ts, 54 LOC)
1050
+ #
1051
+ # Shared callees (9): ScipDatabase, db.all(), db.isIgnored(), ...
1052
+ # Unique to A (1): BottleneckResult
1053
+ # Unique to B (1): HotspotResult
1054
+ #
1055
+ # Strategy: Create a shared function with the 9 common callees.
1056
+ # Pass the 2 divergent callees as parameters or strategy callbacks.
1057
+ ```
1058
+
1059
+ **Value:** Turns "these two functions are similar" into a concrete refactoring prescription.
1060
+
1061
+ ---
1062
+
1063
+ ### Source & Analysis
1064
+
1065
+ #### `code <symbol>`
1066
+
1067
+ Read the source code for a symbol, bounded to its definition range.
1068
+
1069
+ ```bash
1070
+ scip-query code shortenSymbol
1071
+ scip-query code shortenSymbol -C 5 # 5 extra lines of context
1072
+ ```
1073
+
1074
+ **Options:**
1075
+ - `-C, --context <n>` — Extra lines above/below the definition (default: 0)
1076
+
1077
+ **Value:** Read source without leaving the terminal. Language-agnostic — just reads the file at the line range from the index.
1078
+
1079
+ ---
1080
+
1081
+ #### `complexity <symbol>`
1082
+
1083
+ Per-symbol complexity analysis: source-level branch counting + index-level metrics.
1084
+
1085
+ ```bash
1086
+ scip-query complexity login
1087
+ # LOC: 41
1088
+ # Branches: 8
1089
+ # Cyclomatic estimate: 9
1090
+ # Callees: 5
1091
+ # Fan-in: 12
1092
+ # Fan-out: 3
1093
+ ```
1094
+
1095
+ **Value:** Combines source-level analysis (branch counting via language-aware regex) with graph-level metrics (fan-in, fan-out, callee count) for a complete complexity picture.
1096
+
1097
+ ---
1098
+
1099
+ #### `dataflow <symbol>`
1100
+
1101
+ Reference-level dataflow: where data around a symbol comes from and where it goes.
1102
+
1103
+ ```bash
1104
+ scip-query dataflow login
1105
+ # ═══ DEFINED AT ═══
1106
+ # src/auth.service.ts:5
1107
+ # ═══ USED AT ═══
1108
+ # src/auth.controller.ts:15 in handleAuth
1109
+ # ═══ PRODUCERS (feeds into this) ═══
1110
+ # validateInput, formatName
1111
+ # ═══ CONSUMERS (this feeds into) ═══
1112
+ # sendEmail, logAudit
1113
+ ```
1114
+
1115
+ **Value:** Shows the data flow context: what other symbols are referenced alongside this one, what feeds in, what consumes it.
1116
+
1117
+ ---
1118
+
1119
+ #### `slice <symbol>`
1120
+
1121
+ Reference-level program slicing: what affects a symbol (backward) or what it affects (forward).
1122
+
1123
+ ```bash
1124
+ scip-query slice login # backward: what feeds in
1125
+ scip-query slice login --forward # forward: what this feeds into
1126
+ ```
1127
+
1128
+ **Options:**
1129
+ - `--forward` — Forward slice instead of backward (default: backward)
1130
+
1131
+ **Value:** Backward slice shows inputs/dependencies. Forward slice shows outputs/effects. Useful for tracing data flow through error handling and concurrency paths.
1132
+
1133
+ ---
1134
+
1135
+ ### Additional Cleanup
1136
+
1137
+ #### `redundant-reexports`
1138
+
1139
+ Find barrel file re-exports that nobody imports through.
1140
+
1141
+ ```bash
1142
+ scip-query redundant-reexports
1143
+ # src/index.ts
1144
+ # resolveCacheDir() (from src/config.ts)
1145
+ # barrel: 0 consumer(s) | direct: 0 consumer(s)
1146
+ ```
1147
+
1148
+ **Options:**
1149
+ - `-s, --scope <path>` — Limit to files matching path
1150
+ - `-n, --limit <n>` — Number of results (default: 30)
1151
+
1152
+ **Value:** Finds dead entries in barrel files. Note: TypeScript namespace imports (`import * as`) resolve through barrels transparently, so the command is most effective on codebases using named imports.
1153
+
1154
+ ---
1155
+
1156
+ #### `similar-signatures`
1157
+
1158
+ Find functions with near-identical type signatures (same parameter types and return type).
1159
+
1160
+ ```bash
1161
+ scip-query similar-signatures --min-loc 5
1162
+ # Signature: (email: string): Promise<Token> (2 functions)
1163
+ # src/auth.ts:5-20 login (15 LOC)
1164
+ # src/auth.ts:22-37 signup (15 LOC)
1165
+ ```
1166
+
1167
+ **Options:**
1168
+ - `-s, --scope <path>` — Limit to files matching path
1169
+ - `--min-loc <n>` — Minimum LOC per function (default: 3)
1170
+ - `-n, --limit <n>` — Number of groups (default: 20)
1171
+
1172
+ **Value:** Different signal from callee similarity — catches "same interface, different implementation" even when the internal logic differs completely.
1173
+
1174
+ ---
1175
+
1176
+ ## Programmatic API
1177
+
1178
+ All 50 commands are available as TypeScript functions:
1179
+
1180
+ ```typescript
1181
+ import {
1182
+ ScipDatabase, createGitignoreFilter,
1183
+ health, affected, changeSurface, diffImpact,
1184
+ hotspots, similar, dead, convergence,
1185
+ } from 'scip-query';
1186
+
1187
+ const filter = createGitignoreFilter('/path/to/project');
1188
+ const db = new ScipDatabase({
1189
+ dbPath: '/path/to/index.db',
1190
+ indexPath: '/path/to/index.scip',
1191
+ projectRoot: '/path/to/project',
1192
+ }, filter);
1193
+
1194
+ // Full health report
1195
+ const report = health(db);
1196
+ console.log(`Score: ${report.score}/100`);
1197
+ console.log(`Actions: ${report.actions.length}`);
1198
+
1199
+ // Impact analysis
1200
+ const blast = affected(db, 'login', { maxDepth: 3 });
1201
+ const brief = changeSurface(db, 'auth.service.ts');
1202
+ const impact = diffImpact(db, { base: 'main' });
1203
+
1204
+ // Consolidation
1205
+ const pairs = similar(db, 'myFunction', { minSimilarity: 0.5 });
1206
+ const recipe = convergence(db, 'funcA', 'funcB');
1207
+
1208
+ db.close();
1209
+ ```
1210
+
1211
+ ## License
1212
+
1213
+ Apache-2.0