scip-query 0.7.1 → 0.8.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.
- package/README.md +171 -1132
- package/dist/augment-vue-worker.js +1 -1
- package/dist/{chunk-NSTZMBAB.js → chunk-2EC4JTHC.js} +2 -2
- package/dist/{chunk-ZXFTC5ET.js → chunk-46ILZVMX.js} +2 -2
- package/dist/chunk-4A4JFNWG.js +2 -0
- package/dist/{chunk-GAQGJ52J.js → chunk-4B7YLRXX.js} +2 -2
- package/dist/chunk-64UY7VTR.js +63 -0
- package/dist/chunk-66ORT3LS.js +2 -0
- package/dist/{chunk-QPRIYXH4.js → chunk-6G76D2YM.js} +2 -2
- package/dist/{chunk-VUBQBW7H.js → chunk-6P5W4U6G.js} +2 -2
- package/dist/chunk-6ZFKI5EP.js +40 -0
- package/dist/{chunk-ZNUPGRPR.js → chunk-7I6KNKE3.js} +2 -2
- package/dist/{chunk-23YIGCYF.js → chunk-7TYJD45F.js} +5 -5
- package/dist/chunk-7UZWNW4E.js +2 -0
- package/dist/{chunk-4STLJYHI.js → chunk-AGW2MVIO.js} +2 -2
- package/dist/chunk-APLCSDXL.js +4 -0
- package/dist/chunk-BCFED24F.js +2 -0
- package/dist/chunk-CVRXOP6M.js +3 -0
- package/dist/chunk-D43L5PQF.js +2 -0
- package/dist/chunk-DJTJ3DLZ.js +7 -0
- package/dist/chunk-EAU4RDFG.js +2 -0
- package/dist/{chunk-BI4F6GXI.js → chunk-EKP7XJ6L.js} +2 -2
- package/dist/{chunk-33SSUPCB.js → chunk-EM2PPDN7.js} +2 -2
- package/dist/{chunk-ROOHENEP.js → chunk-FIPE5AQT.js} +2 -2
- package/dist/chunk-FTBT4RP2.js +7 -0
- package/dist/{chunk-WPLKHAH7.js → chunk-GD7XRHSV.js} +2 -2
- package/dist/{chunk-WJQY2LGT.js → chunk-GMEBYEMU.js} +2 -2
- package/dist/chunk-GTZAU7OL.js +2 -0
- package/dist/chunk-HVGNOUYP.js +2 -0
- package/dist/chunk-HVXIXDLV.js +2 -0
- package/dist/{chunk-KJ3ZJIE5.js → chunk-I7OTKWNY.js} +2 -2
- package/dist/{chunk-2JEFS2YJ.js → chunk-JAMU6FLN.js} +2 -2
- package/dist/chunk-JTCEWV7Q.js +2 -0
- package/dist/chunk-K4Z3FCUJ.js +6 -0
- package/dist/{chunk-FD37DBTD.js → chunk-K6YIGVL7.js} +2 -2
- package/dist/chunk-MKE7SEEX.js +2 -0
- package/dist/chunk-N5D5ZCBW.js +7 -0
- package/dist/{chunk-ROZNBWIF.js → chunk-NGLRXEWN.js} +2 -2
- package/dist/{chunk-J6Z5YKGQ.js → chunk-NK7TQQG4.js} +2 -2
- package/dist/chunk-NOVKLH2F.js +2 -0
- package/dist/chunk-OIMM7KMI.js +2 -0
- package/dist/chunk-OQSV6OS2.js +2 -0
- package/dist/chunk-PBGTMPJ7.js +2 -0
- package/dist/{chunk-ARBZM2NF.js → chunk-PCMVXWDC.js} +4 -4
- package/dist/{chunk-U75WH4XG.js → chunk-PE4EJOLN.js} +2 -2
- package/dist/chunk-PLFYFZX3.js +2 -0
- package/dist/{chunk-A2AVLALL.js → chunk-QYQXPPDI.js} +2 -2
- package/dist/{chunk-3OUC276S.js → chunk-RCRK4E7E.js} +2 -2
- package/dist/chunk-RIXOMSOR.js +20 -0
- package/dist/chunk-SB6I6O3P.js +2 -0
- package/dist/{chunk-KNA6Z7JB.js → chunk-SDGCKEB7.js} +2 -2
- package/dist/chunk-SLOIQKY7.js +2 -0
- package/dist/chunk-SOGLYIJ4.js +62 -0
- package/dist/chunk-SSINY7HL.js +4 -0
- package/dist/{chunk-563HLCDW.js → chunk-TFO4OMJZ.js} +2 -2
- package/dist/chunk-TH4JVC34.js +71 -0
- package/dist/chunk-TQTVM27C.js +6 -0
- package/dist/{chunk-LDV2B7ET.js → chunk-TR5AU6A5.js} +2 -2
- package/dist/{chunk-WODJHE6Z.js → chunk-UQE3DSXY.js} +2 -2
- package/dist/{chunk-72JOIFXL.js → chunk-UUDYI3FF.js} +2 -2
- package/dist/chunk-VDZL45XI.js +2 -0
- package/dist/{chunk-QWJBIBE6.js → chunk-VN6B6HFB.js} +2 -2
- package/dist/{chunk-DFK54IRN.js → chunk-WC43FMAB.js} +2 -2
- package/dist/chunk-WEJYUS5O.js +2 -0
- package/dist/chunk-WQFOZIID.js +4 -0
- package/dist/chunk-XBFLIGWU.js +3 -0
- package/dist/chunk-XSZ5NC4O.js +2 -0
- package/dist/{chunk-2IYEIFPP.js → chunk-Z2AJQ7VA.js} +2 -2
- package/dist/chunk-ZIIQ55VK.js +2 -0
- package/dist/chunk-ZJ737ZMD.js +2 -0
- package/dist/cli.js +171 -174
- package/dist/health-C6r2VgpA.d.ts +234 -0
- package/dist/index.d.ts +16 -30
- package/dist/index.js +1 -1
- package/dist/postinstall.js +4 -4
- package/dist/queries/affected.js +1 -1
- package/dist/queries/bottlenecks.js +1 -1
- package/dist/queries/by-kind.js +1 -1
- package/dist/queries/call-graph.js +1 -1
- package/dist/queries/change-surface.js +1 -1
- package/dist/queries/cleanup-plan.d.ts +66 -0
- package/dist/queries/cleanup-plan.js +2 -0
- package/dist/queries/co-change.d.ts +42 -0
- package/dist/queries/co-change.js +2 -0
- package/dist/queries/code.js +1 -1
- package/dist/queries/complexity-hotspots.d.ts +1 -1
- package/dist/queries/complexity-hotspots.js +1 -1
- package/dist/queries/complexity.js +1 -1
- package/dist/queries/convergence.js +1 -1
- package/dist/queries/coupling.js +1 -1
- package/dist/queries/cycles.js +1 -1
- package/dist/queries/dataflow.js +1 -1
- package/dist/queries/dead.js +1 -1
- package/dist/queries/deep-chains.js +1 -1
- package/dist/queries/deps.js +1 -1
- package/dist/queries/diff-gate.d.ts +52 -0
- package/dist/queries/diff-gate.js +2 -0
- package/dist/queries/diff-impact.js +1 -1
- package/dist/queries/doc-drift.d.ts +69 -0
- package/dist/queries/doc-drift.js +2 -0
- package/dist/queries/drift.js +1 -1
- package/dist/queries/extract-candidates.js +1 -1
- package/dist/queries/fan.js +1 -1
- package/dist/queries/health.d.ts +1 -1
- package/dist/queries/health.js +1 -1
- package/dist/queries/hierarchy.js +1 -1
- package/dist/queries/hotspots.js +1 -1
- package/dist/queries/imports.js +1 -1
- package/dist/queries/index.d.ts +38 -2
- package/dist/queries/index.js +1 -1
- package/dist/queries/isolated.js +1 -1
- package/dist/queries/members.js +1 -1
- package/dist/queries/methods.js +1 -1
- package/dist/queries/outline.d.ts +1 -0
- package/dist/queries/outline.js +1 -1
- package/dist/queries/passthrough-candidates.js +1 -1
- package/dist/queries/plan-context.d.ts +65 -0
- package/dist/queries/plan-context.js +2 -0
- package/dist/queries/recent-duplicates.d.ts +48 -0
- package/dist/queries/recent-duplicates.js +2 -0
- package/dist/queries/redundant-reexports.js +1 -1
- package/dist/queries/refs.js +1 -1
- package/dist/queries/self-audit.d.ts +58 -0
- package/dist/queries/self-audit.js +2 -0
- package/dist/queries/similar-chains.js +1 -1
- package/dist/queries/similar-files.d.ts +6 -0
- package/dist/queries/similar-files.js +1 -1
- package/dist/queries/similar-signatures.js +1 -1
- package/dist/queries/similar.js +1 -1
- package/dist/queries/slice.js +1 -1
- package/dist/queries/stale-abstractions.js +1 -1
- package/dist/queries/surface.js +1 -1
- package/dist/queries/symbols.js +1 -1
- package/dist/queries/system.js +1 -1
- package/dist/queries/trace.js +1 -1
- package/dist/queries/unused-params.d.ts +38 -0
- package/dist/queries/unused-params.js +2 -0
- package/dist/queries/wrapper-candidates.js +1 -1
- package/dist/reindex-worker.js +1 -1
- package/dist/reindex.js +16 -16
- package/dist/runtime.d.ts +3 -2
- package/dist/runtime.js +2 -2
- package/package.json +34 -1
- package/skills/concrete-plan/SKILL.md +37 -7
- package/skills/scip-ai-cleanup/SKILL.md +145 -0
- package/skills/scip-debloat/SKILL.md +37 -7
- package/skills/scip-explore/SKILL.md +22 -9
- package/skills/scip-language-playbook/SKILL.md +4 -4
- package/skills/scip-maintainability/SKILL.md +264 -0
- package/skills/scip-verify/SKILL.md +2 -2
- package/dist/chunk-3GNFUVFA.js +0 -2
- package/dist/chunk-5TT47UMX.js +0 -44
- package/dist/chunk-6H2XIIPY.js +0 -71
- package/dist/chunk-7H4RJ4MC.js +0 -2
- package/dist/chunk-7O4MJYIW.js +0 -63
- package/dist/chunk-7OX2O53H.js +0 -62
- package/dist/chunk-BOVNTAKQ.js +0 -3
- package/dist/chunk-CKIO6SVS.js +0 -2
- package/dist/chunk-D6Z67MZL.js +0 -2
- package/dist/chunk-FOQQDXE7.js +0 -2
- package/dist/chunk-IODTPF5H.js +0 -20
- package/dist/chunk-JB4PUN5S.js +0 -40
- package/dist/chunk-JTXKS5GK.js +0 -3
- package/dist/chunk-KJ6CW6EK.js +0 -2
- package/dist/chunk-MDAYGS6T.js +0 -2
- package/dist/chunk-NHDPYW7O.js +0 -2
- package/dist/chunk-NKJKI6SE.js +0 -2
- package/dist/chunk-NYEMZHUC.js +0 -6
- package/dist/chunk-OHEIZWIA.js +0 -4
- package/dist/chunk-QAEDNTY7.js +0 -2
- package/dist/chunk-QE6MGGUY.js +0 -2
- package/dist/chunk-RCJEFQOK.js +0 -4
- package/dist/chunk-TGK5DFBJ.js +0 -2
- package/dist/chunk-TRNAQABL.js +0 -7
- package/dist/chunk-V53J46BX.js +0 -2
- package/dist/chunk-XO6R3X5J.js +0 -2
- package/dist/chunk-YSZNAG4G.js +0 -2
- package/dist/health-x7B4Xu_6.d.ts +0 -119
package/README.md
CHANGED
|
@@ -1,1228 +1,267 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/scip-query-logo.png" alt="scip-query logo" width="120">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">scip-query</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Structural code intelligence for AI agents and engineers.</strong>
|
|
9
|
+
</p>
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
<p align="center">
|
|
12
|
+
Ask compiler-backed questions about how a codebase is wired together, find what's rotting, and delete it with a compiler proof in hand.
|
|
13
|
+
</p>
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
<p align="center">
|
|
16
|
+
<a href="https://www.npmjs.com/package/scip-query"><img alt="npm version" src="https://img.shields.io/npm/v/scip-query.svg"></a>
|
|
17
|
+
<a href="https://www.npmjs.com/package/scip-query"><img alt="npm downloads" src="https://img.shields.io/npm/dm/scip-query.svg"></a>
|
|
18
|
+
<a href="package.json"><img alt="Node version" src="https://img.shields.io/node/v/scip-query.svg"></a>
|
|
19
|
+
<a href="https://www.apache.org/licenses/LICENSE-2.0"><img alt="License" src="https://img.shields.io/npm/l/scip-query.svg"></a>
|
|
20
|
+
</p>
|
|
10
21
|
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- Where is the architecture drifting, duplicating work, or hiding complexity?
|
|
22
|
+
<p align="center">
|
|
23
|
+
<a href="https://www.npmjs.com/package/scip-query"><img alt="Install from npm" src="https://img.shields.io/badge/install-npm-cb3837?style=for-the-badge&logo=npm&logoColor=white"></a>
|
|
24
|
+
<a href="docs/AGENT_GUIDE.md"><img alt="Agent guide" src="https://img.shields.io/badge/agent-guide-2563eb?style=for-the-badge"></a>
|
|
25
|
+
<a href="docs/COMMAND_REFERENCE.md"><img alt="Command reference" src="https://img.shields.io/badge/command-reference-111827?style=for-the-badge"></a>
|
|
26
|
+
</p>
|
|
17
27
|
|
|
18
|
-
|
|
28
|
+
`scip-query` answers precise questions about how a codebase is wired together — where a symbol is defined, who references it, what calls it, what breaks if it changes — and turns those answers into something rarer: **cleanup you can trust**. Findings are ranked by evidence quality, validated against your repo's own git history, and (for deletions) proven safe by your own compiler before you touch anything.
|
|
19
29
|
|
|
20
|
-
|
|
30
|
+
Works with every language that has a [SCIP](https://github.com/sourcegraph/scip) indexer: TypeScript, JavaScript, Vue, Java, Scala, Kotlin, Rust, Python, Ruby, Go, C/C++, C#, Visual Basic, Dart, PHP.
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
- **Change planning.** Use `affected`, `change-surface`, and `diff-impact` to identify downstream consumers before and after a change.
|
|
24
|
-
- **Architecture visibility.** Use `deps`, `rdeps`, `system`, `surface`, `coupling`, `cycles`, and `deep-chains` to see how modules actually relate.
|
|
25
|
-
- **Codebase cleanup.** Use `dead`, `stale-abstractions`, `wrapper-candidates`, `passthrough-candidates`, `similar`, `similar-signatures`, `extract-candidates`, and `drift` to find removal or consolidation opportunities.
|
|
26
|
-
- **Health reporting.** Use `health` to aggregate cleanup signals into one prioritized report instead of running dozens of commands by hand.
|
|
27
|
-
- **Agent workflows.** Install the bundled Codex/Claude skills so agents can explore, plan, de-bloat, and verify changes with a consistent command vocabulary.
|
|
28
|
-
|
|
29
|
-
## Accuracy Model
|
|
30
|
-
|
|
31
|
-
A SCIP index is a database-shaped record of code facts produced by language-aware indexers: the source files they read, the symbols they define, and the references they resolve. Because these facts come from compilers, type checkers, or language servers, direct definition and reference queries are much stronger evidence than text search.
|
|
32
|
-
|
|
33
|
-
`scip-query` separates three kinds of evidence:
|
|
34
|
-
|
|
35
|
-
- **Compiler-backed facts** come from the SCIP database. Commands like `symbols`, `refs`, `trace`, `deps`, `rdeps`, `surface`, and most symbol-level counts start here.
|
|
36
|
-
- **Semantic augmentation** adds language-specific checks when available. TypeScript projects use `ts-morph` to verify references, import usage, callers, callees, and signatures when SCIP alone is incomplete.
|
|
37
|
-
- **Source-backed heuristics** use parsed source text or ASTs to keep higher-level cleanup commands useful when an indexer omits call-site details. These findings are designed as investigation leads, not blind deletion instructions.
|
|
38
|
-
|
|
39
|
-
The goal is not to replace compiler facts with regexes. The goal is to use the strongest available evidence first, fall back only when needed, and keep cleanup commands conservative enough that speed does not trade away accuracy.
|
|
40
|
-
|
|
41
|
-
## Workflows
|
|
42
|
-
|
|
43
|
-
For goal-oriented usage guides (not just command reference), see **[Agent Guide](docs/AGENT_GUIDE.md)**:
|
|
44
|
-
|
|
45
|
-
- **[Understand a system](docs/AGENT_GUIDE.md#workflow-1-understand-a-system-before-making-changes)** — map a module, trace symbols, check blast radius
|
|
46
|
-
- **[Write an implementation plan](docs/AGENT_GUIDE.md#workflow-2-write-a-concrete-implementation-plan)** — identify contracts, map dependencies, find reusable code
|
|
47
|
-
- **[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
|
|
48
|
-
- **[Assess code quality](docs/AGENT_GUIDE.md#workflow-4-assess-code-quality-and-risk)** — health score, complexity hotspots, coupling risks
|
|
49
|
-
- **[Verify change impact](docs/AGENT_GUIDE.md#workflow-5-understand-impact-after-making-changes)** — diff impact, transitive blast radius, consumer blast radius
|
|
50
|
-
|
|
51
|
-
Historical implementation plans and completed cleanup notes live in [`docs/plans/`](docs/plans/).
|
|
52
|
-
|
|
53
|
-
## Install From npm
|
|
54
|
-
|
|
55
|
-
Install the published CLI globally from npm:
|
|
32
|
+
## Install
|
|
56
33
|
|
|
57
34
|
```bash
|
|
58
35
|
npm install -g scip-query@latest
|
|
59
|
-
scip-query
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
You can also run it without a global install:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
npx scip-query@latest --version
|
|
66
|
-
npx scip-query@latest reindex
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
The npm package is published at [`scip-query`](https://www.npmjs.com/package/scip-query). `@latest` should resolve to the newest published version.
|
|
70
|
-
|
|
71
|
-
## Quick Start
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
# Install
|
|
75
|
-
npm install -g scip-query@latest
|
|
76
|
-
scip-query --version
|
|
77
|
-
scip-query check-deps # verify optional indexers and parser support
|
|
78
|
-
scip-query install-skills # install built-in Codex/Claude skills
|
|
79
|
-
|
|
80
|
-
# Index your project (auto-detects language)
|
|
81
|
-
scip-query reindex
|
|
82
|
-
|
|
83
|
-
# Start querying
|
|
84
|
-
scip-query stats
|
|
85
|
-
scip-query health # full codebase health report
|
|
86
|
-
scip-query symbols src/auth.service.ts
|
|
87
|
-
scip-query refs login
|
|
88
|
-
scip-query affected login # transitive blast radius
|
|
89
|
-
scip-query dead --min-loc 10
|
|
90
|
-
scip-query similar --min-similarity 0.5
|
|
91
|
-
scip-query diff-impact # what did my changes affect?
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Prerequisites
|
|
95
|
-
|
|
96
|
-
- **Node.js** >= 18
|
|
97
|
-
- **scip** CLI - [Install from releases](https://github.com/sourcegraph/scip/releases) (converts index data to SQLite)
|
|
98
|
-
- A language-specific SCIP indexer for your project:
|
|
99
|
-
|
|
100
|
-
| Language | Indexer | Install |
|
|
101
|
-
|---|---|---|
|
|
102
|
-
| TypeScript / JavaScript / Vue | scip-typescript | `npm install -g @sourcegraph/scip-typescript` |
|
|
103
|
-
| Java / Scala / Kotlin | scip-java | [releases](https://github.com/sourcegraph/scip-java/releases) |
|
|
104
|
-
| Rust | rust-analyzer | Ships with rust-analyzer (`rust-analyzer scip`) |
|
|
105
|
-
| Python | scip-python-plus | `npm install -g scip-python-plus` |
|
|
106
|
-
| Go | scip-go | `go install github.com/sourcegraph/scip-go@latest` |
|
|
107
|
-
| Ruby | scip-ruby | [releases](https://github.com/sourcegraph/scip-ruby/releases) |
|
|
108
|
-
| C / C++ | scip-clang | [releases](https://github.com/sourcegraph/scip-clang/releases) |
|
|
109
|
-
| C# / VB | scip-dotnet | [releases](https://github.com/sourcegraph/scip-dotnet/releases) |
|
|
110
|
-
| Dart | scip-dart | [releases](https://github.com/nicovince/scip-dart/releases) |
|
|
111
|
-
| PHP | scip-php | [releases](https://github.com/nicovince/scip-php/releases) |
|
|
112
|
-
|
|
113
|
-
For Python, the npm package is `scip-python-plus`. Depending on which version you installed, the executable on your `PATH` may be `scip-python`, `scip-python-plus`, or both. `scip-query` accepts either name.
|
|
114
|
-
|
|
115
|
-
Vue single-file components (`.vue`) are handled by the JavaScript/TypeScript indexer. `scip-query` extracts the `<script>` block (or `<script setup>`, picking the language from the `lang=` attribute) and parses it as TS/JS so symbol, reference, and import queries cover Vue components alongside regular `.ts`/`.js` files.
|
|
116
|
-
|
|
117
|
-
## How It Works
|
|
118
|
-
|
|
119
|
-
1. A SCIP indexer analyzes your source code using the actual compiler/type checker and produces a `index.scip` protobuf file containing symbols, definitions, and references.
|
|
120
|
-
2. The `scip` CLI converts the protobuf to a SQLite database (`index.db`).
|
|
121
|
-
3. `scip-query` runs SQL queries and language-aware source augmentation against that database to answer questions about your codebase.
|
|
122
|
-
|
|
123
|
-
Because the index comes from real language tooling, direct symbol, definition, and reference queries are precise, not grep-based approximations. When a language index is missing enough call-site detail for higher-level analyses, `scip-query` can fall back to AST parsing, semantic providers, and identifier recovery so those commands stay useful while still reporting conservative results.
|
|
124
|
-
|
|
125
|
-
## Configuration
|
|
126
|
-
|
|
127
|
-
### Per-project config
|
|
128
|
-
|
|
129
|
-
Run `scip-query init` to generate a `.scipquery.json` in your project root:
|
|
130
|
-
|
|
131
|
-
```json
|
|
132
|
-
{
|
|
133
|
-
"languages": ["typescript"],
|
|
134
|
-
"watch": {
|
|
135
|
-
"enabled": false,
|
|
136
|
-
"debounceMs": 30000,
|
|
137
|
-
"cooldownMs": 60000
|
|
138
|
-
},
|
|
139
|
-
"indexer": {
|
|
140
|
-
"typescript": {
|
|
141
|
-
"pnpmWorkspaces": true
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Environment variables
|
|
148
|
-
|
|
149
|
-
| Variable | Purpose |
|
|
150
|
-
|---|---|
|
|
151
|
-
| `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory |
|
|
152
|
-
| `SCIP_QUERY_INDEX_DB` | Override the SQLite database path |
|
|
153
|
-
| `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path |
|
|
154
|
-
| `SCIP_QUERY_CACHE_DIR` | Override the cache directory |
|
|
155
|
-
|
|
156
|
-
### Index storage
|
|
157
|
-
|
|
158
|
-
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.
|
|
159
|
-
|
|
160
|
-
### Gitignore integration
|
|
161
|
-
|
|
162
|
-
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.
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## Command Reference
|
|
167
|
-
|
|
168
|
-
### Index Management
|
|
169
|
-
|
|
170
|
-
#### `reindex`
|
|
171
|
-
|
|
172
|
-
Index (or re-index) the codebase. Auto-detects which languages are present, runs the appropriate SCIP indexer, and converts the output to SQLite.
|
|
173
|
-
|
|
174
|
-
```bash
|
|
175
|
-
scip-query reindex
|
|
176
|
-
scip-query reindex --language typescript
|
|
177
|
-
scip-query reindex --pnpm-workspaces # for pnpm monorepos
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
**Options:**
|
|
181
|
-
- `-l, --language <lang>` — Index only this language (can repeat)
|
|
182
|
-
- `--pnpm-workspaces` — Enable pnpm workspace support (TypeScript)
|
|
183
|
-
|
|
184
|
-
**When to use:** After significant code changes, after pulling, or before running analysis commands for the first time.
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
#### `watch`
|
|
189
|
-
|
|
190
|
-
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.
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
scip-query watch
|
|
194
|
-
scip-query watch --debounce 60000 # wait 60s after last change
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
**Options:**
|
|
198
|
-
- `--debounce <ms>` — Milliseconds to wait after the last file change before reindexing (default: 30000)
|
|
199
|
-
- `--cooldown <ms>` — Minimum milliseconds between reindex completions (default: 60000)
|
|
200
|
-
|
|
201
|
-
**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.
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
#### `status`
|
|
206
|
-
|
|
207
|
-
Show the current index status: where it's stored, how big it is, when it was built.
|
|
208
|
-
|
|
209
|
-
```bash
|
|
210
|
-
scip-query status
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
|
-
#### `stats`
|
|
216
|
-
|
|
217
|
-
Show index statistics: document count, symbol count, definition count, reference count, database size.
|
|
218
|
-
|
|
219
|
-
```bash
|
|
220
|
-
scip-query stats
|
|
221
|
-
# Documents: 42
|
|
222
|
-
# Symbols: 1111
|
|
223
|
-
# Definitions: 803
|
|
224
|
-
# References: 2094
|
|
225
|
-
# Index size: 660 KB
|
|
226
|
-
# Last built: 2026-04-10 16:12:58
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
**Value:** Quick sanity check that your index is healthy and up to date.
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
#### `init`
|
|
234
|
-
|
|
235
|
-
Create a `.scipquery.json` config file in the project root with auto-detected languages and default settings.
|
|
236
|
-
|
|
237
|
-
```bash
|
|
238
|
-
scip-query init
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
---
|
|
242
|
-
|
|
243
|
-
### Navigation
|
|
244
|
-
|
|
245
|
-
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.
|
|
246
|
-
|
|
247
|
-
#### `files <pattern>`
|
|
248
|
-
|
|
249
|
-
Find indexed files matching a path pattern.
|
|
250
|
-
|
|
251
|
-
```bash
|
|
252
|
-
scip-query files auth # all files with "auth" in the path
|
|
253
|
-
scip-query files .service.ts # all service files
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
**Value:** Quick file discovery without leaving the terminal. Respects gitignore.
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
#### `symbols <file>`
|
|
261
|
-
|
|
262
|
-
List all symbols defined in a file with their line ranges and type signatures.
|
|
263
|
-
|
|
264
|
-
```bash
|
|
265
|
-
scip-query symbols auth.service.ts
|
|
266
|
-
# 1-50 AuthService — class AuthService
|
|
267
|
-
# 5-20 AuthService:login() — login(email: string): Promise<Token>
|
|
268
|
-
# 22-35 AuthService:logout() — logout(): void
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
**Value:** Instant overview of a file's API surface — like a table of contents with type information. Faster than reading the file.
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
#### `methods <className>`
|
|
276
|
-
|
|
277
|
-
List all methods of a class with their line ranges.
|
|
278
|
-
|
|
279
|
-
```bash
|
|
280
|
-
scip-query methods AuthService
|
|
281
|
-
# 5-20 login
|
|
282
|
-
# 22-35 logout
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
**Value:** Quick method inventory for a class. Useful when you need to know what a class can do without reading its full source.
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
|
-
#### `refs <symbol>`
|
|
290
|
-
|
|
291
|
-
Find every file that references a symbol, grouped by file with line numbers.
|
|
292
|
-
|
|
293
|
-
```bash
|
|
294
|
-
scip-query refs login
|
|
295
|
-
# src/controllers/auth.controller.ts
|
|
296
|
-
# line 15
|
|
297
|
-
# src/__tests__/auth.test.ts
|
|
298
|
-
# line 8
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
**Value:** "Who uses this?" — the most fundamental code intelligence question. Compiler-resolved, so no false positives from string matches.
|
|
302
|
-
|
|
303
|
-
---
|
|
304
|
-
|
|
305
|
-
#### `trace <symbol>`
|
|
306
|
-
|
|
307
|
-
Show a symbol's definition (with signature) and every file that references it. Like `refs` but also shows you where the symbol is defined.
|
|
308
|
-
|
|
309
|
-
```bash
|
|
310
|
-
scip-query trace parseSymbol
|
|
311
|
-
# ═══ DEFINITION ═══
|
|
312
|
-
# src/symbols/symbol-parser.ts:35-99 — parseSymbol(raw: string): ScipSymbol | ScipLocalSymbol
|
|
313
|
-
#
|
|
314
|
-
# ═══ REFERENCED BY ═══
|
|
315
|
-
# src/index.ts
|
|
316
|
-
# src/symbols/symbol-parser.ts
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
**Value:** End-to-end symbol investigation. Answers "where is this defined, what's its signature, and who uses it?" in one command.
|
|
320
|
-
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
#### `outline <file>`
|
|
324
|
-
|
|
325
|
-
Tree-structured view of all symbols in a file, using parent-child nesting when the indexer provides `enclosing_symbol` data.
|
|
326
|
-
|
|
327
|
-
```bash
|
|
328
|
-
scip-query outline db.ts
|
|
329
|
-
# 0-111 src:db
|
|
330
|
-
# 19-110 src:db:ScipDatabase
|
|
331
|
-
# 24-29 src:db:ScipDatabase:constructor()
|
|
332
|
-
# 32-34 src:db:ScipDatabase:setPathFilter()
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
**Value:** Visual file structure at a glance — like an IDE's outline panel but in the terminal.
|
|
336
|
-
|
|
337
|
-
---
|
|
338
|
-
|
|
339
|
-
#### `hierarchy <symbol>`
|
|
340
|
-
|
|
341
|
-
Show a symbol's ancestry chain — from the symbol up through its enclosing scopes (method → class → module → file).
|
|
342
|
-
|
|
343
|
-
```bash
|
|
344
|
-
scip-query hierarchy login
|
|
345
|
-
# src:auth:AuthService:login()
|
|
346
|
-
# src:auth:AuthService
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
**Value:** Understand where a symbol lives in the nesting hierarchy. Requires the indexer to populate `enclosing_symbol`.
|
|
350
|
-
|
|
351
|
-
---
|
|
352
|
-
|
|
353
|
-
#### `members <symbol>`
|
|
354
|
-
|
|
355
|
-
Find all direct children of a symbol (methods, fields, nested types) using the enclosing_symbol relationship.
|
|
356
|
-
|
|
357
|
-
```bash
|
|
358
|
-
scip-query members AuthService
|
|
359
|
-
# 5-20 [method] login
|
|
360
|
-
# 22-35 [method] logout
|
|
361
|
-
# 37-37 [term] tokenSecret
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
**Value:** Like `methods` but includes fields, nested types, and anything else directly inside a symbol. Requires `enclosing_symbol` support from the indexer.
|
|
365
|
-
|
|
366
|
-
---
|
|
367
|
-
|
|
368
|
-
#### `call-graph <symbol>`
|
|
369
|
-
|
|
370
|
-
Show what calls a symbol (incoming) and what the symbol calls (outgoing).
|
|
371
|
-
|
|
372
|
-
```bash
|
|
373
|
-
scip-query call-graph shortenSymbol
|
|
374
|
-
# Symbol: src:symbol-parser:shortenSymbol()
|
|
375
|
-
#
|
|
376
|
-
# ═══ CALLERS (16) ═══
|
|
377
|
-
# src/queries/dead.ts src:queries:dead
|
|
378
|
-
# src/queries/hotspots.ts src:queries:hotspots
|
|
379
|
-
# ...
|
|
380
|
-
#
|
|
381
|
-
# ═══ CALLEES (0) ═══
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
**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.
|
|
385
|
-
|
|
386
|
-
---
|
|
387
|
-
|
|
388
|
-
### Dependency Analysis
|
|
389
|
-
|
|
390
|
-
These commands map how files and modules depend on each other — forward deps, reverse deps, and full module maps.
|
|
391
|
-
|
|
392
|
-
#### `deps <file>`
|
|
393
|
-
|
|
394
|
-
List all internal files that this file depends on (forward dependencies).
|
|
395
|
-
|
|
396
|
-
```bash
|
|
397
|
-
scip-query deps cli.ts
|
|
398
|
-
# src/runtime/config.ts
|
|
399
|
-
# src/storage/db.ts
|
|
400
|
-
# src/queries/index.ts
|
|
401
|
-
# src/reindex/index.ts
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
**Value:** "What does this file need to work?" Useful before refactoring — tells you what you're coupled to.
|
|
405
|
-
|
|
406
|
-
---
|
|
407
|
-
|
|
408
|
-
#### `rdeps <file>`
|
|
409
|
-
|
|
410
|
-
List all files that depend on this file (reverse dependencies).
|
|
411
|
-
|
|
412
|
-
```bash
|
|
413
|
-
scip-query rdeps symbol-parser
|
|
414
|
-
# src/index.ts
|
|
415
|
-
# src/queries/dead.ts
|
|
416
|
-
# src/queries/hotspots.ts
|
|
417
|
-
# ...
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
**Value:** "Who breaks if I change this?" The blast radius of a modification. High rdeps count = be very careful with changes.
|
|
421
|
-
|
|
422
|
-
---
|
|
423
|
-
|
|
424
|
-
#### `system <module>`
|
|
425
|
-
|
|
426
|
-
Full module map: all files in the module, all exported symbols, all inbound and outbound dependencies.
|
|
427
|
-
|
|
428
|
-
```bash
|
|
429
|
-
scip-query system queries
|
|
430
|
-
# ═══ FILES ═══
|
|
431
|
-
# src/queries/dead.ts
|
|
432
|
-
# src/queries/deps.ts
|
|
433
|
-
# ...
|
|
434
|
-
#
|
|
435
|
-
# ═══ EXPORTED SYMBOLS ═══
|
|
436
|
-
# 8-124 dead()
|
|
437
|
-
# 4-23 deps()
|
|
438
|
-
# ...
|
|
439
|
-
#
|
|
440
|
-
# ═══ DEPENDS ON (internal) ═══
|
|
441
|
-
# src/storage/db.ts
|
|
442
|
-
# src/symbols/symbol-parser.ts
|
|
443
|
-
#
|
|
444
|
-
# ═══ DEPENDED ON BY ═══
|
|
445
|
-
# src/runtime/cli.ts
|
|
446
|
-
# src/index.ts
|
|
36
|
+
scip-query reindex # index the current project
|
|
37
|
+
scip-query health # see where you stand
|
|
447
38
|
```
|
|
448
39
|
|
|
449
|
-
|
|
40
|
+
Or without a global install: `npx scip-query@latest reindex`.
|
|
450
41
|
|
|
451
|
-
|
|
42
|
+
## The Problem
|
|
452
43
|
|
|
453
|
-
|
|
44
|
+
Two problems, actually.
|
|
454
45
|
|
|
455
|
-
|
|
46
|
+
**Agents lose the thread.** A codebase is files connected by definitions, references, imports, calls, and dependency paths. Reading files gives local text, not verified structure. Search finds matching words, not real references. Before editing one unit you need to know what it is, who uses it, and what depends on it — with evidence, not vibes.
|
|
456
47
|
|
|
457
|
-
|
|
458
|
-
scip-query surface storage/db.ts
|
|
459
|
-
# src/runtime/cli.ts → ScipDatabase
|
|
460
|
-
# src/runtime/cli.ts → ScipDatabase:close()
|
|
461
|
-
# src/queries/dead.ts → ScipDatabase:all()
|
|
462
|
-
# src/queries/dead.ts → ScipDatabase:isIgnored()
|
|
463
|
-
```
|
|
48
|
+
**AI-generated code rots in specific ways.** Agents re-implement helpers they didn't know existed. They leave parallel half-wired implementations behind. They add parameters and options "for later" that never come. And the standards docs you write *for* them drift away from the code — so the next agent implements against a dead spec. Generic linters don't see any of this, because none of it is visible in a single file.
|
|
464
49
|
|
|
465
|
-
|
|
50
|
+
`scip-query` attacks both: structural questions with evidence-backed answers, and rot detectors tuned to how code actually decays — each one validated, and each one honest about its own confidence.
|
|
466
51
|
|
|
467
|
-
|
|
52
|
+
## Three Sources of Evidence
|
|
468
53
|
|
|
469
|
-
|
|
54
|
+
Most code tools have one lens. `scip-query` has three, and tells you which one each answer came from:
|
|
470
55
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
**Value:** Quick import inventory. Note: depends on the indexer emitting `role=2` — not all do (e.g., `scip-typescript` currently doesn't).
|
|
480
|
-
|
|
481
|
-
---
|
|
482
|
-
|
|
483
|
-
#### `imported-by <symbol>`
|
|
484
|
-
|
|
485
|
-
Which files import this symbol?
|
|
486
|
-
|
|
487
|
-
```bash
|
|
488
|
-
scip-query imported-by AuthService
|
|
489
|
-
# src/controllers/auth.controller.ts
|
|
490
|
-
# src/__tests__/auth.test.ts
|
|
56
|
+
```mermaid
|
|
57
|
+
flowchart LR
|
|
58
|
+
A["Reference graph<br/>(SCIP: compilers & language servers)"] --> D["scip-query"]
|
|
59
|
+
B["Change graph<br/>(git history: co-change, churn, fix density)"] --> D
|
|
60
|
+
C["Verification oracles<br/>(tsc / cargo check / ts-morph)"] --> D
|
|
61
|
+
D --> E["Evidence-ranked answers<br/>graph-fact · change-graph · heuristic · compiler-verified"]
|
|
491
62
|
```
|
|
492
63
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
Find imports in a file that are never referenced in the same file — likely unused imports that should be cleaned up.
|
|
498
|
-
|
|
499
|
-
```bash
|
|
500
|
-
scip-query unused-imports auth.controller.ts
|
|
501
|
-
# formatDate in src/controllers/auth.controller.ts
|
|
502
|
-
# 1 unused import(s)
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
**Value:** Automated unused import detection. Note: same `role=2` limitation as `imports`.
|
|
506
|
-
|
|
507
|
-
---
|
|
508
|
-
|
|
509
|
-
### Code Quality & Dead Code
|
|
510
|
-
|
|
511
|
-
These commands find code that can be removed, consolidated, or cleaned up.
|
|
512
|
-
|
|
513
|
-
#### `dead [scope]`
|
|
514
|
-
|
|
515
|
-
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).
|
|
516
|
-
|
|
517
|
-
```bash
|
|
518
|
-
scip-query dead --min-loc 10
|
|
519
|
-
scip-query dead src/utils --skip-barrels --include-members
|
|
520
|
-
```
|
|
64
|
+
1. **The reference graph** — who defines, references, calls, imports what. Built from SCIP indexes produced by real compilers and language servers, not text search.
|
|
65
|
+
2. **The change graph** — what git history knows that no compiler can: files that always change together without any dependency edge (one concept scattered across artifacts), churn-weighted complexity (gnarly code nobody touches costs nothing), and whether flagged files actually attract fix commits.
|
|
66
|
+
3. **Verification oracles** — your own toolchain as ground truth. Deletion plans are applied in a throwaway worktree and run through `tsc`/`cargo check` before being stamped `COMPILER-VERIFIED`. The tool even audits *itself*: `self-audit` scores its cheap evidence paths against the TypeScript compiler and reports precision/recall as a tracked number.
|
|
521
67
|
|
|
522
|
-
|
|
523
|
-
- `--min-loc <n>` — Only show symbols >= N lines (default: 1)
|
|
524
|
-
- `--include-tests` — Include test files in results (excluded by default)
|
|
525
|
-
- `--skip-barrels` — Ignore references from inactive barrel re-export files
|
|
526
|
-
- `--include-members` — Include class members (module-level only by default)
|
|
527
|
-
- `--only-dead` — Show only `[dead code]` symbols (skip `[file-internal only]`)
|
|
528
|
-
- `--only-internal` — Show only `[file-internal only]` symbols (skip `[dead code]`)
|
|
68
|
+
## At a Glance
|
|
529
69
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
scip-query
|
|
540
|
-
scip-query
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
545
|
-
- `--min-loc <n>` — Minimum lines of code (default: 3)
|
|
546
|
-
|
|
547
|
-
**Value:** Stricter than `dead` — these symbols serve no purpose at all. Safe deletion candidates.
|
|
548
|
-
|
|
549
|
-
---
|
|
550
|
-
|
|
551
|
-
### Codebase Metrics
|
|
552
|
-
|
|
553
|
-
These commands measure structural properties of the codebase — hotspots, coupling, bottlenecks, fan-in/out.
|
|
554
|
-
|
|
555
|
-
#### `hotspots`
|
|
556
|
-
|
|
557
|
-
Find the most-referenced symbols in the codebase. These are the choke points where changes have the widest blast radius.
|
|
558
|
-
|
|
559
|
-
```bash
|
|
560
|
-
scip-query hotspots -n 15
|
|
561
|
-
# refs files symbol
|
|
562
|
-
# ──── ───── ──────
|
|
563
|
-
# 39 39 src:types
|
|
564
|
-
# 33 31 src:db:ScipDatabase
|
|
565
|
-
# 27 27 src:db:ScipDatabase:all()
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
**Options:**
|
|
569
|
-
- `-n, --limit <n>` — Number of results (default: 30)
|
|
570
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
571
|
-
|
|
572
|
-
**Value:** Identify the symbols where a bug or breaking change would affect the most consumers. Hotspots deserve the most careful review and the most stable interfaces.
|
|
573
|
-
|
|
574
|
-
---
|
|
575
|
-
|
|
576
|
-
#### `fan-in [symbol]`
|
|
577
|
-
|
|
578
|
-
How many distinct files reference a symbol. Without an argument, shows the top N symbols by fan-in across the codebase.
|
|
579
|
-
|
|
580
|
-
```bash
|
|
581
|
-
scip-query fan-in ScipDatabase
|
|
582
|
-
# 19 files ScipDatabase
|
|
583
|
-
# 16 files ScipDatabase:all()
|
|
584
|
-
# 13 files ScipDatabase:isIgnored()
|
|
585
|
-
|
|
586
|
-
scip-query fan-in -n 10
|
|
587
|
-
# files symbol
|
|
588
|
-
# ───── ──────
|
|
589
|
-
# 31 ScipDatabase
|
|
590
|
-
# 27 ScipDatabase:all()
|
|
591
|
-
```
|
|
592
|
-
|
|
593
|
-
**Options:**
|
|
594
|
-
- `-n, --limit <n>` — Number of results for top mode (default: 30)
|
|
595
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
596
|
-
|
|
597
|
-
**Value:** High fan-in = widely depended upon. Changes to high fan-in symbols have large blast radius. These symbols should have stable interfaces and careful review.
|
|
598
|
-
|
|
599
|
-
---
|
|
600
|
-
|
|
601
|
-
#### `fan-out [file]`
|
|
602
|
-
|
|
603
|
-
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.
|
|
604
|
-
|
|
605
|
-
```bash
|
|
606
|
-
scip-query fan-out runtime/cli.ts
|
|
607
|
-
# 23 symbols src/runtime/cli.ts
|
|
608
|
-
|
|
609
|
-
scip-query fan-out -n 10
|
|
610
|
-
# symbols file
|
|
611
|
-
# ─────── ────
|
|
612
|
-
# 68 src/queries/index.ts
|
|
613
|
-
# 23 src/runtime/cli.ts
|
|
614
|
-
```
|
|
615
|
-
|
|
616
|
-
**Options:**
|
|
617
|
-
- `-n, --limit <n>` — Number of results for top mode (default: 30)
|
|
618
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
619
|
-
|
|
620
|
-
**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.
|
|
621
|
-
|
|
622
|
-
---
|
|
623
|
-
|
|
624
|
-
#### `bottlenecks`
|
|
625
|
-
|
|
626
|
-
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.
|
|
627
|
-
|
|
628
|
-
```bash
|
|
629
|
-
scip-query bottlenecks -n 10
|
|
630
|
-
# score fan-in fan-out symbol
|
|
631
|
-
# ───── ────── ─────── ──────
|
|
632
|
-
# 136 2 68 src:queries:index
|
|
633
|
-
# 124 31 4 src:storage:db:ScipDatabase
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
**Options:**
|
|
637
|
-
- `-n, --limit <n>` — Number of results (default: 20)
|
|
638
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
639
|
-
- `--min-fan-in <n>` — Minimum fan-in (default: 2)
|
|
640
|
-
- `--min-fan-out <n>` — Minimum fan-out (default: 2)
|
|
641
|
-
|
|
642
|
-
**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.
|
|
643
|
-
|
|
644
|
-
---
|
|
645
|
-
|
|
646
|
-
#### `coupling [file1] [file2]`
|
|
647
|
-
|
|
648
|
-
Measure coupling between two specific files (how many symbols they share), or find the most coupled file pairs across the codebase.
|
|
649
|
-
|
|
650
|
-
```bash
|
|
651
|
-
scip-query coupling storage/db.ts runtime/cli.ts
|
|
652
|
-
# storage/db.ts ↔ runtime/cli.ts: 4 shared symbols
|
|
653
|
-
|
|
654
|
-
scip-query coupling -n 10
|
|
655
|
-
# shared file1 → file2
|
|
656
|
-
# ────── ─────────────
|
|
657
|
-
# 5 src/storage/db.ts → src/queries/stats.ts
|
|
658
|
-
```
|
|
659
|
-
|
|
660
|
-
**Options:**
|
|
661
|
-
- `-n, --limit <n>` — Number of results for top mode (default: 20)
|
|
662
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
663
|
-
|
|
664
|
-
**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.
|
|
665
|
-
|
|
666
|
-
---
|
|
667
|
-
|
|
668
|
-
#### `cycles`
|
|
669
|
-
|
|
670
|
-
Detect circular dependency chains between files. A cycle exists when file A depends on B, B on C, and C on A.
|
|
671
|
-
|
|
672
|
-
```bash
|
|
673
|
-
scip-query cycles
|
|
674
|
-
# No circular dependencies found.
|
|
675
|
-
|
|
676
|
-
scip-query cycles --scope src/services
|
|
677
|
-
# Cycle 1 (3 files):
|
|
678
|
-
# src/services/auth.ts →
|
|
679
|
-
# src/services/user.ts →
|
|
680
|
-
# src/services/auth.ts (cycle)
|
|
681
|
-
```
|
|
682
|
-
|
|
683
|
-
**Options:**
|
|
684
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
685
|
-
- `--max-depth <n>` — Maximum cycle depth (default: 10)
|
|
686
|
-
|
|
687
|
-
**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.
|
|
70
|
+
| Ask this | Run this |
|
|
71
|
+
|---|---|
|
|
72
|
+
| What is in this module? | `scip-query system src/auth` |
|
|
73
|
+
| Who uses this symbol? | `scip-query trace login` |
|
|
74
|
+
| What might break if I change it? | `scip-query affected login` |
|
|
75
|
+
| Everything I need before editing this | `scip-query plan-context login` |
|
|
76
|
+
| What did my git diff affect? | `scip-query diff-impact` |
|
|
77
|
+
| How healthy is this codebase, really? | `scip-query health` |
|
|
78
|
+
| What can I delete — *prove it* | `scip-query cleanup-plan --verify` |
|
|
79
|
+
| What new code duplicates old code? | `scip-query recent-duplicates` |
|
|
80
|
+
| Which docs lie about the code now? | `scip-query doc-drift` |
|
|
81
|
+
| What changes together but isn't linked? | `scip-query co-change` |
|
|
82
|
+
| Gate an agent's diff before merging | `scip-query diff-gate` |
|
|
83
|
+
| Did the findings get worse? (CI gate) | `scip-query health --baseline` |
|
|
688
84
|
|
|
689
|
-
|
|
85
|
+
## Cleaning Up AI-Generated Code
|
|
690
86
|
|
|
691
|
-
|
|
87
|
+
This is the workflow the tool is built around. Each detector targets a specific way AI-assisted development rots a codebase:
|
|
692
88
|
|
|
693
|
-
Find the
|
|
89
|
+
**1. Find the echoes.** Agents re-implement helpers 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:
|
|
694
90
|
|
|
695
|
-
```bash
|
|
696
|
-
scip-query deep-chains -n 5 --min-depth 4
|
|
697
|
-
# Chain 1 (depth 5):
|
|
698
|
-
# → src/runtime/cli.ts
|
|
699
|
-
# → src/queries/index.ts
|
|
700
|
-
# → src/queries/surface.ts
|
|
701
|
-
# → src/storage/db.ts
|
|
702
|
-
# → src/domain/types.ts
|
|
703
91
|
```
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
- `--min-depth <n>` — Minimum chain depth (default: 3)
|
|
709
|
-
|
|
710
|
-
**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.
|
|
711
|
-
|
|
712
|
-
---
|
|
713
|
-
|
|
714
|
-
#### `by-kind <kind>`
|
|
715
|
-
|
|
716
|
-
Find symbols by their SCIP symbol kind (class, interface, enum, function, struct, method, etc.).
|
|
717
|
-
|
|
718
|
-
```bash
|
|
719
|
-
scip-query by-kind class
|
|
720
|
-
scip-query by-kind interface --scope src/types
|
|
721
|
-
scip-query by-kind 68 # kind number for Struct
|
|
92
|
+
91% ECHO src/components/ProjectCardVisual.tsx ProjectCardVisual() (added 62 commits ago)
|
|
93
|
+
duplicates established src/pages/HomePage.tsx RecentProjectRow()
|
|
94
|
+
100% TWIN src/workflows/a.ts ensureAccessible() / src/workflows/b.ts ensureAccessible()
|
|
95
|
+
(both new — one agent session duplicated itself; consolidate before they diverge)
|
|
722
96
|
```
|
|
723
97
|
|
|
724
|
-
**
|
|
725
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
726
|
-
- `-n, --limit <n>` — Number of results (default: 100)
|
|
727
|
-
|
|
728
|
-
**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.
|
|
729
|
-
|
|
730
|
-
---
|
|
98
|
+
**2. Catch your standards docs lying.** If you keep in-repo standards for agents to read before implementing, a stale standard is worse than none. `doc-drift` reads every doc's file citations *and* its co-change history, then flags docs whose code moved on without them — including **broken references** to files that no longer exist:
|
|
731
99
|
|
|
732
|
-
#### `kind-counts`
|
|
733
|
-
|
|
734
|
-
Show a histogram of symbol kinds in the codebase.
|
|
735
|
-
|
|
736
|
-
```bash
|
|
737
|
-
scip-query kind-counts
|
|
738
|
-
# count kind
|
|
739
|
-
# ───── ────
|
|
740
|
-
# 45 Class (9)
|
|
741
|
-
# 23 Interface (27)
|
|
742
|
-
# 12 Enum (16)
|
|
743
100
|
```
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
**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.
|
|
749
|
-
|
|
750
|
-
---
|
|
751
|
-
|
|
752
|
-
### Similarity & Consolidation
|
|
753
|
-
|
|
754
|
-
These commands find duplication, redundancy, and extraction opportunities — the tools for de-bloating a codebase.
|
|
755
|
-
|
|
756
|
-
#### `similar [symbol]`
|
|
757
|
-
|
|
758
|
-
Find functions with similar callee fingerprints using TF-IDF weighted cosine similarity. Each callee is weighted by how rare it is across the codebase — two functions sharing a niche helper (`sendWelcomeEmail()`) score much higher than two functions sharing infrastructure callees (`db.all()`, `shortenSymbol()`). The "shared" list shown for each pair is the high-IDF (significant) intersection, not every shared callee.
|
|
759
|
-
|
|
760
|
-
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.
|
|
761
|
-
|
|
762
|
-
```bash
|
|
763
|
-
scip-query similar --min-similarity 0.5
|
|
764
|
-
# 80% similar:
|
|
765
|
-
# A: by-kind (src/queries/by-kind.ts)
|
|
766
|
-
# B: call-graph (src/queries/call-graph.ts)
|
|
767
|
-
# Shared: ScipDatabase, db.all(), db.get(), db.isIgnored(), shortenSymbol()
|
|
768
|
-
|
|
769
|
-
scip-query similar dead --min-similarity 0.3
|
|
770
|
-
# 64% similar:
|
|
771
|
-
# A: dead (src/queries/dead.ts)
|
|
772
|
-
# B: bottlenecks (src/queries/bottlenecks.ts)
|
|
773
|
-
# Shared callees: db, ScipDatabase, db.all(), db.isIgnored(), shortenSymbol()
|
|
774
|
-
# Only in A: DeadOptions, DeadSummary, DeadSymbolResult
|
|
775
|
-
# Only in B: BottleneckResult
|
|
101
|
+
staleness 94 product/domain-model.md
|
|
102
|
+
BROKEN REFERENCE: cites src/api/servicePlans.ts — that file no longer exists
|
|
103
|
+
22 change(s) since doc update src/workflows/serviceTasks.ts (referenced by doc)
|
|
776
104
|
```
|
|
777
105
|
|
|
778
|
-
**
|
|
779
|
-
- `--min-similarity <n>` — Minimum cosine similarity 0-1 (default: 0.4)
|
|
780
|
-
- `-n, --limit <n>` — Number of results (default: 20)
|
|
781
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
782
|
-
- `--min-callees <n>` — Minimum callees to consider a symbol (default: 4)
|
|
783
|
-
- `--cross-file-only` — Only show cross-file pairs (skip same-file matches)
|
|
784
|
-
|
|
785
|
-
**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.
|
|
786
|
-
|
|
787
|
-
---
|
|
788
|
-
|
|
789
|
-
#### `similar-files [file]`
|
|
790
|
-
|
|
791
|
-
Find files with similar dependency profiles using Jaccard similarity on their dependency sets. Files that import the same modules are structurally doing similar work.
|
|
106
|
+
**3. Delete with proof.** `cleanup-plan` runs dead-code analysis to a *fixpoint* — deleting batch 0 makes batch 1 dead, and the plan shows the cascade. `--verify` applies each batch in a throwaway git worktree and runs your own compiler (differentially, so pre-existing errors don't drown the signal):
|
|
792
107
|
|
|
793
|
-
```bash
|
|
794
|
-
scip-query similar-files --min-similarity 0.7
|
|
795
|
-
# 100% similar:
|
|
796
|
-
# src/queries/symbols.ts
|
|
797
|
-
# src/queries/system.ts
|
|
798
|
-
# Shared deps (4): db.ts, types.ts, symbol-parser.ts, clean-signature.ts
|
|
799
|
-
|
|
800
|
-
scip-query similar-files auth.controller.ts
|
|
801
108
|
```
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
- `-n, --limit <n>` — Number of results (default: 20)
|
|
806
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
807
|
-
- `--min-deps <n>` — Minimum dependencies on the smaller side (auto-tunes by default; pass to override)
|
|
808
|
-
|
|
809
|
-
**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.
|
|
810
|
-
|
|
811
|
-
---
|
|
812
|
-
|
|
813
|
-
#### `similar-chains`
|
|
814
|
-
|
|
815
|
-
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.
|
|
816
|
-
|
|
817
|
-
```bash
|
|
818
|
-
scip-query similar-chains --min-similarity 0.5
|
|
819
|
-
# ── Chain pair 1 (67% similar, 1 divergence point) ──
|
|
820
|
-
# Chain A: auth.controller.ts → auth.service.ts → user.repo.ts
|
|
821
|
-
# Chain B: org.controller.ts → org.service.ts → user.repo.ts
|
|
822
|
-
# Common suffix: user.repo.ts
|
|
823
|
-
# Divergence points (consolidation targets):
|
|
824
|
-
# [0] auth.controller.ts ↔ org.controller.ts
|
|
825
|
-
# [1] auth.service.ts ↔ org.service.ts
|
|
109
|
+
── Batch 0: deletable now (graph-fact, 67 LOC) ──
|
|
110
|
+
── Batch 1: dead once batch 0 lands (cascade, 21 LOC) ──
|
|
111
|
+
Batch 0: COMPILER-VERIFIED
|
|
826
112
|
```
|
|
827
113
|
|
|
828
|
-
|
|
829
|
-
- `--min-similarity <n>` — Minimum chain similarity 0-1 (default: 0.5)
|
|
830
|
-
- `-n, --limit <n>` — Number of results (default: 15)
|
|
831
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
832
|
-
- `--min-length <n>` — Minimum chain length (default: 3)
|
|
833
|
-
- `--max-length <n>` — Maximum chain length (default: 8)
|
|
834
|
-
|
|
835
|
-
**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.
|
|
114
|
+
When verification *fails*, the errors name the exact references the static evidence missed — that failure has caught real detector mistakes and stopped build-breaking deletions.
|
|
836
115
|
|
|
837
|
-
|
|
116
|
+
**4. Trim speculative generality.** `unused-params` finds trailing parameters no body ever uses (the classic "options for later"), scoped to removals that are type-safe by construction.
|
|
838
117
|
|
|
839
|
-
|
|
118
|
+
**5. Surface hidden coupling.** `co-change` finds file pairs that repeatedly change in the same commits with *no* dependency edge — schema ↔ generated inventory ↔ doc triangles, backend schemas ↔ frontend stores, `.env.example` ↔ its parser. The reference graph cannot see these; the change graph can.
|
|
840
119
|
|
|
841
|
-
|
|
120
|
+
**6. Gate every diff.** `diff-gate` runs the whole suite scoped to what a change *introduces* — echoes of established code, missing co-change partners, docs that cite the changed files, fresh unused params, new dead symbols, baseline regressions — in seconds, exit-code friendly, with a remediation per finding an agent can act on without human triage:
|
|
842
121
|
|
|
843
|
-
```bash
|
|
844
|
-
scip-query extract-candidates --min-loc 20 --min-callees 6
|
|
845
|
-
# src/services/auth.ts:10-85 processAuth (75 LOC, 12 callees)
|
|
846
|
-
# Cluster 1 (92% isolated, 4 callees):
|
|
847
|
-
# validateToken, parseJwt, checkExpiry, refreshToken
|
|
848
|
-
# Cluster 2 (88% isolated, 3 callees):
|
|
849
|
-
# formatUser, enrichProfile, cacheResult
|
|
850
122
|
```
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
854
|
-
- `--min-loc <n>` — Minimum function LOC (default: 10)
|
|
855
|
-
- `--min-callees <n>` — Minimum callees to analyze (default: 6)
|
|
856
|
-
- `-n, --limit <n>` — Number of results (default: 20)
|
|
857
|
-
|
|
858
|
-
**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.
|
|
859
|
-
|
|
860
|
-
---
|
|
861
|
-
|
|
862
|
-
### Impact & Planning
|
|
863
|
-
|
|
864
|
-
#### `affected <symbol>`
|
|
865
|
-
|
|
866
|
-
Full transitive closure of symbols that could break if this symbol changes. BFS through the mention graph at configurable depth.
|
|
867
|
-
|
|
868
|
-
```bash
|
|
869
|
-
scip-query affected login --max-depth 3
|
|
870
|
-
# ── Depth 1 ──
|
|
871
|
-
# src/controllers/auth.controller.ts handleLogin
|
|
872
|
-
# src/__tests__/auth.test.ts authTests
|
|
873
|
-
#
|
|
874
|
-
# ── Depth 2 ──
|
|
875
|
-
# src/routes/index.ts routes
|
|
123
|
+
[co-change-partner] schema.prisma changed, but scripts/scope-inventory.mjs did not — they change together 12x (86% of the time)
|
|
124
|
+
-> Update scripts/scope-inventory.mjs alongside this change, or confirm the coupling no longer holds.
|
|
876
125
|
```
|
|
877
126
|
|
|
878
|
-
**
|
|
879
|
-
- `--max-depth <n>` — Maximum traversal depth (default: 5)
|
|
880
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
127
|
+
**7. Ratchet it in CI.** `health --write-baseline` snapshots finding identities into a committable file; `health --baseline` exits 1 on any *new* finding. "Don't get worse" is an objective gate that no score arithmetic can game.
|
|
881
128
|
|
|
882
|
-
|
|
129
|
+
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").
|
|
883
130
|
|
|
884
|
-
|
|
131
|
+
## A Health Score You Can Argue With
|
|
885
132
|
|
|
886
|
-
|
|
133
|
+
`scip-query health` refuses to be a vanity number:
|
|
887
134
|
|
|
888
|
-
Pre-change briefing for a file: every exported symbol, consumer count, and blast-radius risk.
|
|
889
|
-
|
|
890
|
-
```bash
|
|
891
|
-
scip-query change-surface auth.service.ts
|
|
892
|
-
# File: src/services/auth.service.ts
|
|
893
|
-
# External consumers: 45
|
|
894
|
-
#
|
|
895
|
-
# 1-50 AuthService [12 consumers] *** HIGH RISK ***
|
|
896
|
-
# 5-20 login() [8 consumers] * medium risk *
|
|
897
|
-
# 22-35 logout() [0 consumers]
|
|
898
135
|
```
|
|
136
|
+
Codebase Health Score: 95/100
|
|
137
|
+
Risk: 95/100 (validated predictors: graph facts + change graph)
|
|
138
|
+
Hygiene: 100/100 (tidiness candidates)
|
|
899
139
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
---
|
|
140
|
+
Score Breakdown (100 minus the following):
|
|
141
|
+
- 5 hidden-coupling: 5 co-changing pair(s) without a dependency edge
|
|
903
142
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
scip-query diff-impact
|
|
910
|
-
scip-query diff-impact --base main
|
|
911
|
-
# Changed files: 3
|
|
912
|
-
# Changed symbols: 12
|
|
913
|
-
# Affected consumer files: 28
|
|
143
|
+
Axes:
|
|
144
|
+
Deletable: 1,027 LOC across 89 symbols
|
|
145
|
+
Change amplification: 5 files/commit median, 23 p90
|
|
146
|
+
Evidence quality: 5 graph-fact, 150 heuristic, 0 user-suppressed
|
|
147
|
+
Validation: flagged fix-density 0.12 vs baseline 0.20 (0.6x)
|
|
914
148
|
```
|
|
915
149
|
|
|
916
|
-
**
|
|
917
|
-
-
|
|
918
|
-
|
|
919
|
-
**
|
|
920
|
-
|
|
921
|
-
---
|
|
922
|
-
|
|
923
|
-
### De-bloating
|
|
924
|
-
|
|
925
|
-
#### `drift [module]`
|
|
150
|
+
- **Risk vs. Hygiene** are separate claims: risk components are empirically fix-predictive; hygiene components are tidiness. Blending them is how scores become meaningless.
|
|
151
|
+
- **Every deduction is itemized** — the scalar is auditable, not vibes.
|
|
152
|
+
- **The validation axis is a falsifiability loop**: it measures whether flagged files actually attract more fix commits than the rest *in your repo*, per detector. On some codebases passthrough findings predict fixes at 6× baseline; on others they're noise — the tool reports which, instead of assuming.
|
|
153
|
+
- **Suppressions are data**: every `// scip-query: ignore-*` comment is a precision label, counted and reported.
|
|
926
154
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
```bash
|
|
930
|
-
scip-query drift --min-deviation 6
|
|
931
|
-
#
|
|
932
|
-
# src/services/legacy-auth.ts
|
|
933
|
-
# [LAYER] Imports from infra/ (infra/raw-sql.ts) — may cross architectural boundary
|
|
934
|
-
# app/ should not depend on infra/
|
|
935
|
-
```
|
|
936
|
-
|
|
937
|
-
**Options:**
|
|
938
|
-
- `--min-deviation <n>` — Minimum sibling files before reporting unique dependency deviations (default: 5)
|
|
939
|
-
|
|
940
|
-
**Value:** Finds unused imports, layer-policy violations, and files that don't follow their neighbors' dependency conventions. The outliers are either legacy code needing migration or intentional exceptions needing documentation.
|
|
155
|
+
## Accuracy Model
|
|
941
156
|
|
|
942
|
-
|
|
157
|
+
Evidence tiers are kept explicit, strongest first:
|
|
943
158
|
|
|
944
|
-
|
|
159
|
+
1. **Compiler-backed facts** from the SCIP database (`trace`, `refs`, `deps`, `outline`, ...).
|
|
160
|
+
2. **Semantic augmentation** via `ts-morph` for TypeScript — verified references, callers, callees when SCIP alone is incomplete.
|
|
161
|
+
3. **Source-backed heuristics** (AST/text) for cleanup signals. Always labeled: *"these are candidates, not exact compiler facts."*
|
|
162
|
+
4. **Compiler verification** for deletions — the only tier that earns the word "safe."
|
|
945
163
|
|
|
946
|
-
|
|
164
|
+
And because accuracy you don't measure is a feeling, `self-audit` samples symbols and scores the cheap paths against the TypeScript compiler:
|
|
947
165
|
|
|
948
|
-
```bash
|
|
949
|
-
scip-query wrapper-candidates --max-loc 15
|
|
950
|
-
# src/utils/format.ts:10-18 formatCurrency (8 LOC)
|
|
951
|
-
# Only called by: formatInvoice (fan-in: 12)
|
|
952
166
|
```
|
|
953
|
-
|
|
954
|
-
**Options:**
|
|
955
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
956
|
-
- `--max-loc <n>` — Maximum LOC (default: 15)
|
|
957
|
-
- `-n, --limit <n>` — Number of results (default: 30)
|
|
958
|
-
|
|
959
|
-
**Value:** If a function is only called by one other function, it might be inlineable. The smaller it is, the stronger the signal.
|
|
960
|
-
|
|
961
|
-
---
|
|
962
|
-
|
|
963
|
-
#### `passthrough-candidates`
|
|
964
|
-
|
|
965
|
-
Find functions that forward to exactly one callee — pure indirection.
|
|
966
|
-
|
|
967
|
-
```bash
|
|
968
|
-
scip-query passthrough-candidates
|
|
969
|
-
# src/services/user.ts:5-10 getUser (5 LOC)
|
|
970
|
-
# Forwards to: userRepo.findById (src/repos/user.repo.ts)
|
|
167
|
+
references precision 1.0 recall 0.9 (the cheap path doesn't fabricate; it occasionally misses)
|
|
971
168
|
```
|
|
972
169
|
|
|
973
|
-
|
|
974
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
975
|
-
- `--max-loc <n>` — Maximum LOC (default: 15)
|
|
976
|
-
- `-n, --limit <n>` — Number of results (default: 30)
|
|
977
|
-
|
|
978
|
-
**Value:** Functions that just call one other function without adding logic. Either inline them or verify they serve a purpose (testing boundary, dependency inversion).
|
|
170
|
+
Heuristic detectors carry guardrails learned from real codebases: published `package.json` surfaces are exempt from "unused" advice, `contracts/` and `types/` modules are exempt from "definer never uses it," test files and component-sibling files don't count as hidden coupling, and changelogs-by-policy aren't drift.
|
|
979
171
|
|
|
980
|
-
|
|
172
|
+
## Agent Skills
|
|
981
173
|
|
|
982
|
-
|
|
174
|
+
`scip-query install-skills` symlinks ready-made skills into Claude Code, Codex, and shared agent roots — workflows for exploring (`scip-explore`), debloating (`scip-debloat`), maintainability review (`scip-maintainability`), claim verification (`scip-verify`), per-language guidance (`scip-language-playbook`), and grounded planning (`concrete-plan`).
|
|
983
175
|
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
```bash
|
|
987
|
-
scip-query stale-abstractions --min-loc 5
|
|
988
|
-
# src/types/deprecated.ts:1-25 OldUserType (25 LOC, unused)
|
|
989
|
-
# src/interfaces/single.ts:1-15 ISingleUse (15 LOC, 1 consumer)
|
|
990
|
-
```
|
|
991
|
-
|
|
992
|
-
**Options:**
|
|
993
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
994
|
-
- `--min-loc <n>` — Minimum LOC (default: 3)
|
|
995
|
-
- `-n, --limit <n>` — Number of results (default: 30)
|
|
996
|
-
- `--include-low-confidence` — Include 1-consumer classes (usually encapsulation, not stale)
|
|
997
|
-
|
|
998
|
-
**Value:** An interface with one implementation isn't an abstraction — it's indirection. Finds over-engineering.
|
|
999
|
-
|
|
1000
|
-
---
|
|
1001
|
-
|
|
1002
|
-
#### `complexity-hotspots`
|
|
1003
|
-
|
|
1004
|
-
Composite complexity score per symbol: LOC x fan-in x fan-out.
|
|
176
|
+
## Quick Start
|
|
1005
177
|
|
|
1006
178
|
```bash
|
|
1007
|
-
scip-query
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
# 101.7 541 47 0 16 types
|
|
1011
|
-
# 31.3 279 28 5 33 symbol-parser
|
|
1012
|
-
```
|
|
1013
|
-
|
|
1014
|
-
**Options:**
|
|
1015
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
1016
|
-
- `--min-loc <n>` — Minimum LOC (default: 10)
|
|
1017
|
-
- `-n, --limit <n>` — Number of results (default: 20)
|
|
1018
|
-
|
|
1019
|
-
**Value:** The symbols most likely to contain bugs and be hardest to modify. High score = high LOC + many consumers + many dependencies.
|
|
1020
|
-
|
|
1021
|
-
---
|
|
1022
|
-
|
|
1023
|
-
### Composite Reports
|
|
1024
|
-
|
|
1025
|
-
#### `health`
|
|
1026
|
-
|
|
1027
|
-
Single command that runs all analyses and produces a prioritized action list with a health score.
|
|
179
|
+
scip-query check-deps # verify indexers are runnable
|
|
180
|
+
scip-query install-skills # optional: agent skills
|
|
181
|
+
scip-query reindex
|
|
1028
182
|
|
|
1029
|
-
|
|
183
|
+
scip-query stats
|
|
184
|
+
scip-query system src/auth
|
|
185
|
+
scip-query plan-context login
|
|
1030
186
|
scip-query health
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
#
|
|
1034
|
-
# Findings:
|
|
1035
|
-
# Dead code: 12 symbols (340 LOC)
|
|
1036
|
-
# Similar pairs: 8
|
|
1037
|
-
# Stale abstractions: 5
|
|
1038
|
-
#
|
|
1039
|
-
# Prioritized Actions:
|
|
1040
|
-
# 1. [low effort / high impact] 12 symbols with zero references — safe to delete (~340 LOC)
|
|
1041
|
-
# 2. [low effort / medium impact] 5 types with 0-1 consumers — premature abstraction
|
|
1042
|
-
# 3. [medium effort / medium impact] 8 pairs with >60% callee overlap — consolidation candidates
|
|
1043
|
-
|
|
1044
|
-
scip-query health --json # JSON output for programmatic use
|
|
1045
|
-
```
|
|
1046
|
-
|
|
1047
|
-
**Options:**
|
|
1048
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
1049
|
-
- `--json` — Output as JSON
|
|
1050
|
-
|
|
1051
|
-
**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.
|
|
1052
|
-
|
|
1053
|
-
---
|
|
1054
|
-
|
|
1055
|
-
#### `convergence <symbol1> <symbol2>`
|
|
1056
|
-
|
|
1057
|
-
Given two similar functions (from `similar`), show what a consolidated version would look like.
|
|
1058
|
-
|
|
1059
|
-
```bash
|
|
1060
|
-
scip-query convergence bottlenecks hotspots
|
|
1061
|
-
# 82% callee overlap
|
|
1062
|
-
#
|
|
1063
|
-
# A: bottlenecks (src/queries/bottlenecks.ts, 68 LOC)
|
|
1064
|
-
# B: hotspots (src/queries/hotspots.ts, 54 LOC)
|
|
1065
|
-
#
|
|
1066
|
-
# Shared callees (9): ScipDatabase, db.all(), db.isIgnored(), ...
|
|
1067
|
-
# Unique to A (1): BottleneckResult
|
|
1068
|
-
# Unique to B (1): HotspotResult
|
|
1069
|
-
#
|
|
1070
|
-
# Strategy: Create a shared function with the 9 common callees.
|
|
1071
|
-
# Pass the 2 divergent callees as parameters or strategy callbacks.
|
|
1072
|
-
```
|
|
1073
|
-
|
|
1074
|
-
**Value:** Turns "these two functions are similar" into a concrete refactoring prescription.
|
|
1075
|
-
|
|
1076
|
-
---
|
|
1077
|
-
|
|
1078
|
-
### Source & Analysis
|
|
1079
|
-
|
|
1080
|
-
#### `code <symbol>`
|
|
1081
|
-
|
|
1082
|
-
Read the source code for a symbol, bounded to its definition range.
|
|
1083
|
-
|
|
1084
|
-
```bash
|
|
1085
|
-
scip-query code shortenSymbol
|
|
1086
|
-
scip-query code shortenSymbol -C 5 # 5 extra lines of context
|
|
1087
|
-
```
|
|
1088
|
-
|
|
1089
|
-
**Options:**
|
|
1090
|
-
- `-C, --context <n>` — Extra lines above/below the definition (default: 0)
|
|
1091
|
-
|
|
1092
|
-
**Value:** Read source without leaving the terminal. Language-agnostic — just reads the file at the line range from the index.
|
|
1093
|
-
|
|
1094
|
-
---
|
|
1095
|
-
|
|
1096
|
-
#### `complexity <symbol>`
|
|
1097
|
-
|
|
1098
|
-
Per-symbol complexity analysis: source-level branch counting + index-level metrics.
|
|
1099
|
-
|
|
1100
|
-
```bash
|
|
1101
|
-
scip-query complexity login
|
|
1102
|
-
# LOC: 41
|
|
1103
|
-
# Branches: 8
|
|
1104
|
-
# Cyclomatic estimate: 9
|
|
1105
|
-
# Callees: 5
|
|
1106
|
-
# Fan-in: 12
|
|
1107
|
-
# Fan-out: 3
|
|
187
|
+
scip-query cleanup-plan --verify
|
|
188
|
+
scip-query health --write-baseline # start the ratchet
|
|
1108
189
|
```
|
|
1109
190
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
---
|
|
1113
|
-
|
|
1114
|
-
#### `dataflow <symbol>`
|
|
1115
|
-
|
|
1116
|
-
Reference-level dataflow: where data around a symbol comes from and where it goes.
|
|
1117
|
-
|
|
1118
|
-
```bash
|
|
1119
|
-
scip-query dataflow login
|
|
1120
|
-
# ═══ DEFINED AT ═══
|
|
1121
|
-
# src/auth.service.ts:5
|
|
1122
|
-
# ═══ USED AT ═══
|
|
1123
|
-
# src/auth.controller.ts:15 in handleAuth
|
|
1124
|
-
# ═══ PRODUCERS (feeds into this) ═══
|
|
1125
|
-
# validateInput, formatName
|
|
1126
|
-
# ═══ CONSUMERS (this feeds into) ═══
|
|
1127
|
-
# sendEmail, logAudit
|
|
1128
|
-
```
|
|
1129
|
-
|
|
1130
|
-
**Value:** Shows the data flow context: what other symbols are referenced alongside this one, what feeds in, what consumes it.
|
|
1131
|
-
|
|
1132
|
-
---
|
|
191
|
+
## Prerequisites
|
|
1133
192
|
|
|
1134
|
-
|
|
193
|
+
- Node.js >= 18
|
|
194
|
+
- `scip` CLI, from [Sourcegraph SCIP releases](https://github.com/sourcegraph/scip/releases)
|
|
195
|
+
- A language-specific SCIP indexer for your project
|
|
1135
196
|
|
|
1136
|
-
|
|
197
|
+
| Language | Indexer | Install |
|
|
198
|
+
|---|---|---|
|
|
199
|
+
| TypeScript / JavaScript / Vue | scip-typescript | `npm install -g @sourcegraph/scip-typescript` |
|
|
200
|
+
| Java / Scala / Kotlin | scip-java | [releases](https://github.com/sourcegraph/scip-java/releases) |
|
|
201
|
+
| Rust | rust-analyzer | Ships with rust-analyzer: `rust-analyzer scip` |
|
|
202
|
+
| Python | scip-python-plus | `npm install -g scip-python-plus` |
|
|
203
|
+
| Go | scip-go | `go install github.com/sourcegraph/scip-go@latest` |
|
|
204
|
+
| Ruby | scip-ruby | [releases](https://github.com/sourcegraph/scip-ruby/releases) |
|
|
205
|
+
| C / C++ | scip-clang | [releases](https://github.com/sourcegraph/scip-clang/releases) |
|
|
206
|
+
| C# / VB | scip-dotnet | [releases](https://github.com/sourcegraph/scip-dotnet/releases) |
|
|
207
|
+
| Dart | scip-dart | [releases](https://github.com/nicovince/scip-dart/releases) |
|
|
208
|
+
| PHP | scip-php | [releases](https://github.com/nicovince/scip-php/releases) |
|
|
1137
209
|
|
|
1138
|
-
|
|
1139
|
-
scip-query slice login # backward: what feeds in
|
|
1140
|
-
scip-query slice login --forward # forward: what this feeds into
|
|
1141
|
-
```
|
|
210
|
+
For Python, the executable may be `scip-python`, `scip-python-plus`, or both. `scip-query` accepts either name.
|
|
1142
211
|
|
|
1143
|
-
|
|
1144
|
-
- `--forward` — Forward slice instead of backward (default: backward)
|
|
1145
|
-
- `--depth <n>` — Max transitive depth for backward slice (default: 3)
|
|
212
|
+
Vue single-file components are handled through the JavaScript/TypeScript indexer. `scip-query` also extracts the `<script>` or `<script setup>` block so symbol, reference, and import queries cover Vue components alongside regular `.ts` and `.js` files.
|
|
1146
213
|
|
|
1147
|
-
|
|
214
|
+
## How It Works
|
|
1148
215
|
|
|
1149
|
-
|
|
216
|
+
1. A SCIP indexer analyzes source code with the actual compiler, type checker, or language server and produces `index.scip`.
|
|
217
|
+
2. The `scip` CLI converts that protobuf file to a SQLite database: `index.db`.
|
|
218
|
+
3. `scip-query` runs SQL queries, language-aware source augmentation, and git-history analysis against it.
|
|
1150
219
|
|
|
1151
|
-
|
|
220
|
+
By default, indexes live in `~/.cache/scip-query/projects/<hash>/`, keeping project directories clean. Override paths with `.scipquery.json` or `SCIP_QUERY_*` environment variables.
|
|
1152
221
|
|
|
1153
|
-
|
|
222
|
+
## Configuration
|
|
1154
223
|
|
|
1155
|
-
|
|
224
|
+
Run this in a project root:
|
|
1156
225
|
|
|
1157
226
|
```bash
|
|
1158
|
-
scip-query
|
|
1159
|
-
# No redundant re-exports found.
|
|
227
|
+
scip-query init
|
|
1160
228
|
```
|
|
1161
229
|
|
|
1162
|
-
|
|
1163
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
1164
|
-
- `-n, --limit <n>` — Number of results (default: 30)
|
|
1165
|
-
|
|
1166
|
-
**Value:** Finds dead entries in inactive barrel files. Live barrels are skipped so shared entry surfaces like package roots and CLI registries do not show up as false positives.
|
|
1167
|
-
|
|
1168
|
-
---
|
|
1169
|
-
|
|
1170
|
-
#### `similar-signatures`
|
|
1171
|
-
|
|
1172
|
-
Find functions with near-identical type signatures (same parameter types and return type).
|
|
230
|
+
It creates `.scipquery.json`:
|
|
1173
231
|
|
|
1174
|
-
```
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"languages": ["typescript"],
|
|
235
|
+
"watch": {
|
|
236
|
+
"enabled": false,
|
|
237
|
+
"debounceMs": 30000,
|
|
238
|
+
"cooldownMs": 60000
|
|
239
|
+
},
|
|
240
|
+
"indexer": {
|
|
241
|
+
"typescript": {
|
|
242
|
+
"pnpmWorkspaces": true
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
1179
246
|
```
|
|
1180
247
|
|
|
1181
|
-
|
|
1182
|
-
- `-s, --scope <path>` — Limit to files matching path
|
|
1183
|
-
- `--min-loc <n>` — Minimum LOC per function (default: 3)
|
|
1184
|
-
- `-n, --limit <n>` — Number of groups (default: 20)
|
|
1185
|
-
|
|
1186
|
-
**Value:** Different signal from callee similarity — catches "same interface, different implementation" even when the internal logic differs completely.
|
|
1187
|
-
|
|
1188
|
-
---
|
|
1189
|
-
|
|
1190
|
-
## Programmatic API
|
|
1191
|
-
|
|
1192
|
-
Every CLI command is also a TypeScript function. The `queries` namespace exports cover all of them — including the `top*` variants of `fan-in`, `fan-out`, and `coupling`, plus `similarAll` for the cross-codebase mode of `similar`:
|
|
1193
|
-
|
|
1194
|
-
```typescript
|
|
1195
|
-
import {
|
|
1196
|
-
ScipDatabase, createGitignoreFilter,
|
|
1197
|
-
} from 'scip-query';
|
|
1198
|
-
import {
|
|
1199
|
-
health, affected, changeSurface, diffImpact,
|
|
1200
|
-
hotspots, similar, dead, convergence,
|
|
1201
|
-
} from 'scip-query/queries';
|
|
1202
|
-
|
|
1203
|
-
const filter = createGitignoreFilter('/path/to/project');
|
|
1204
|
-
const db = new ScipDatabase({
|
|
1205
|
-
dbPath: '/path/to/index.db',
|
|
1206
|
-
indexPath: '/path/to/index.scip',
|
|
1207
|
-
projectRoot: '/path/to/project',
|
|
1208
|
-
}, filter);
|
|
248
|
+
Useful environment variables:
|
|
1209
249
|
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
250
|
+
| Variable | Purpose |
|
|
251
|
+
|---|---|
|
|
252
|
+
| `SCIP_QUERY_PROJECT_ROOT` | Override the project root directory |
|
|
253
|
+
| `SCIP_QUERY_INDEX_DB` | Override the SQLite database path |
|
|
254
|
+
| `SCIP_QUERY_INDEX_SCIP` | Override the SCIP protobuf path |
|
|
255
|
+
| `SCIP_QUERY_CACHE_DIR` | Override the cache directory |
|
|
1214
256
|
|
|
1215
|
-
|
|
1216
|
-
const blast = affected(db, 'login', { maxDepth: 3 });
|
|
1217
|
-
const brief = changeSurface(db, 'auth.service.ts');
|
|
1218
|
-
const impact = diffImpact(db, { base: 'main' });
|
|
257
|
+
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.
|
|
1219
258
|
|
|
1220
|
-
|
|
1221
|
-
const pairs = similar(db, 'myFunction', { minSimilarity: 0.5 });
|
|
1222
|
-
const recipe = convergence(db, 'funcA', 'funcB');
|
|
259
|
+
## Documentation
|
|
1223
260
|
|
|
1224
|
-
|
|
1225
|
-
|
|
261
|
+
- [Agent Guide](docs/AGENT_GUIDE.md): goal-oriented workflows for tracing, planning, cleanup, quality checks, and change verification.
|
|
262
|
+
- [Command Reference](docs/COMMAND_REFERENCE.md): generated command syntax, descriptions, and options.
|
|
263
|
+
- [Programmatic API](docs/API.md): using the query functions from TypeScript.
|
|
264
|
+
- [Historical plans](docs/plans/): implementation notes and completed cleanup plans.
|
|
1226
265
|
|
|
1227
266
|
## License
|
|
1228
267
|
|