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.
- package/IMPROVEMENTS.md +143 -0
- package/PLAN.md +320 -0
- package/README.md +1213 -0
- package/dist/chunk-2QZ23IBN.js +55 -0
- package/dist/chunk-2QZ23IBN.js.map +1 -0
- package/dist/chunk-36OMT7ZJ.js +144 -0
- package/dist/chunk-36OMT7ZJ.js.map +1 -0
- package/dist/chunk-3E2X7RIE.js +101 -0
- package/dist/chunk-3E2X7RIE.js.map +1 -0
- package/dist/chunk-3UOUTZQT.js +45 -0
- package/dist/chunk-3UOUTZQT.js.map +1 -0
- package/dist/chunk-3ZZJVBIO.js +88 -0
- package/dist/chunk-3ZZJVBIO.js.map +1 -0
- package/dist/chunk-4TYLS5XX.js +10 -0
- package/dist/chunk-4TYLS5XX.js.map +1 -0
- package/dist/chunk-5FGUEU7N.js +101 -0
- package/dist/chunk-5FGUEU7N.js.map +1 -0
- package/dist/chunk-5WTJAXY2.js +61 -0
- package/dist/chunk-5WTJAXY2.js.map +1 -0
- package/dist/chunk-6NBLIDF4.js +24 -0
- package/dist/chunk-6NBLIDF4.js.map +1 -0
- package/dist/chunk-6SXADWLW.js +43 -0
- package/dist/chunk-6SXADWLW.js.map +1 -0
- package/dist/chunk-6VJ6Q7IE.js +65 -0
- package/dist/chunk-6VJ6Q7IE.js.map +1 -0
- package/dist/chunk-7OZPA5OO.js +258 -0
- package/dist/chunk-7OZPA5OO.js.map +1 -0
- package/dist/chunk-BEPIEVLR.js +76 -0
- package/dist/chunk-BEPIEVLR.js.map +1 -0
- package/dist/chunk-BFSCMC22.js +42 -0
- package/dist/chunk-BFSCMC22.js.map +1 -0
- package/dist/chunk-BP2ATLK2.js +110 -0
- package/dist/chunk-BP2ATLK2.js.map +1 -0
- package/dist/chunk-CM454WL3.js +114 -0
- package/dist/chunk-CM454WL3.js.map +1 -0
- package/dist/chunk-DCKMSTJ4.js +74 -0
- package/dist/chunk-DCKMSTJ4.js.map +1 -0
- package/dist/chunk-DEZKCZXD.js +40 -0
- package/dist/chunk-DEZKCZXD.js.map +1 -0
- package/dist/chunk-DVWGWHFW.js +99 -0
- package/dist/chunk-DVWGWHFW.js.map +1 -0
- package/dist/chunk-EMDQWNYR.js +102 -0
- package/dist/chunk-EMDQWNYR.js.map +1 -0
- package/dist/chunk-FFSWWE5O.js +33 -0
- package/dist/chunk-FFSWWE5O.js.map +1 -0
- package/dist/chunk-FGXRVW7G.js +73 -0
- package/dist/chunk-FGXRVW7G.js.map +1 -0
- package/dist/chunk-FUHJCHS4.js +158 -0
- package/dist/chunk-FUHJCHS4.js.map +1 -0
- package/dist/chunk-GJFURBEW.js +64 -0
- package/dist/chunk-GJFURBEW.js.map +1 -0
- package/dist/chunk-GTILYBH6.js +102 -0
- package/dist/chunk-GTILYBH6.js.map +1 -0
- package/dist/chunk-JJP7KQND.js +1 -0
- package/dist/chunk-JJP7KQND.js.map +1 -0
- package/dist/chunk-JKP5GH6T.js +213 -0
- package/dist/chunk-JKP5GH6T.js.map +1 -0
- package/dist/chunk-KCBMVQL5.js +38 -0
- package/dist/chunk-KCBMVQL5.js.map +1 -0
- package/dist/chunk-KVSW5KYP.js +78 -0
- package/dist/chunk-KVSW5KYP.js.map +1 -0
- package/dist/chunk-LAWMH22O.js +172 -0
- package/dist/chunk-LAWMH22O.js.map +1 -0
- package/dist/chunk-LB7OS35Q.js +72 -0
- package/dist/chunk-LB7OS35Q.js.map +1 -0
- package/dist/chunk-LUSIFBXO.js +57 -0
- package/dist/chunk-LUSIFBXO.js.map +1 -0
- package/dist/chunk-MBVNHJVN.js +44 -0
- package/dist/chunk-MBVNHJVN.js.map +1 -0
- package/dist/chunk-MGNMHKX3.js +15 -0
- package/dist/chunk-MGNMHKX3.js.map +1 -0
- package/dist/chunk-N5KEREIA.js +41 -0
- package/dist/chunk-N5KEREIA.js.map +1 -0
- package/dist/chunk-NDSQYIWT.js +71 -0
- package/dist/chunk-NDSQYIWT.js.map +1 -0
- package/dist/chunk-NUZ4OMU3.js +28 -0
- package/dist/chunk-NUZ4OMU3.js.map +1 -0
- package/dist/chunk-QOV2R2WT.js +170 -0
- package/dist/chunk-QOV2R2WT.js.map +1 -0
- package/dist/chunk-SEFSL2GF.js +78 -0
- package/dist/chunk-SEFSL2GF.js.map +1 -0
- package/dist/chunk-T6ARFSBZ.js +103 -0
- package/dist/chunk-T6ARFSBZ.js.map +1 -0
- package/dist/chunk-TBP6BICL.js +46 -0
- package/dist/chunk-TBP6BICL.js.map +1 -0
- package/dist/chunk-TDNNOR6D.js +97 -0
- package/dist/chunk-TDNNOR6D.js.map +1 -0
- package/dist/chunk-TSPZOMHC.js +195 -0
- package/dist/chunk-TSPZOMHC.js.map +1 -0
- package/dist/chunk-UNTPVD36.js +55 -0
- package/dist/chunk-UNTPVD36.js.map +1 -0
- package/dist/chunk-VRUJH4BO.js +88 -0
- package/dist/chunk-VRUJH4BO.js.map +1 -0
- package/dist/chunk-VZ7AMAFL.js +76 -0
- package/dist/chunk-VZ7AMAFL.js.map +1 -0
- package/dist/chunk-XFXDXEUN.js +24 -0
- package/dist/chunk-XFXDXEUN.js.map +1 -0
- package/dist/chunk-YZAA4LYG.js +169 -0
- package/dist/chunk-YZAA4LYG.js.map +1 -0
- package/dist/chunk-Z73NYSBZ.js +92 -0
- package/dist/chunk-Z73NYSBZ.js.map +1 -0
- package/dist/chunk-ZJRYBOEE.js +125 -0
- package/dist/chunk-ZJRYBOEE.js.map +1 -0
- package/dist/cli.js +5798 -0
- package/dist/cli.js.map +1 -0
- package/dist/db-BxaevAyc.d.ts +683 -0
- package/dist/index.d.ts +254 -0
- package/dist/index.js +1271 -0
- package/dist/index.js.map +1 -0
- package/dist/postinstall.js +167 -0
- package/dist/postinstall.js.map +1 -0
- package/dist/queries/affected.d.ts +14 -0
- package/dist/queries/affected.js +9 -0
- package/dist/queries/affected.js.map +1 -0
- package/dist/queries/bottlenecks.d.ts +18 -0
- package/dist/queries/bottlenecks.js +8 -0
- package/dist/queries/bottlenecks.js.map +1 -0
- package/dist/queries/by-kind.d.ts +20 -0
- package/dist/queries/by-kind.js +10 -0
- package/dist/queries/by-kind.js.map +1 -0
- package/dist/queries/call-graph.d.ts +13 -0
- package/dist/queries/call-graph.js +9 -0
- package/dist/queries/call-graph.js.map +1 -0
- package/dist/queries/change-surface.d.ts +10 -0
- package/dist/queries/change-surface.js +9 -0
- package/dist/queries/change-surface.js.map +1 -0
- package/dist/queries/clean-signature.d.ts +9 -0
- package/dist/queries/clean-signature.js +7 -0
- package/dist/queries/clean-signature.js.map +1 -0
- package/dist/queries/code.d.ts +17 -0
- package/dist/queries/code.js +9 -0
- package/dist/queries/code.js.map +1 -0
- package/dist/queries/complexity-hotspots.d.ts +19 -0
- package/dist/queries/complexity-hotspots.js +9 -0
- package/dist/queries/complexity-hotspots.js.map +1 -0
- package/dist/queries/complexity.d.ts +13 -0
- package/dist/queries/complexity.js +9 -0
- package/dist/queries/complexity.js.map +1 -0
- package/dist/queries/convergence.d.ts +11 -0
- package/dist/queries/convergence.js +9 -0
- package/dist/queries/convergence.js.map +1 -0
- package/dist/queries/coupling.d.ts +17 -0
- package/dist/queries/coupling.js +9 -0
- package/dist/queries/coupling.js.map +1 -0
- package/dist/queries/cycles.d.ts +16 -0
- package/dist/queries/cycles.js +8 -0
- package/dist/queries/cycles.js.map +1 -0
- package/dist/queries/dataflow.d.ts +19 -0
- package/dist/queries/dataflow.js +9 -0
- package/dist/queries/dataflow.js.map +1 -0
- package/dist/queries/dead.d.ts +10 -0
- package/dist/queries/dead.js +9 -0
- package/dist/queries/dead.js.map +1 -0
- package/dist/queries/deep-chains.d.ts +16 -0
- package/dist/queries/deep-chains.js +8 -0
- package/dist/queries/deep-chains.js.map +1 -0
- package/dist/queries/deps.d.ts +9 -0
- package/dist/queries/deps.js +9 -0
- package/dist/queries/deps.js.map +1 -0
- package/dist/queries/diff-impact.d.ts +13 -0
- package/dist/queries/diff-impact.js +9 -0
- package/dist/queries/diff-impact.js.map +1 -0
- package/dist/queries/doc-coverage.d.ts +14 -0
- package/dist/queries/doc-coverage.js +8 -0
- package/dist/queries/doc-coverage.js.map +1 -0
- package/dist/queries/drift.d.ts +25 -0
- package/dist/queries/drift.js +8 -0
- package/dist/queries/drift.js.map +1 -0
- package/dist/queries/extract-candidates.d.ts +25 -0
- package/dist/queries/extract-candidates.js +9 -0
- package/dist/queries/extract-candidates.js.map +1 -0
- package/dist/queries/fan.d.ts +29 -0
- package/dist/queries/fan.js +14 -0
- package/dist/queries/fan.js.map +1 -0
- package/dist/queries/files.d.ts +6 -0
- package/dist/queries/files.js +7 -0
- package/dist/queries/files.js.map +1 -0
- package/dist/queries/health.d.ts +18 -0
- package/dist/queries/health.js +21 -0
- package/dist/queries/health.js.map +1 -0
- package/dist/queries/hierarchy.d.ts +13 -0
- package/dist/queries/hierarchy.js +8 -0
- package/dist/queries/hierarchy.js.map +1 -0
- package/dist/queries/hotspots.d.ts +13 -0
- package/dist/queries/hotspots.js +8 -0
- package/dist/queries/hotspots.js.map +1 -0
- package/dist/queries/imports.d.ts +19 -0
- package/dist/queries/imports.js +12 -0
- package/dist/queries/imports.js.map +1 -0
- package/dist/queries/index.d.ts +47 -0
- package/dist/queries/index.js +207 -0
- package/dist/queries/index.js.map +1 -0
- package/dist/queries/isolated.d.ts +14 -0
- package/dist/queries/isolated.js +9 -0
- package/dist/queries/isolated.js.map +1 -0
- package/dist/queries/members.d.ts +10 -0
- package/dist/queries/members.js +8 -0
- package/dist/queries/members.js.map +1 -0
- package/dist/queries/methods.d.ts +6 -0
- package/dist/queries/methods.js +8 -0
- package/dist/queries/methods.js.map +1 -0
- package/dist/queries/outline.d.ts +10 -0
- package/dist/queries/outline.js +8 -0
- package/dist/queries/outline.js.map +1 -0
- package/dist/queries/passthrough-candidates.d.ts +18 -0
- package/dist/queries/passthrough-candidates.js +9 -0
- package/dist/queries/passthrough-candidates.js.map +1 -0
- package/dist/queries/redundant-reexports.d.ts +22 -0
- package/dist/queries/redundant-reexports.js +8 -0
- package/dist/queries/redundant-reexports.js.map +1 -0
- package/dist/queries/refs.d.ts +6 -0
- package/dist/queries/refs.js +7 -0
- package/dist/queries/refs.js.map +1 -0
- package/dist/queries/similar-chains.d.ts +29 -0
- package/dist/queries/similar-chains.js +8 -0
- package/dist/queries/similar-chains.js.map +1 -0
- package/dist/queries/similar-files.d.ts +19 -0
- package/dist/queries/similar-files.js +8 -0
- package/dist/queries/similar-files.js.map +1 -0
- package/dist/queries/similar-signatures.d.ts +21 -0
- package/dist/queries/similar-signatures.js +8 -0
- package/dist/queries/similar-signatures.js.map +1 -0
- package/dist/queries/similar.d.ts +34 -0
- package/dist/queries/similar.js +11 -0
- package/dist/queries/similar.js.map +1 -0
- package/dist/queries/slice.d.ts +21 -0
- package/dist/queries/slice.js +9 -0
- package/dist/queries/slice.js.map +1 -0
- package/dist/queries/stale-abstractions.d.ts +18 -0
- package/dist/queries/stale-abstractions.js +9 -0
- package/dist/queries/stale-abstractions.js.map +1 -0
- package/dist/queries/stats.d.ts +6 -0
- package/dist/queries/stats.js +7 -0
- package/dist/queries/stats.js.map +1 -0
- package/dist/queries/surface.d.ts +7 -0
- package/dist/queries/surface.js +8 -0
- package/dist/queries/surface.js.map +1 -0
- package/dist/queries/symbols.d.ts +6 -0
- package/dist/queries/symbols.js +9 -0
- package/dist/queries/symbols.js.map +1 -0
- package/dist/queries/system.d.ts +7 -0
- package/dist/queries/system.js +9 -0
- package/dist/queries/system.js.map +1 -0
- package/dist/queries/test-coverage.d.ts +22 -0
- package/dist/queries/test-coverage.js +11 -0
- package/dist/queries/test-coverage.js.map +1 -0
- package/dist/queries/trace.d.ts +6 -0
- package/dist/queries/trace.js +8 -0
- package/dist/queries/trace.js.map +1 -0
- package/dist/queries/wrapper-candidates.d.ts +17 -0
- package/dist/queries/wrapper-candidates.js +9 -0
- package/dist/queries/wrapper-candidates.js.map +1 -0
- package/dist/reindex-worker.js +368 -0
- package/dist/reindex-worker.js.map +1 -0
- package/docs/AGENT_GUIDE.md +359 -0
- package/package.json +70 -0
- package/reports/debloat/2026-04-10-scip-query-self-audit.md +161 -0
- package/skills/concrete-plan/SKILL.md +318 -0
- package/skills/scip-debloat/SKILL.md +413 -0
- package/skills/scip-explore/SKILL.md +235 -0
- package/skills/scip-verify/SKILL.md +323 -0
- package/src/cli.ts +1480 -0
- package/src/config.ts +117 -0
- package/src/db.ts +127 -0
- package/src/gitignore-filter.ts +143 -0
- package/src/index.ts +11 -0
- package/src/postinstall.ts +8 -0
- package/src/queries/affected.ts +86 -0
- package/src/queries/bottlenecks.ts +67 -0
- package/src/queries/by-kind.ts +204 -0
- package/src/queries/call-graph.ts +66 -0
- package/src/queries/change-surface.ts +110 -0
- package/src/queries/clean-signature.ts +22 -0
- package/src/queries/code.ts +101 -0
- package/src/queries/complexity-hotspots.ts +119 -0
- package/src/queries/complexity.ts +152 -0
- package/src/queries/convergence.ts +82 -0
- package/src/queries/coupling.ts +99 -0
- package/src/queries/cycles.ts +78 -0
- package/src/queries/dataflow.ts +128 -0
- package/src/queries/dead.ts +122 -0
- package/src/queries/deep-chains.ts +59 -0
- package/src/queries/deps.ts +46 -0
- package/src/queries/diff-impact.ts +204 -0
- package/src/queries/doc-coverage.ts +86 -0
- package/src/queries/drift.ts +224 -0
- package/src/queries/extract-candidates.ts +167 -0
- package/src/queries/fan.ts +148 -0
- package/src/queries/files.ts +16 -0
- package/src/queries/health.ts +324 -0
- package/src/queries/hierarchy.ts +49 -0
- package/src/queries/hotspots.ts +53 -0
- package/src/queries/imports.ts +95 -0
- package/src/queries/index.ts +45 -0
- package/src/queries/isolated.ts +67 -0
- package/src/queries/members.ts +54 -0
- package/src/queries/methods.ts +27 -0
- package/src/queries/outline.ts +52 -0
- package/src/queries/passthrough-candidates.ts +94 -0
- package/src/queries/redundant-reexports.ts +170 -0
- package/src/queries/refs.ts +27 -0
- package/src/queries/similar-chains.ts +314 -0
- package/src/queries/similar-files.ts +140 -0
- package/src/queries/similar-signatures.ts +151 -0
- package/src/queries/similar.ts +305 -0
- package/src/queries/slice.ts +154 -0
- package/src/queries/stale-abstractions.ts +82 -0
- package/src/queries/stats.ts +22 -0
- package/src/queries/surface.ts +34 -0
- package/src/queries/symbols.ts +39 -0
- package/src/queries/system.ts +86 -0
- package/src/queries/test-coverage.ts +106 -0
- package/src/queries/trace.ts +55 -0
- package/src/queries/wrapper-candidates.ts +112 -0
- package/src/query-support.ts +226 -0
- package/src/reindex/detect.ts +58 -0
- package/src/reindex/index.ts +153 -0
- package/src/reindex/indexers.ts +220 -0
- package/src/reindex/install.ts +125 -0
- package/src/reindex-worker.ts +35 -0
- package/src/setup.ts +202 -0
- package/src/symbol-parser.ts +278 -0
- package/src/types.ts +654 -0
- package/src/watch.ts +274 -0
- package/tests/gitignore-filter.test.ts +48 -0
- package/tests/queries.test.ts +300 -0
- package/tests/symbol-parser.test.ts +157 -0
- package/tsconfig.json +20 -0
- package/tsup.config.ts +40 -0
- package/vitest.config.ts +7 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1271 @@
|
|
|
1
|
+
import "./chunk-JJP7KQND.js";
|
|
2
|
+
import {
|
|
3
|
+
surface
|
|
4
|
+
} from "./chunk-FFSWWE5O.js";
|
|
5
|
+
import {
|
|
6
|
+
symbols
|
|
7
|
+
} from "./chunk-KCBMVQL5.js";
|
|
8
|
+
import {
|
|
9
|
+
system
|
|
10
|
+
} from "./chunk-DCKMSTJ4.js";
|
|
11
|
+
import {
|
|
12
|
+
trace
|
|
13
|
+
} from "./chunk-TBP6BICL.js";
|
|
14
|
+
import {
|
|
15
|
+
redundantReexports
|
|
16
|
+
} from "./chunk-3E2X7RIE.js";
|
|
17
|
+
import {
|
|
18
|
+
refs
|
|
19
|
+
} from "./chunk-6NBLIDF4.js";
|
|
20
|
+
import {
|
|
21
|
+
similarChains
|
|
22
|
+
} from "./chunk-JKP5GH6T.js";
|
|
23
|
+
import {
|
|
24
|
+
similarFiles
|
|
25
|
+
} from "./chunk-Z73NYSBZ.js";
|
|
26
|
+
import {
|
|
27
|
+
similarSignatures
|
|
28
|
+
} from "./chunk-SEFSL2GF.js";
|
|
29
|
+
import {
|
|
30
|
+
slice
|
|
31
|
+
} from "./chunk-ZJRYBOEE.js";
|
|
32
|
+
import {
|
|
33
|
+
hierarchy
|
|
34
|
+
} from "./chunk-DEZKCZXD.js";
|
|
35
|
+
import {
|
|
36
|
+
hotspots
|
|
37
|
+
} from "./chunk-BFSCMC22.js";
|
|
38
|
+
import {
|
|
39
|
+
importedBy,
|
|
40
|
+
imports,
|
|
41
|
+
unusedImports
|
|
42
|
+
} from "./chunk-BEPIEVLR.js";
|
|
43
|
+
import {
|
|
44
|
+
members
|
|
45
|
+
} from "./chunk-3UOUTZQT.js";
|
|
46
|
+
import {
|
|
47
|
+
methods
|
|
48
|
+
} from "./chunk-NUZ4OMU3.js";
|
|
49
|
+
import {
|
|
50
|
+
outline
|
|
51
|
+
} from "./chunk-6SXADWLW.js";
|
|
52
|
+
import {
|
|
53
|
+
deps,
|
|
54
|
+
rdeps
|
|
55
|
+
} from "./chunk-N5KEREIA.js";
|
|
56
|
+
import {
|
|
57
|
+
diffImpact
|
|
58
|
+
} from "./chunk-YZAA4LYG.js";
|
|
59
|
+
import {
|
|
60
|
+
docCoverage
|
|
61
|
+
} from "./chunk-FGXRVW7G.js";
|
|
62
|
+
import {
|
|
63
|
+
fanIn,
|
|
64
|
+
fanOut,
|
|
65
|
+
topFanIn,
|
|
66
|
+
topFanOut
|
|
67
|
+
} from "./chunk-GTILYBH6.js";
|
|
68
|
+
import {
|
|
69
|
+
files
|
|
70
|
+
} from "./chunk-MGNMHKX3.js";
|
|
71
|
+
import {
|
|
72
|
+
health
|
|
73
|
+
} from "./chunk-7OZPA5OO.js";
|
|
74
|
+
import {
|
|
75
|
+
staleAbstractions
|
|
76
|
+
} from "./chunk-GJFURBEW.js";
|
|
77
|
+
import {
|
|
78
|
+
stats
|
|
79
|
+
} from "./chunk-XFXDXEUN.js";
|
|
80
|
+
import {
|
|
81
|
+
testCoverage,
|
|
82
|
+
testCoverageSummary
|
|
83
|
+
} from "./chunk-3ZZJVBIO.js";
|
|
84
|
+
import {
|
|
85
|
+
wrapperCandidates
|
|
86
|
+
} from "./chunk-TDNNOR6D.js";
|
|
87
|
+
import {
|
|
88
|
+
passthroughCandidates
|
|
89
|
+
} from "./chunk-NDSQYIWT.js";
|
|
90
|
+
import {
|
|
91
|
+
similar,
|
|
92
|
+
similarAll
|
|
93
|
+
} from "./chunk-TSPZOMHC.js";
|
|
94
|
+
import {
|
|
95
|
+
isolated
|
|
96
|
+
} from "./chunk-LUSIFBXO.js";
|
|
97
|
+
import {
|
|
98
|
+
drift
|
|
99
|
+
} from "./chunk-36OMT7ZJ.js";
|
|
100
|
+
import {
|
|
101
|
+
extractCandidates
|
|
102
|
+
} from "./chunk-CM454WL3.js";
|
|
103
|
+
import {
|
|
104
|
+
complexityHotspots
|
|
105
|
+
} from "./chunk-EMDQWNYR.js";
|
|
106
|
+
import {
|
|
107
|
+
complexity
|
|
108
|
+
} from "./chunk-BP2ATLK2.js";
|
|
109
|
+
import {
|
|
110
|
+
convergence
|
|
111
|
+
} from "./chunk-LB7OS35Q.js";
|
|
112
|
+
import {
|
|
113
|
+
coupling,
|
|
114
|
+
topCoupling
|
|
115
|
+
} from "./chunk-KVSW5KYP.js";
|
|
116
|
+
import {
|
|
117
|
+
cycles
|
|
118
|
+
} from "./chunk-5WTJAXY2.js";
|
|
119
|
+
import {
|
|
120
|
+
dataflow
|
|
121
|
+
} from "./chunk-T6ARFSBZ.js";
|
|
122
|
+
import {
|
|
123
|
+
dead
|
|
124
|
+
} from "./chunk-5FGUEU7N.js";
|
|
125
|
+
import {
|
|
126
|
+
deepChains
|
|
127
|
+
} from "./chunk-MBVNHJVN.js";
|
|
128
|
+
import {
|
|
129
|
+
affected
|
|
130
|
+
} from "./chunk-6VJ6Q7IE.js";
|
|
131
|
+
import {
|
|
132
|
+
bottlenecks
|
|
133
|
+
} from "./chunk-2QZ23IBN.js";
|
|
134
|
+
import {
|
|
135
|
+
byKind,
|
|
136
|
+
kindCounts
|
|
137
|
+
} from "./chunk-LAWMH22O.js";
|
|
138
|
+
import {
|
|
139
|
+
callGraph
|
|
140
|
+
} from "./chunk-UNTPVD36.js";
|
|
141
|
+
import {
|
|
142
|
+
changeSurface
|
|
143
|
+
} from "./chunk-VRUJH4BO.js";
|
|
144
|
+
import "./chunk-4TYLS5XX.js";
|
|
145
|
+
import {
|
|
146
|
+
code
|
|
147
|
+
} from "./chunk-VZ7AMAFL.js";
|
|
148
|
+
import "./chunk-FUHJCHS4.js";
|
|
149
|
+
import {
|
|
150
|
+
leafName,
|
|
151
|
+
parseSymbol,
|
|
152
|
+
shortenSymbol
|
|
153
|
+
} from "./chunk-QOV2R2WT.js";
|
|
154
|
+
|
|
155
|
+
// src/db.ts
|
|
156
|
+
import Database from "better-sqlite3";
|
|
157
|
+
import { statSync } from "fs";
|
|
158
|
+
var ScipDatabase = class {
|
|
159
|
+
db;
|
|
160
|
+
config;
|
|
161
|
+
pathFilter;
|
|
162
|
+
constructor(config, pathFilter) {
|
|
163
|
+
this.config = config;
|
|
164
|
+
this.pathFilter = pathFilter ?? null;
|
|
165
|
+
this.db = new Database(config.dbPath, { readonly: true });
|
|
166
|
+
this.db.pragma("busy_timeout = 5000");
|
|
167
|
+
}
|
|
168
|
+
/** Attach a gitignore-based path filter for query results */
|
|
169
|
+
setPathFilter(filter) {
|
|
170
|
+
this.pathFilter = filter;
|
|
171
|
+
}
|
|
172
|
+
/** Check if a path should be excluded based on .gitignore rules */
|
|
173
|
+
isIgnored(relativePath) {
|
|
174
|
+
return this.pathFilter?.isIgnored(relativePath) ?? false;
|
|
175
|
+
}
|
|
176
|
+
/** Filter an array of paths using the gitignore filter */
|
|
177
|
+
filterPaths(paths) {
|
|
178
|
+
return this.pathFilter?.filter(paths) ?? paths;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* The local-symbol predicate: only match symbols that are defined
|
|
182
|
+
* in files NOT excluded by gitignore. This replaces the old hardcoded
|
|
183
|
+
* `NOT LIKE 'node_modules/%'` check.
|
|
184
|
+
*
|
|
185
|
+
* Since SQLite can't evaluate JS gitignore rules inline, we use a
|
|
186
|
+
* simpler approach: query broadly, then filter in JS. For queries
|
|
187
|
+
* that need SQL-level filtering, use excludedPathPatterns().
|
|
188
|
+
*/
|
|
189
|
+
get localSymbolPredicate() {
|
|
190
|
+
return `EXISTS (
|
|
191
|
+
SELECT 1
|
|
192
|
+
FROM defn_enclosing_ranges local_der
|
|
193
|
+
JOIN documents local_d ON local_der.document_id = local_d.id
|
|
194
|
+
WHERE local_der.symbol_id = gs.id
|
|
195
|
+
${this.pathExclusionsFor("local_d").trimStart()}
|
|
196
|
+
)`;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* SQL WHERE clause fragments to exclude common build/dependency paths.
|
|
200
|
+
* Complements the JS-level gitignore filtering for performance.
|
|
201
|
+
*/
|
|
202
|
+
get pathExclusions() {
|
|
203
|
+
return this.pathExclusionsFor("d");
|
|
204
|
+
}
|
|
205
|
+
/** Reusable SQL fragment: filter out synthetic/internal symbol noise */
|
|
206
|
+
get symbolNoise() {
|
|
207
|
+
return this.symbolNoiseFor("gs");
|
|
208
|
+
}
|
|
209
|
+
/** Build SQL path exclusions for one or more document table aliases */
|
|
210
|
+
pathExclusionsFor(...aliases) {
|
|
211
|
+
return aliases.flatMap((alias) => [
|
|
212
|
+
`AND ${alias}.relative_path NOT LIKE 'node_modules/%'`,
|
|
213
|
+
`AND ${alias}.relative_path NOT LIKE '.git/%'`
|
|
214
|
+
]).join("\n ");
|
|
215
|
+
}
|
|
216
|
+
/** Build SQL symbol exclusions for the given global_symbols alias */
|
|
217
|
+
symbolNoiseFor(alias) {
|
|
218
|
+
return `AND ${alias}.symbol NOT LIKE '%().(%' AND ${alias}.symbol NOT LIKE '%typeLiteral%'`;
|
|
219
|
+
}
|
|
220
|
+
/** Run a raw SQL query and return all rows */
|
|
221
|
+
all(sql, ...params) {
|
|
222
|
+
return this.db.prepare(sql).all(...params);
|
|
223
|
+
}
|
|
224
|
+
/** Run a raw SQL query and return the first row */
|
|
225
|
+
get(sql, ...params) {
|
|
226
|
+
return this.db.prepare(sql).get(...params);
|
|
227
|
+
}
|
|
228
|
+
/** Get the database file size in bytes */
|
|
229
|
+
sizeBytes() {
|
|
230
|
+
try {
|
|
231
|
+
return statSync(this.config.dbPath).size;
|
|
232
|
+
} catch {
|
|
233
|
+
return 0;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/** Get the last modification time of the database file */
|
|
237
|
+
lastModified() {
|
|
238
|
+
try {
|
|
239
|
+
return statSync(this.config.dbPath).mtime;
|
|
240
|
+
} catch {
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
close() {
|
|
245
|
+
this.db.close();
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
// src/gitignore-filter.ts
|
|
250
|
+
import ignore from "ignore";
|
|
251
|
+
import { readFileSync, existsSync } from "fs";
|
|
252
|
+
import { join, dirname } from "path";
|
|
253
|
+
function createGitignoreFilter(projectRoot) {
|
|
254
|
+
const ig = ignore();
|
|
255
|
+
let loaded = false;
|
|
256
|
+
const gitignorePaths = findGitignoreFiles(projectRoot);
|
|
257
|
+
for (const gitignorePath of gitignorePaths) {
|
|
258
|
+
try {
|
|
259
|
+
const content = readFileSync(gitignorePath, "utf-8");
|
|
260
|
+
ig.add(content);
|
|
261
|
+
loaded = true;
|
|
262
|
+
} catch {
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (!loaded) {
|
|
266
|
+
ig.add(DEFAULT_IGNORES);
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
isIgnored: (relativePath) => ig.ignores(relativePath),
|
|
270
|
+
filter: (paths) => paths.filter((p) => !ig.ignores(p))
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function findGitignoreFiles(projectRoot) {
|
|
274
|
+
const files2 = [];
|
|
275
|
+
const rootGitignore = join(projectRoot, ".gitignore");
|
|
276
|
+
if (existsSync(rootGitignore)) {
|
|
277
|
+
files2.push(rootGitignore);
|
|
278
|
+
}
|
|
279
|
+
let dir = dirname(projectRoot);
|
|
280
|
+
let depth = 0;
|
|
281
|
+
while (dir !== dirname(dir) && depth < 5) {
|
|
282
|
+
const parentGitignore = join(dir, ".gitignore");
|
|
283
|
+
if (existsSync(parentGitignore)) {
|
|
284
|
+
files2.push(parentGitignore);
|
|
285
|
+
}
|
|
286
|
+
if (existsSync(join(dir, ".git"))) break;
|
|
287
|
+
dir = dirname(dir);
|
|
288
|
+
depth++;
|
|
289
|
+
}
|
|
290
|
+
return files2;
|
|
291
|
+
}
|
|
292
|
+
var DEFAULT_IGNORES = `
|
|
293
|
+
# Dependencies
|
|
294
|
+
node_modules/
|
|
295
|
+
vendor/
|
|
296
|
+
.bundle/
|
|
297
|
+
|
|
298
|
+
# Build output
|
|
299
|
+
dist/
|
|
300
|
+
build/
|
|
301
|
+
out/
|
|
302
|
+
target/
|
|
303
|
+
bin/
|
|
304
|
+
obj/
|
|
305
|
+
|
|
306
|
+
# Python
|
|
307
|
+
__pycache__/
|
|
308
|
+
*.pyc
|
|
309
|
+
*.pyo
|
|
310
|
+
.venv/
|
|
311
|
+
venv/
|
|
312
|
+
.env/
|
|
313
|
+
env/
|
|
314
|
+
*.egg-info/
|
|
315
|
+
|
|
316
|
+
# Rust
|
|
317
|
+
target/
|
|
318
|
+
|
|
319
|
+
# Java / Kotlin / Scala
|
|
320
|
+
*.class
|
|
321
|
+
.gradle/
|
|
322
|
+
.mvn/
|
|
323
|
+
|
|
324
|
+
# C# / .NET
|
|
325
|
+
bin/
|
|
326
|
+
obj/
|
|
327
|
+
packages/
|
|
328
|
+
|
|
329
|
+
# Go
|
|
330
|
+
vendor/
|
|
331
|
+
|
|
332
|
+
# Dart
|
|
333
|
+
.dart_tool/
|
|
334
|
+
build/
|
|
335
|
+
|
|
336
|
+
# PHP
|
|
337
|
+
vendor/
|
|
338
|
+
|
|
339
|
+
# IDE / OS
|
|
340
|
+
.idea/
|
|
341
|
+
.vscode/
|
|
342
|
+
*.swp
|
|
343
|
+
*.swo
|
|
344
|
+
.DS_Store
|
|
345
|
+
Thumbs.db
|
|
346
|
+
|
|
347
|
+
# Type definitions (often noise in queries)
|
|
348
|
+
*.d.ts
|
|
349
|
+
`;
|
|
350
|
+
|
|
351
|
+
// src/reindex/index.ts
|
|
352
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
353
|
+
import { existsSync as existsSync3 } from "fs";
|
|
354
|
+
import { join as join3 } from "path";
|
|
355
|
+
|
|
356
|
+
// src/reindex/detect.ts
|
|
357
|
+
import { existsSync as existsSync2 } from "fs";
|
|
358
|
+
import { join as join2 } from "path";
|
|
359
|
+
var LANGUAGE_MARKERS = [
|
|
360
|
+
{ language: "typescript", files: ["tsconfig.json", "tsconfig.base.json"] },
|
|
361
|
+
{ language: "rust", files: ["Cargo.toml"] },
|
|
362
|
+
{ language: "go", files: ["go.mod"] },
|
|
363
|
+
{ language: "java", files: ["pom.xml", "build.gradle", "build.gradle.kts"] },
|
|
364
|
+
{ language: "kotlin", files: ["build.gradle.kts"] },
|
|
365
|
+
{ language: "scala", files: ["build.sbt"] },
|
|
366
|
+
{ language: "python", files: ["pyproject.toml", "setup.py", "setup.cfg", "Pipfile"] },
|
|
367
|
+
{ language: "ruby", files: ["Gemfile"] },
|
|
368
|
+
{ language: "csharp", files: ["*.csproj", "*.sln"] },
|
|
369
|
+
{ language: "dart", files: ["pubspec.yaml"] },
|
|
370
|
+
{ language: "php", files: ["composer.json"] },
|
|
371
|
+
{ language: "javascript", files: ["package.json"] }
|
|
372
|
+
// Last — very common, low specificity
|
|
373
|
+
];
|
|
374
|
+
function detectLanguages(projectRoot) {
|
|
375
|
+
const detected = [];
|
|
376
|
+
for (const marker of LANGUAGE_MARKERS) {
|
|
377
|
+
for (const file of marker.files) {
|
|
378
|
+
if (file.includes("*")) {
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (existsSync2(join2(projectRoot, file))) {
|
|
382
|
+
if (!detected.includes(marker.language)) {
|
|
383
|
+
detected.push(marker.language);
|
|
384
|
+
}
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (detected.includes("typescript")) {
|
|
390
|
+
const jsIdx = detected.indexOf("javascript");
|
|
391
|
+
if (jsIdx !== -1) detected.splice(jsIdx, 1);
|
|
392
|
+
}
|
|
393
|
+
return detected;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// src/reindex/indexers.ts
|
|
397
|
+
var INDEXER_CONFIGS = {
|
|
398
|
+
typescript: {
|
|
399
|
+
language: "typescript",
|
|
400
|
+
indexerBinary: "scip-typescript",
|
|
401
|
+
checkCommand: "npx scip-typescript --version",
|
|
402
|
+
indexArgs: ({ outputPath, pnpmWorkspaces }) => {
|
|
403
|
+
const args = ["scip-typescript", "index", "--infer-tsconfig", "--output", outputPath, "--no-progress-bar"];
|
|
404
|
+
if (pnpmWorkspaces) args.splice(2, 0, "--pnpm-workspaces");
|
|
405
|
+
return { binary: "npx", args };
|
|
406
|
+
},
|
|
407
|
+
markerFiles: ["tsconfig.json"],
|
|
408
|
+
installMethods: [
|
|
409
|
+
{ label: "npm", prerequisite: "npm", binary: "npm", args: ["install", "-g", "@sourcegraph/scip-typescript"] }
|
|
410
|
+
],
|
|
411
|
+
installUrl: "https://github.com/sourcegraph/scip-typescript"
|
|
412
|
+
},
|
|
413
|
+
javascript: {
|
|
414
|
+
language: "javascript",
|
|
415
|
+
indexerBinary: "scip-typescript",
|
|
416
|
+
checkCommand: "npx scip-typescript --version",
|
|
417
|
+
indexArgs: ({ outputPath }) => ({
|
|
418
|
+
binary: "npx",
|
|
419
|
+
args: ["scip-typescript", "index", "--infer-tsconfig", "--output", outputPath, "--no-progress-bar"]
|
|
420
|
+
}),
|
|
421
|
+
markerFiles: ["package.json"],
|
|
422
|
+
installMethods: [
|
|
423
|
+
{ label: "npm", prerequisite: "npm", binary: "npm", args: ["install", "-g", "@sourcegraph/scip-typescript"] }
|
|
424
|
+
],
|
|
425
|
+
installUrl: "https://github.com/sourcegraph/scip-typescript"
|
|
426
|
+
},
|
|
427
|
+
java: {
|
|
428
|
+
language: "java",
|
|
429
|
+
indexerBinary: "scip-java",
|
|
430
|
+
checkCommand: "scip-java --version",
|
|
431
|
+
indexArgs: ({ outputPath }) => ({
|
|
432
|
+
binary: "scip-java",
|
|
433
|
+
args: ["index", "--output", outputPath]
|
|
434
|
+
}),
|
|
435
|
+
markerFiles: ["pom.xml", "build.gradle"],
|
|
436
|
+
installMethods: [
|
|
437
|
+
{ label: "coursier", prerequisite: "cs", binary: "cs", args: ["install", "scip-java"] }
|
|
438
|
+
],
|
|
439
|
+
installUrl: "https://github.com/sourcegraph/scip-java/releases"
|
|
440
|
+
},
|
|
441
|
+
scala: {
|
|
442
|
+
language: "scala",
|
|
443
|
+
indexerBinary: "scip-java",
|
|
444
|
+
checkCommand: "scip-java --version",
|
|
445
|
+
indexArgs: ({ outputPath }) => ({
|
|
446
|
+
binary: "scip-java",
|
|
447
|
+
args: ["index", "--output", outputPath]
|
|
448
|
+
}),
|
|
449
|
+
markerFiles: ["build.sbt"],
|
|
450
|
+
installMethods: [
|
|
451
|
+
{ label: "coursier", prerequisite: "cs", binary: "cs", args: ["install", "scip-java"] }
|
|
452
|
+
],
|
|
453
|
+
installUrl: "https://github.com/sourcegraph/scip-java/releases"
|
|
454
|
+
},
|
|
455
|
+
kotlin: {
|
|
456
|
+
language: "kotlin",
|
|
457
|
+
indexerBinary: "scip-java",
|
|
458
|
+
checkCommand: "scip-java --version",
|
|
459
|
+
indexArgs: ({ outputPath }) => ({
|
|
460
|
+
binary: "scip-java",
|
|
461
|
+
args: ["index", "--output", outputPath]
|
|
462
|
+
}),
|
|
463
|
+
markerFiles: ["build.gradle.kts"],
|
|
464
|
+
installMethods: [
|
|
465
|
+
{ label: "coursier", prerequisite: "cs", binary: "cs", args: ["install", "scip-java"] }
|
|
466
|
+
],
|
|
467
|
+
installUrl: "https://github.com/sourcegraph/scip-java/releases"
|
|
468
|
+
},
|
|
469
|
+
rust: {
|
|
470
|
+
language: "rust",
|
|
471
|
+
indexerBinary: "rust-analyzer",
|
|
472
|
+
checkCommand: "rust-analyzer --version",
|
|
473
|
+
indexArgs: ({ outputPath }) => ({
|
|
474
|
+
binary: "rust-analyzer",
|
|
475
|
+
args: ["scip", ".", "--output", outputPath]
|
|
476
|
+
}),
|
|
477
|
+
markerFiles: ["Cargo.toml"],
|
|
478
|
+
installMethods: [
|
|
479
|
+
{ label: "rustup", prerequisite: "rustup", binary: "rustup", args: ["component", "add", "rust-analyzer"] }
|
|
480
|
+
],
|
|
481
|
+
installUrl: "https://github.com/rust-lang/rust-analyzer"
|
|
482
|
+
},
|
|
483
|
+
python: {
|
|
484
|
+
language: "python",
|
|
485
|
+
indexerBinary: "scip-python",
|
|
486
|
+
checkCommand: "scip-python --version",
|
|
487
|
+
indexArgs: ({ outputPath }) => ({
|
|
488
|
+
binary: "scip-python",
|
|
489
|
+
args: ["index", "--output", outputPath, "--project-name", "project"]
|
|
490
|
+
}),
|
|
491
|
+
markerFiles: ["pyproject.toml", "setup.py"],
|
|
492
|
+
installMethods: [
|
|
493
|
+
{ label: "npm", prerequisite: "npm", binary: "npm", args: ["install", "-g", "scip-python-plus"] }
|
|
494
|
+
],
|
|
495
|
+
installUrl: "https://github.com/PlunderStruck/scip-python"
|
|
496
|
+
},
|
|
497
|
+
ruby: {
|
|
498
|
+
language: "ruby",
|
|
499
|
+
indexerBinary: "scip-ruby",
|
|
500
|
+
checkCommand: "scip-ruby --version",
|
|
501
|
+
indexArgs: ({ outputPath }) => ({
|
|
502
|
+
binary: "scip-ruby",
|
|
503
|
+
args: ["--output", outputPath]
|
|
504
|
+
}),
|
|
505
|
+
markerFiles: ["Gemfile"],
|
|
506
|
+
installMethods: [],
|
|
507
|
+
installUrl: "https://github.com/sourcegraph/scip-ruby/releases"
|
|
508
|
+
},
|
|
509
|
+
go: {
|
|
510
|
+
language: "go",
|
|
511
|
+
indexerBinary: "scip-go",
|
|
512
|
+
checkCommand: "scip-go --version",
|
|
513
|
+
indexArgs: ({ outputPath }) => ({
|
|
514
|
+
binary: "scip-go",
|
|
515
|
+
args: ["--output", outputPath]
|
|
516
|
+
}),
|
|
517
|
+
markerFiles: ["go.mod"],
|
|
518
|
+
installMethods: [
|
|
519
|
+
{ label: "go install", prerequisite: "go", binary: "go", args: ["install", "github.com/sourcegraph/scip-go@latest"] }
|
|
520
|
+
],
|
|
521
|
+
installUrl: "https://github.com/sourcegraph/scip-go"
|
|
522
|
+
},
|
|
523
|
+
cpp: {
|
|
524
|
+
language: "cpp",
|
|
525
|
+
indexerBinary: "scip-clang",
|
|
526
|
+
checkCommand: "scip-clang --version",
|
|
527
|
+
indexArgs: ({ outputPath }) => ({
|
|
528
|
+
binary: "scip-clang",
|
|
529
|
+
args: ["--output", outputPath]
|
|
530
|
+
}),
|
|
531
|
+
markerFiles: ["CMakeLists.txt", "Makefile"],
|
|
532
|
+
installMethods: [],
|
|
533
|
+
installUrl: "https://github.com/sourcegraph/scip-clang/releases"
|
|
534
|
+
},
|
|
535
|
+
c: {
|
|
536
|
+
language: "c",
|
|
537
|
+
indexerBinary: "scip-clang",
|
|
538
|
+
checkCommand: "scip-clang --version",
|
|
539
|
+
indexArgs: ({ outputPath }) => ({
|
|
540
|
+
binary: "scip-clang",
|
|
541
|
+
args: ["--output", outputPath]
|
|
542
|
+
}),
|
|
543
|
+
markerFiles: ["CMakeLists.txt", "Makefile"],
|
|
544
|
+
installMethods: [],
|
|
545
|
+
installUrl: "https://github.com/sourcegraph/scip-clang/releases"
|
|
546
|
+
},
|
|
547
|
+
csharp: {
|
|
548
|
+
language: "csharp",
|
|
549
|
+
indexerBinary: "scip-dotnet",
|
|
550
|
+
checkCommand: "scip-dotnet --version",
|
|
551
|
+
indexArgs: ({ outputPath }) => ({
|
|
552
|
+
binary: "scip-dotnet",
|
|
553
|
+
args: ["index", "--output", outputPath]
|
|
554
|
+
}),
|
|
555
|
+
markerFiles: [],
|
|
556
|
+
installMethods: [
|
|
557
|
+
{ label: "dotnet", prerequisite: "dotnet", binary: "dotnet", args: ["tool", "install", "--global", "scip-dotnet"] }
|
|
558
|
+
],
|
|
559
|
+
installUrl: "https://github.com/sourcegraph/scip-dotnet/releases"
|
|
560
|
+
},
|
|
561
|
+
dart: {
|
|
562
|
+
language: "dart",
|
|
563
|
+
indexerBinary: "scip-dart",
|
|
564
|
+
checkCommand: "scip-dart --version",
|
|
565
|
+
indexArgs: ({ outputPath }) => ({
|
|
566
|
+
binary: "scip-dart",
|
|
567
|
+
args: ["index", "--output", outputPath]
|
|
568
|
+
}),
|
|
569
|
+
markerFiles: ["pubspec.yaml"],
|
|
570
|
+
installMethods: [
|
|
571
|
+
{ label: "dart pub", prerequisite: "dart", binary: "dart", args: ["pub", "global", "activate", "scip_dart"] }
|
|
572
|
+
],
|
|
573
|
+
installUrl: "https://github.com/Workiva/scip-dart/releases"
|
|
574
|
+
},
|
|
575
|
+
php: {
|
|
576
|
+
language: "php",
|
|
577
|
+
indexerBinary: "scip-php",
|
|
578
|
+
checkCommand: "scip-php --version",
|
|
579
|
+
indexArgs: ({ outputPath }) => ({
|
|
580
|
+
binary: "scip-php",
|
|
581
|
+
args: ["index", "--output", outputPath]
|
|
582
|
+
}),
|
|
583
|
+
markerFiles: ["composer.json"],
|
|
584
|
+
installMethods: [
|
|
585
|
+
{ label: "composer", prerequisite: "composer", binary: "composer", args: ["global", "require", "davidrjenni/scip-php"] }
|
|
586
|
+
],
|
|
587
|
+
installUrl: "https://github.com/davidrjenni/scip-php/releases"
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
function getIndexerConfig(language) {
|
|
591
|
+
return INDEXER_CONFIGS[language];
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// src/reindex/install.ts
|
|
595
|
+
import { execFileSync } from "child_process";
|
|
596
|
+
import { platform } from "os";
|
|
597
|
+
var IS_WINDOWS = platform() === "win32";
|
|
598
|
+
function isBinaryAvailable(name) {
|
|
599
|
+
const cmd = IS_WINDOWS ? "where" : "which";
|
|
600
|
+
try {
|
|
601
|
+
execFileSync(cmd, [name], { stdio: "pipe" });
|
|
602
|
+
return true;
|
|
603
|
+
} catch {
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
function isIndexerInstalled(config) {
|
|
608
|
+
return isBinaryAvailable(config.indexerBinary);
|
|
609
|
+
}
|
|
610
|
+
function tryInstallIndexer(config, onStatus) {
|
|
611
|
+
const methods2 = config.installMethods;
|
|
612
|
+
if (!methods2?.length) {
|
|
613
|
+
onStatus(`No auto-install method available for ${config.indexerBinary}.`);
|
|
614
|
+
if (config.installUrl) {
|
|
615
|
+
onStatus(`Install manually from: ${config.installUrl}`);
|
|
616
|
+
}
|
|
617
|
+
return false;
|
|
618
|
+
}
|
|
619
|
+
for (const method of methods2) {
|
|
620
|
+
if (!isBinaryAvailable(method.prerequisite)) {
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
onStatus(`Installing ${config.indexerBinary} via ${method.label}...`);
|
|
624
|
+
try {
|
|
625
|
+
execFileSync(method.binary, method.args, {
|
|
626
|
+
stdio: "inherit",
|
|
627
|
+
timeout: 3e5,
|
|
628
|
+
env: process.env
|
|
629
|
+
});
|
|
630
|
+
if (isIndexerInstalled(config)) {
|
|
631
|
+
onStatus(`Successfully installed ${config.indexerBinary} via ${method.label}`);
|
|
632
|
+
return true;
|
|
633
|
+
}
|
|
634
|
+
onStatus(`${method.label} command completed but ${config.indexerBinary} not found on PATH`);
|
|
635
|
+
} catch (err) {
|
|
636
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
637
|
+
onStatus(`${method.label} install failed: ${msg}`);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
onStatus(`Could not auto-install ${config.indexerBinary}.`);
|
|
641
|
+
if (config.installUrl) {
|
|
642
|
+
onStatus(`Install manually from: ${config.installUrl}`);
|
|
643
|
+
}
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
function tryInstallScipCli(onStatus) {
|
|
647
|
+
if (platform() === "darwin" && isBinaryAvailable("brew")) {
|
|
648
|
+
onStatus("Installing scip CLI via Homebrew...");
|
|
649
|
+
try {
|
|
650
|
+
execFileSync("brew", ["install", "sourcegraph/scip/scip"], {
|
|
651
|
+
stdio: "inherit",
|
|
652
|
+
timeout: 3e5,
|
|
653
|
+
env: process.env
|
|
654
|
+
});
|
|
655
|
+
if (isBinaryAvailable("scip")) {
|
|
656
|
+
onStatus("Successfully installed scip CLI via Homebrew");
|
|
657
|
+
return true;
|
|
658
|
+
}
|
|
659
|
+
} catch (err) {
|
|
660
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
661
|
+
onStatus(`Homebrew install failed: ${msg}`);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (isBinaryAvailable("go")) {
|
|
665
|
+
onStatus("Installing scip CLI via go install...");
|
|
666
|
+
try {
|
|
667
|
+
execFileSync("go", ["install", "github.com/sourcegraph/scip/cmd/scip@latest"], {
|
|
668
|
+
stdio: "inherit",
|
|
669
|
+
timeout: 3e5,
|
|
670
|
+
env: process.env
|
|
671
|
+
});
|
|
672
|
+
if (isBinaryAvailable("scip")) {
|
|
673
|
+
onStatus("Successfully installed scip CLI via go install");
|
|
674
|
+
return true;
|
|
675
|
+
}
|
|
676
|
+
} catch (err) {
|
|
677
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
678
|
+
onStatus(`go install failed: ${msg}`);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
onStatus("Could not auto-install scip CLI.");
|
|
682
|
+
onStatus("Install manually from: https://github.com/sourcegraph/scip/releases");
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// src/reindex/index.ts
|
|
687
|
+
async function reindex(opts) {
|
|
688
|
+
const {
|
|
689
|
+
projectRoot,
|
|
690
|
+
maxHeapMb = 8192,
|
|
691
|
+
onStatus = console.log,
|
|
692
|
+
skipAutoInstall = false
|
|
693
|
+
} = opts;
|
|
694
|
+
const outputScip = opts.outputScip ?? join3(projectRoot, "index.scip");
|
|
695
|
+
const outputDb = opts.outputDb ?? join3(projectRoot, "index.db");
|
|
696
|
+
const start = Date.now();
|
|
697
|
+
const languages = opts.languages ?? detectLanguages(projectRoot);
|
|
698
|
+
if (languages.length === 0) {
|
|
699
|
+
throw new Error(
|
|
700
|
+
"No supported languages detected in this project. Looked for: tsconfig.json, Cargo.toml, go.mod, pyproject.toml, etc."
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
onStatus(`Detected languages: ${languages.join(", ")}`);
|
|
704
|
+
if (!isBinaryAvailable("scip")) {
|
|
705
|
+
if (skipAutoInstall) {
|
|
706
|
+
throw new Error(
|
|
707
|
+
"The scip CLI is required but not found on PATH.\nInstall from: https://github.com/sourcegraph/scip/releases"
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
onStatus("scip CLI not found on PATH. Attempting auto-install...");
|
|
711
|
+
if (!tryInstallScipCli(onStatus)) {
|
|
712
|
+
throw new Error(
|
|
713
|
+
"The scip CLI is required but could not be installed.\nInstall manually from: https://github.com/sourcegraph/scip/releases"
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
const env = {
|
|
718
|
+
...process.env,
|
|
719
|
+
NODE_OPTIONS: `--max-old-space-size=${maxHeapMb}`
|
|
720
|
+
};
|
|
721
|
+
for (const lang of languages) {
|
|
722
|
+
const config = getIndexerConfig(lang);
|
|
723
|
+
if (!isIndexerInstalled(config)) {
|
|
724
|
+
if (skipAutoInstall) {
|
|
725
|
+
throw new Error(
|
|
726
|
+
`${config.indexerBinary} is required to index ${lang} but not found on PATH.
|
|
727
|
+
` + (config.installUrl ? `Install from: ${config.installUrl}` : `Make sure ${config.indexerBinary} is installed and available on PATH.`)
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
onStatus(`${config.indexerBinary} not found. Attempting auto-install...`);
|
|
731
|
+
if (!tryInstallIndexer(config, onStatus)) {
|
|
732
|
+
throw new Error(
|
|
733
|
+
`${config.indexerBinary} is required to index ${lang} but could not be installed.
|
|
734
|
+
` + (config.installUrl ? `Install manually from: ${config.installUrl}` : `Make sure ${config.indexerBinary} is installed and available on PATH.`)
|
|
735
|
+
);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
onStatus(`Indexing ${lang} with ${config.indexerBinary}...`);
|
|
739
|
+
const { binary, args } = config.indexArgs({
|
|
740
|
+
projectRoot,
|
|
741
|
+
outputPath: outputScip,
|
|
742
|
+
pnpmWorkspaces: opts.pnpmWorkspaces
|
|
743
|
+
});
|
|
744
|
+
try {
|
|
745
|
+
execFileSync2(binary, args, {
|
|
746
|
+
cwd: projectRoot,
|
|
747
|
+
env,
|
|
748
|
+
stdio: "pipe",
|
|
749
|
+
maxBuffer: 50 * 1024 * 1024
|
|
750
|
+
});
|
|
751
|
+
} catch (err) {
|
|
752
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
753
|
+
throw new Error(
|
|
754
|
+
`Failed to index ${lang} with ${config.indexerBinary}: ${msg}
|
|
755
|
+
Make sure ${config.indexerBinary} is installed and available on PATH.`
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
onStatus("Converting to SQLite...");
|
|
760
|
+
if (!existsSync3(outputScip)) {
|
|
761
|
+
throw new Error(`SCIP index not found at ${outputScip} after indexing`);
|
|
762
|
+
}
|
|
763
|
+
try {
|
|
764
|
+
execFileSync2("scip", ["expt-convert", "--output", outputDb, outputScip], {
|
|
765
|
+
env,
|
|
766
|
+
stdio: "pipe",
|
|
767
|
+
maxBuffer: 50 * 1024 * 1024
|
|
768
|
+
});
|
|
769
|
+
} catch (err) {
|
|
770
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
771
|
+
throw new Error(`Failed to convert SCIP index to SQLite: ${msg}`);
|
|
772
|
+
}
|
|
773
|
+
const durationMs = Date.now() - start;
|
|
774
|
+
onStatus(`Done in ${(durationMs / 1e3).toFixed(1)}s`);
|
|
775
|
+
return { languages, indexPath: outputScip, dbPath: outputDb, durationMs };
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// src/config.ts
|
|
779
|
+
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync4, mkdirSync } from "fs";
|
|
780
|
+
import { join as join4, resolve } from "path";
|
|
781
|
+
import { createHash } from "crypto";
|
|
782
|
+
import { homedir } from "os";
|
|
783
|
+
var CONFIG_FILENAME = ".scipquery.json";
|
|
784
|
+
var DEFAULT_WATCH = {
|
|
785
|
+
enabled: false,
|
|
786
|
+
debounceMs: 3e4,
|
|
787
|
+
cooldownMs: 6e4,
|
|
788
|
+
ignore: []
|
|
789
|
+
};
|
|
790
|
+
function loadProjectConfig(projectRoot) {
|
|
791
|
+
const configPath = join4(projectRoot, CONFIG_FILENAME);
|
|
792
|
+
if (!existsSync4(configPath)) {
|
|
793
|
+
return {};
|
|
794
|
+
}
|
|
795
|
+
try {
|
|
796
|
+
const raw = readFileSync2(configPath, "utf-8");
|
|
797
|
+
return JSON.parse(raw);
|
|
798
|
+
} catch {
|
|
799
|
+
return {};
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
function resolveWatchConfig(config) {
|
|
803
|
+
return {
|
|
804
|
+
...DEFAULT_WATCH,
|
|
805
|
+
...config.watch
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
function resolveCacheDir(projectRoot, config) {
|
|
809
|
+
const envOverride = process.env["SCIP_QUERY_CACHE_DIR"];
|
|
810
|
+
if (envOverride) return ensureDir(envOverride);
|
|
811
|
+
if (config?.dbPath) return ensureDir(resolve(projectRoot, config.dbPath));
|
|
812
|
+
const xdgCache = process.env["XDG_CACHE_HOME"];
|
|
813
|
+
const cacheBase = xdgCache || join4(homedir(), ".cache");
|
|
814
|
+
const projectHash = createHash("sha256").update(resolve(projectRoot)).digest("hex").slice(0, 12);
|
|
815
|
+
const dir = join4(cacheBase, "scip-query", "projects", projectHash);
|
|
816
|
+
return ensureDir(dir);
|
|
817
|
+
}
|
|
818
|
+
function resolveIndexPaths(projectRoot, config) {
|
|
819
|
+
const cacheDir = resolveCacheDir(projectRoot, config);
|
|
820
|
+
return {
|
|
821
|
+
cacheDir,
|
|
822
|
+
dbPath: join4(cacheDir, "index.db"),
|
|
823
|
+
indexPath: join4(cacheDir, "index.scip"),
|
|
824
|
+
metaPath: join4(cacheDir, "meta.json")
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
function initProjectConfig(projectRoot, languages) {
|
|
828
|
+
const configPath = join4(projectRoot, CONFIG_FILENAME);
|
|
829
|
+
if (existsSync4(configPath)) {
|
|
830
|
+
return configPath;
|
|
831
|
+
}
|
|
832
|
+
const config = {
|
|
833
|
+
languages,
|
|
834
|
+
watch: {
|
|
835
|
+
enabled: false,
|
|
836
|
+
debounceMs: 3e4,
|
|
837
|
+
cooldownMs: 6e4
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
841
|
+
return configPath;
|
|
842
|
+
}
|
|
843
|
+
function ensureDir(dir) {
|
|
844
|
+
mkdirSync(dir, { recursive: true });
|
|
845
|
+
return dir;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// src/watch.ts
|
|
849
|
+
import { watch } from "fs";
|
|
850
|
+
import { existsSync as existsSync5, renameSync } from "fs";
|
|
851
|
+
import { join as join5, relative } from "path";
|
|
852
|
+
import { fork } from "child_process";
|
|
853
|
+
import ignore2 from "ignore";
|
|
854
|
+
var Watcher = class {
|
|
855
|
+
projectRoot;
|
|
856
|
+
watchConfig;
|
|
857
|
+
indexPaths;
|
|
858
|
+
languages;
|
|
859
|
+
pnpmWorkspaces;
|
|
860
|
+
onStatus;
|
|
861
|
+
onReindexComplete;
|
|
862
|
+
onError;
|
|
863
|
+
// State machine
|
|
864
|
+
status = { state: "idle" };
|
|
865
|
+
debounceTimer = null;
|
|
866
|
+
cooldownTimer = null;
|
|
867
|
+
dirty = false;
|
|
868
|
+
changedFiles = 0;
|
|
869
|
+
reindexInFlight = false;
|
|
870
|
+
lastReindexEnd = 0;
|
|
871
|
+
// fs.watch watchers (one per watched directory)
|
|
872
|
+
fsWatchers = [];
|
|
873
|
+
gitignoreFilter;
|
|
874
|
+
extraIgnore;
|
|
875
|
+
stopped = false;
|
|
876
|
+
constructor(opts) {
|
|
877
|
+
this.projectRoot = opts.projectRoot;
|
|
878
|
+
this.watchConfig = resolveWatchConfig(opts.config);
|
|
879
|
+
this.indexPaths = resolveIndexPaths(opts.projectRoot, opts.config);
|
|
880
|
+
this.languages = opts.languages;
|
|
881
|
+
this.pnpmWorkspaces = opts.config.indexer?.typescript?.pnpmWorkspaces ?? false;
|
|
882
|
+
this.onStatus = opts.onStatus ?? (() => {
|
|
883
|
+
});
|
|
884
|
+
this.onReindexComplete = opts.onReindexComplete ?? (() => {
|
|
885
|
+
});
|
|
886
|
+
this.onError = opts.onError ?? ((e) => console.error(e.message));
|
|
887
|
+
this.gitignoreFilter = createGitignoreFilter(opts.projectRoot);
|
|
888
|
+
this.extraIgnore = ignore2();
|
|
889
|
+
if (this.watchConfig.ignore.length > 0) {
|
|
890
|
+
this.extraIgnore.add(this.watchConfig.ignore);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
/** Start watching for file changes */
|
|
894
|
+
start() {
|
|
895
|
+
this.stopped = false;
|
|
896
|
+
this.setStatus({ state: "idle" });
|
|
897
|
+
try {
|
|
898
|
+
const watcher = watch(
|
|
899
|
+
this.projectRoot,
|
|
900
|
+
{ recursive: true },
|
|
901
|
+
(_event, filename) => {
|
|
902
|
+
if (filename && !this.stopped) {
|
|
903
|
+
this.handleFileChange(filename);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
);
|
|
907
|
+
this.fsWatchers.push(watcher);
|
|
908
|
+
} catch {
|
|
909
|
+
this.onError(new Error(
|
|
910
|
+
"Failed to start file watcher. On Linux, you may need to increase inotify limits: sysctl -w fs.inotify.max_user_watches=524288"
|
|
911
|
+
));
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
/** Stop watching and clean up */
|
|
915
|
+
stop() {
|
|
916
|
+
this.stopped = true;
|
|
917
|
+
for (const w of this.fsWatchers) w.close();
|
|
918
|
+
this.fsWatchers = [];
|
|
919
|
+
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
920
|
+
if (this.cooldownTimer) clearTimeout(this.cooldownTimer);
|
|
921
|
+
this.setStatus({ state: "idle" });
|
|
922
|
+
}
|
|
923
|
+
/** Get current watcher status */
|
|
924
|
+
getStatus() {
|
|
925
|
+
return this.status;
|
|
926
|
+
}
|
|
927
|
+
// ── Internal ─────────────────────────────────────────────
|
|
928
|
+
handleFileChange(filename) {
|
|
929
|
+
const rel = relative(this.projectRoot, join5(this.projectRoot, filename));
|
|
930
|
+
if (this.gitignoreFilter.isIgnored(rel)) return;
|
|
931
|
+
if (this.extraIgnore.ignores(rel)) return;
|
|
932
|
+
if (filename.endsWith("index.db") || filename.endsWith("index.scip") || filename.endsWith("index.db.tmp") || filename.endsWith(".scipquery.json")) {
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
this.changedFiles++;
|
|
936
|
+
if (this.reindexInFlight) {
|
|
937
|
+
this.dirty = true;
|
|
938
|
+
this.setStatus({
|
|
939
|
+
state: "indexing",
|
|
940
|
+
startedAt: this.status.startedAt
|
|
941
|
+
});
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (this.status.state === "cooldown") {
|
|
945
|
+
this.dirty = true;
|
|
946
|
+
this.setStatus({ state: "cooldown", until: this.status.until, dirty: true });
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
if (this.debounceTimer) clearTimeout(this.debounceTimer);
|
|
950
|
+
const reindexAt = Date.now() + this.watchConfig.debounceMs;
|
|
951
|
+
this.setStatus({ state: "waiting", changedFiles: this.changedFiles, reindexAt });
|
|
952
|
+
this.debounceTimer = setTimeout(() => {
|
|
953
|
+
this.debounceTimer = null;
|
|
954
|
+
this.triggerReindex();
|
|
955
|
+
}, this.watchConfig.debounceMs);
|
|
956
|
+
}
|
|
957
|
+
triggerReindex() {
|
|
958
|
+
if (this.reindexInFlight || this.stopped) return;
|
|
959
|
+
const timeSinceLastReindex = Date.now() - this.lastReindexEnd;
|
|
960
|
+
if (this.lastReindexEnd > 0 && timeSinceLastReindex < this.watchConfig.cooldownMs) {
|
|
961
|
+
const remaining = this.watchConfig.cooldownMs - timeSinceLastReindex;
|
|
962
|
+
this.dirty = true;
|
|
963
|
+
const until = Date.now() + remaining;
|
|
964
|
+
this.setStatus({ state: "cooldown", until, dirty: true });
|
|
965
|
+
this.cooldownTimer = setTimeout(() => {
|
|
966
|
+
this.cooldownTimer = null;
|
|
967
|
+
if (this.dirty && !this.stopped) {
|
|
968
|
+
this.dirty = false;
|
|
969
|
+
this.triggerReindex();
|
|
970
|
+
}
|
|
971
|
+
}, remaining);
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
this.reindexInFlight = true;
|
|
975
|
+
this.dirty = false;
|
|
976
|
+
this.changedFiles = 0;
|
|
977
|
+
const startedAt = Date.now();
|
|
978
|
+
this.setStatus({ state: "indexing", startedAt });
|
|
979
|
+
this.runReindex().then((durationMs) => {
|
|
980
|
+
this.reindexInFlight = false;
|
|
981
|
+
this.lastReindexEnd = Date.now();
|
|
982
|
+
this.onReindexComplete(durationMs);
|
|
983
|
+
if (this.dirty && !this.stopped) {
|
|
984
|
+
const until = Date.now() + this.watchConfig.cooldownMs;
|
|
985
|
+
this.setStatus({ state: "cooldown", until, dirty: true });
|
|
986
|
+
this.cooldownTimer = setTimeout(() => {
|
|
987
|
+
this.cooldownTimer = null;
|
|
988
|
+
if (this.dirty && !this.stopped) {
|
|
989
|
+
this.dirty = false;
|
|
990
|
+
this.triggerReindex();
|
|
991
|
+
} else {
|
|
992
|
+
this.setStatus({ state: "idle" });
|
|
993
|
+
}
|
|
994
|
+
}, this.watchConfig.cooldownMs);
|
|
995
|
+
} else {
|
|
996
|
+
this.setStatus({ state: "idle" });
|
|
997
|
+
}
|
|
998
|
+
}).catch((err) => {
|
|
999
|
+
this.reindexInFlight = false;
|
|
1000
|
+
this.lastReindexEnd = Date.now();
|
|
1001
|
+
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
1002
|
+
this.setStatus({ state: "idle" });
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Run the reindex in a forked child process.
|
|
1007
|
+
* Writes to index.db.tmp, then atomically renames to index.db.
|
|
1008
|
+
*/
|
|
1009
|
+
runReindex() {
|
|
1010
|
+
return new Promise((resolve3, reject) => {
|
|
1011
|
+
const start = Date.now();
|
|
1012
|
+
const tmpDb = this.indexPaths.dbPath + ".tmp";
|
|
1013
|
+
const tmpScip = this.indexPaths.indexPath + ".tmp";
|
|
1014
|
+
const child = fork(
|
|
1015
|
+
new URL("./reindex-worker.js", import.meta.url).pathname,
|
|
1016
|
+
[],
|
|
1017
|
+
{
|
|
1018
|
+
env: {
|
|
1019
|
+
...process.env,
|
|
1020
|
+
SCIP_REINDEX_PROJECT_ROOT: this.projectRoot,
|
|
1021
|
+
SCIP_REINDEX_OUTPUT_SCIP: tmpScip,
|
|
1022
|
+
SCIP_REINDEX_OUTPUT_DB: tmpDb,
|
|
1023
|
+
SCIP_REINDEX_LANGUAGES: this.languages?.join(",") ?? "",
|
|
1024
|
+
SCIP_REINDEX_PNPM_WORKSPACES: this.pnpmWorkspaces ? "1" : ""
|
|
1025
|
+
},
|
|
1026
|
+
stdio: "pipe"
|
|
1027
|
+
}
|
|
1028
|
+
);
|
|
1029
|
+
child.on("exit", (code2) => {
|
|
1030
|
+
if (code2 === 0) {
|
|
1031
|
+
try {
|
|
1032
|
+
if (existsSync5(tmpDb)) {
|
|
1033
|
+
renameSync(tmpDb, this.indexPaths.dbPath);
|
|
1034
|
+
}
|
|
1035
|
+
if (existsSync5(tmpScip)) {
|
|
1036
|
+
renameSync(tmpScip, this.indexPaths.indexPath);
|
|
1037
|
+
}
|
|
1038
|
+
resolve3(Date.now() - start);
|
|
1039
|
+
} catch (err) {
|
|
1040
|
+
reject(new Error(`Atomic swap failed: ${err}`));
|
|
1041
|
+
}
|
|
1042
|
+
} else {
|
|
1043
|
+
reject(new Error(`Reindex worker exited with code ${code2}`));
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
child.on("error", reject);
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
setStatus(status) {
|
|
1050
|
+
this.status = status;
|
|
1051
|
+
this.onStatus(status);
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
|
|
1055
|
+
// src/setup.ts
|
|
1056
|
+
import {
|
|
1057
|
+
existsSync as existsSync6,
|
|
1058
|
+
mkdirSync as mkdirSync2,
|
|
1059
|
+
symlinkSync,
|
|
1060
|
+
readlinkSync,
|
|
1061
|
+
unlinkSync
|
|
1062
|
+
} from "fs";
|
|
1063
|
+
import { join as join6, dirname as dirname2, resolve as resolve2 } from "path";
|
|
1064
|
+
import { homedir as homedir2, platform as platform2, arch } from "os";
|
|
1065
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
1066
|
+
import { fileURLToPath } from "url";
|
|
1067
|
+
var IS_WINDOWS2 = platform2() === "win32";
|
|
1068
|
+
var SKILLS = ["concrete-plan", "scip-explore", "scip-debloat", "scip-verify"];
|
|
1069
|
+
var SCIP_VERSION = "v0.7.0";
|
|
1070
|
+
function installSkills(opts = {}) {
|
|
1071
|
+
const log = opts.quiet ? () => {
|
|
1072
|
+
} : console.log;
|
|
1073
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
1074
|
+
const skillsSource = resolve2(dirname2(thisFile), "..", "skills");
|
|
1075
|
+
const targets = [
|
|
1076
|
+
join6(homedir2(), ".claude", "skills"),
|
|
1077
|
+
join6(homedir2(), ".codex", "skills")
|
|
1078
|
+
];
|
|
1079
|
+
const result = {
|
|
1080
|
+
installed: [],
|
|
1081
|
+
skipped: [],
|
|
1082
|
+
alreadyLinked: []
|
|
1083
|
+
};
|
|
1084
|
+
for (const targetDir of targets) {
|
|
1085
|
+
const parentDir = dirname2(targetDir);
|
|
1086
|
+
if (!existsSync6(parentDir)) {
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
mkdirSync2(targetDir, { recursive: true });
|
|
1090
|
+
const toolName = targetDir.includes(".codex") ? "Codex" : "Claude";
|
|
1091
|
+
for (const skill of SKILLS) {
|
|
1092
|
+
const source = join6(skillsSource, skill);
|
|
1093
|
+
const target = join6(targetDir, skill);
|
|
1094
|
+
if (!existsSync6(source)) {
|
|
1095
|
+
result.skipped.push(`${toolName}/${skill}`);
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
if (existsSync6(target)) {
|
|
1099
|
+
try {
|
|
1100
|
+
const existing = readlinkSync(target);
|
|
1101
|
+
if (resolve2(existing) === resolve2(source)) {
|
|
1102
|
+
result.alreadyLinked.push(`${toolName}/${skill}`);
|
|
1103
|
+
log(` ok: ${skill} \u2192 ${toolName} (already linked)`);
|
|
1104
|
+
continue;
|
|
1105
|
+
}
|
|
1106
|
+
} catch {
|
|
1107
|
+
result.skipped.push(`${toolName}/${skill}`);
|
|
1108
|
+
log(` skip: ${skill} \u2192 ${toolName} (exists, not a symlink)`);
|
|
1109
|
+
continue;
|
|
1110
|
+
}
|
|
1111
|
+
unlinkSync(target);
|
|
1112
|
+
}
|
|
1113
|
+
symlinkSync(source, target, IS_WINDOWS2 ? "junction" : "dir");
|
|
1114
|
+
result.installed.push(`${toolName}/${skill}`);
|
|
1115
|
+
log(` done: ${skill} \u2192 ${toolName}`);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
return result;
|
|
1119
|
+
}
|
|
1120
|
+
function isScipInstalled() {
|
|
1121
|
+
try {
|
|
1122
|
+
const cmd = IS_WINDOWS2 ? "where" : "which";
|
|
1123
|
+
execFileSync3(cmd, ["scip"], { stdio: "pipe" });
|
|
1124
|
+
return true;
|
|
1125
|
+
} catch {
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
function getScipVersion() {
|
|
1130
|
+
try {
|
|
1131
|
+
const output = execFileSync3("scip", ["--version"], { stdio: "pipe" }).toString().trim();
|
|
1132
|
+
return output;
|
|
1133
|
+
} catch {
|
|
1134
|
+
return null;
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
function getScipDownloadUrl() {
|
|
1138
|
+
const os = platform2();
|
|
1139
|
+
const cpu = arch();
|
|
1140
|
+
let osName;
|
|
1141
|
+
let archName;
|
|
1142
|
+
let ext;
|
|
1143
|
+
switch (os) {
|
|
1144
|
+
case "darwin":
|
|
1145
|
+
osName = "darwin";
|
|
1146
|
+
ext = "tar.gz";
|
|
1147
|
+
break;
|
|
1148
|
+
case "linux":
|
|
1149
|
+
osName = "linux";
|
|
1150
|
+
ext = "tar.gz";
|
|
1151
|
+
break;
|
|
1152
|
+
case "win32":
|
|
1153
|
+
osName = "windows";
|
|
1154
|
+
ext = "zip";
|
|
1155
|
+
break;
|
|
1156
|
+
default:
|
|
1157
|
+
return null;
|
|
1158
|
+
}
|
|
1159
|
+
switch (cpu) {
|
|
1160
|
+
case "arm64":
|
|
1161
|
+
archName = "arm64";
|
|
1162
|
+
break;
|
|
1163
|
+
case "x64":
|
|
1164
|
+
archName = "amd64";
|
|
1165
|
+
break;
|
|
1166
|
+
default:
|
|
1167
|
+
return null;
|
|
1168
|
+
}
|
|
1169
|
+
const filename = `scip-${osName}-${archName}.${ext}`;
|
|
1170
|
+
const url = `https://github.com/sourcegraph/scip/releases/download/${SCIP_VERSION}/${filename}`;
|
|
1171
|
+
return { url, filename };
|
|
1172
|
+
}
|
|
1173
|
+
function printScipInstallInstructions() {
|
|
1174
|
+
const download = getScipDownloadUrl();
|
|
1175
|
+
console.log("\nThe `scip` CLI is required but not found on PATH.\n");
|
|
1176
|
+
if (platform2() === "darwin") {
|
|
1177
|
+
console.log("Install via Homebrew:");
|
|
1178
|
+
console.log(" brew install sourcegraph/scip/scip\n");
|
|
1179
|
+
console.log("Or download manually:");
|
|
1180
|
+
} else {
|
|
1181
|
+
console.log("Download from:");
|
|
1182
|
+
}
|
|
1183
|
+
if (download) {
|
|
1184
|
+
console.log(` ${download.url}
|
|
1185
|
+
`);
|
|
1186
|
+
} else {
|
|
1187
|
+
console.log(` https://github.com/sourcegraph/scip/releases/tag/${SCIP_VERSION}
|
|
1188
|
+
`);
|
|
1189
|
+
}
|
|
1190
|
+
console.log("After installing, ensure `scip` is on your PATH and run `scip-query reindex`.");
|
|
1191
|
+
}
|
|
1192
|
+
export {
|
|
1193
|
+
INDEXER_CONFIGS,
|
|
1194
|
+
ScipDatabase,
|
|
1195
|
+
Watcher,
|
|
1196
|
+
affected,
|
|
1197
|
+
bottlenecks,
|
|
1198
|
+
byKind,
|
|
1199
|
+
callGraph,
|
|
1200
|
+
changeSurface,
|
|
1201
|
+
code,
|
|
1202
|
+
complexity,
|
|
1203
|
+
complexityHotspots,
|
|
1204
|
+
convergence,
|
|
1205
|
+
coupling,
|
|
1206
|
+
createGitignoreFilter,
|
|
1207
|
+
cycles,
|
|
1208
|
+
dataflow,
|
|
1209
|
+
dead,
|
|
1210
|
+
deepChains,
|
|
1211
|
+
deps,
|
|
1212
|
+
detectLanguages,
|
|
1213
|
+
diffImpact,
|
|
1214
|
+
docCoverage,
|
|
1215
|
+
drift,
|
|
1216
|
+
extractCandidates,
|
|
1217
|
+
fanIn,
|
|
1218
|
+
fanOut,
|
|
1219
|
+
files,
|
|
1220
|
+
getIndexerConfig,
|
|
1221
|
+
getScipVersion,
|
|
1222
|
+
health,
|
|
1223
|
+
hierarchy,
|
|
1224
|
+
hotspots,
|
|
1225
|
+
importedBy,
|
|
1226
|
+
imports,
|
|
1227
|
+
initProjectConfig,
|
|
1228
|
+
installSkills,
|
|
1229
|
+
isBinaryAvailable,
|
|
1230
|
+
isIndexerInstalled,
|
|
1231
|
+
isScipInstalled,
|
|
1232
|
+
isolated,
|
|
1233
|
+
kindCounts,
|
|
1234
|
+
leafName,
|
|
1235
|
+
loadProjectConfig,
|
|
1236
|
+
members,
|
|
1237
|
+
methods,
|
|
1238
|
+
outline,
|
|
1239
|
+
parseSymbol,
|
|
1240
|
+
passthroughCandidates,
|
|
1241
|
+
printScipInstallInstructions,
|
|
1242
|
+
rdeps,
|
|
1243
|
+
redundantReexports,
|
|
1244
|
+
refs,
|
|
1245
|
+
reindex,
|
|
1246
|
+
resolveCacheDir,
|
|
1247
|
+
resolveIndexPaths,
|
|
1248
|
+
shortenSymbol,
|
|
1249
|
+
similar,
|
|
1250
|
+
similarAll,
|
|
1251
|
+
similarChains,
|
|
1252
|
+
similarFiles,
|
|
1253
|
+
similarSignatures,
|
|
1254
|
+
slice,
|
|
1255
|
+
staleAbstractions,
|
|
1256
|
+
stats,
|
|
1257
|
+
surface,
|
|
1258
|
+
symbols,
|
|
1259
|
+
system,
|
|
1260
|
+
testCoverage,
|
|
1261
|
+
testCoverageSummary,
|
|
1262
|
+
topCoupling,
|
|
1263
|
+
topFanIn,
|
|
1264
|
+
topFanOut,
|
|
1265
|
+
trace,
|
|
1266
|
+
tryInstallIndexer,
|
|
1267
|
+
tryInstallScipCli,
|
|
1268
|
+
unusedImports,
|
|
1269
|
+
wrapperCandidates
|
|
1270
|
+
};
|
|
1271
|
+
//# sourceMappingURL=index.js.map
|