scip-query 0.3.5 → 0.4.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 +1 -0
- package/dist/{chunk-6FKIA6EI.js → chunk-2F2WH5WQ.js} +12 -12
- package/dist/{chunk-C7H5WBTJ.js → chunk-2UISVZGQ.js} +2 -2
- package/dist/{chunk-EN2Z2CLO.js → chunk-4ZT7UGWW.js} +16 -19
- package/dist/chunk-5AJJGPZE.js +60 -0
- package/dist/chunk-5RKYZSQ6.js +75 -0
- package/dist/chunk-7YBLWIXY.js +115 -0
- package/dist/{chunk-O7Q7FDUJ.js → chunk-A4GWYETB.js} +2 -2
- package/dist/{chunk-CHDJXYBG.js → chunk-A5BGEBM7.js} +2 -2
- package/dist/{chunk-KKCHYLVI.js → chunk-A7YY7IDA.js} +2 -2
- package/dist/chunk-AS7N27JK.js +115 -0
- package/dist/{chunk-F7XU27LU.js → chunk-CQRYLK33.js} +26 -2
- package/dist/{chunk-NFS5W3PP.js → chunk-CQUNEJYM.js} +2 -2
- package/dist/chunk-D4I3ZMN5.js +38 -0
- package/dist/{chunk-J3JSOSUO.js → chunk-E7J7Q7UW.js} +2 -2
- package/dist/{chunk-GEXE2T6I.js → chunk-EOHPASDV.js} +22 -14
- package/dist/chunk-GIBETK3W.js +37 -0
- package/dist/{chunk-SMDCNPMK.js → chunk-H3FPW5YN.js} +2 -2
- package/dist/{chunk-VMM4SYV4.js → chunk-HNURMDF4.js} +16 -3
- package/dist/{chunk-7KIMF5PV.js → chunk-HRDPUTIQ.js} +2 -2
- package/dist/{chunk-OIDHN6GD.js → chunk-I2JM34UV.js} +146 -5
- package/dist/{chunk-EPWLXXBL.js → chunk-IV6NZ426.js} +27 -29
- package/dist/{chunk-VT4JBH6L.js → chunk-KDCQJTYW.js} +2 -2
- package/dist/{chunk-5OMVSV6E.js → chunk-LOVDB4C6.js} +2 -2
- package/dist/chunk-MA3B3IUT.js +75 -0
- package/dist/{chunk-26DOJ63W.js → chunk-N2LH3M2P.js} +13 -2
- package/dist/chunk-NWCJWA36.js +162 -0
- package/dist/{chunk-NG5F43OU.js → chunk-P3VCDYMJ.js} +70 -1
- package/dist/{chunk-P3E6L7KW.js → chunk-P42KQKJZ.js} +83 -3
- package/dist/{chunk-YDBXNPYU.js → chunk-PGHN5UTM.js} +2 -2
- package/dist/{chunk-UGQKAVCD.js → chunk-QCYR4S6T.js} +2 -2
- package/dist/chunk-QGCEAVJD.js +2529 -0
- package/dist/{chunk-KBOQX573.js → chunk-RIEA5DOB.js} +19 -2
- package/dist/{chunk-VIYSWZCO.js → chunk-SL674KAW.js} +31 -3
- package/dist/chunk-SRELHCMG.js +110 -0
- package/dist/chunk-UTRKBUCB.js +87 -0
- package/dist/{chunk-TRESG7OB.js → chunk-VCOJRQPP.js} +2 -2
- package/dist/chunk-VISMEWYP.js +34 -0
- package/dist/{chunk-LFJQVJYJ.js → chunk-VU7FDTWV.js} +2 -2
- package/dist/{chunk-HLUS2HEB.js → chunk-VUBLUTMU.js} +5 -4
- package/dist/{chunk-WGAD3GNR.js → chunk-WNPF2I25.js} +5 -5
- package/dist/{chunk-YY4QGUQ5.js → chunk-X3J4VPWM.js} +2 -2
- package/dist/{chunk-GSH2FPKV.js → chunk-XH56HXLC.js} +2 -2
- package/dist/{chunk-DH7G3DDV.js → chunk-ZU2AQQB5.js} +2 -2
- package/dist/cli.js +2607 -805
- package/dist/{db-viWlyVtv.d.ts → db-C4rPbKkI.d.ts} +6 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +371 -138
- package/dist/postinstall.js +9 -3
- package/dist/queries/affected.d.ts +1 -1
- package/dist/queries/affected.js +2 -2
- package/dist/queries/bottlenecks.d.ts +1 -1
- package/dist/queries/bottlenecks.js +2 -1
- package/dist/queries/by-kind.d.ts +1 -1
- package/dist/queries/by-kind.js +2 -1
- package/dist/queries/call-graph.d.ts +1 -1
- package/dist/queries/call-graph.js +2 -2
- package/dist/queries/change-surface.d.ts +1 -1
- package/dist/queries/change-surface.js +2 -2
- package/dist/queries/code.d.ts +1 -1
- package/dist/queries/code.js +2 -2
- package/dist/queries/complexity-hotspots.d.ts +1 -1
- package/dist/queries/complexity-hotspots.js +2 -2
- package/dist/queries/complexity.d.ts +1 -1
- package/dist/queries/complexity.js +2 -2
- package/dist/queries/convergence.d.ts +1 -1
- package/dist/queries/convergence.js +2 -2
- package/dist/queries/coupling.d.ts +1 -1
- package/dist/queries/coupling.js +2 -2
- package/dist/queries/cycles.d.ts +1 -1
- package/dist/queries/cycles.js +2 -2
- package/dist/queries/dataflow.d.ts +1 -1
- package/dist/queries/dataflow.js +2 -2
- package/dist/queries/dead.d.ts +1 -1
- package/dist/queries/dead.js +3 -3
- package/dist/queries/deep-chains.d.ts +1 -1
- package/dist/queries/deep-chains.js +2 -2
- package/dist/queries/deps.d.ts +1 -1
- package/dist/queries/deps.js +2 -2
- package/dist/queries/diff-impact.d.ts +1 -1
- package/dist/queries/drift.d.ts +1 -1
- package/dist/queries/drift.js +2 -2
- package/dist/queries/extract-candidates.d.ts +1 -1
- package/dist/queries/extract-candidates.js +2 -2
- package/dist/queries/fan.d.ts +1 -1
- package/dist/queries/fan.js +2 -2
- package/dist/queries/files.d.ts +1 -1
- package/dist/queries/health.d.ts +1 -1
- package/dist/queries/health.js +13 -13
- package/dist/queries/hierarchy.d.ts +1 -1
- package/dist/queries/hierarchy.js +2 -2
- package/dist/queries/hotspots.d.ts +1 -1
- package/dist/queries/hotspots.js +2 -1
- package/dist/queries/imports.d.ts +1 -1
- package/dist/queries/imports.js +2 -2
- package/dist/queries/index.d.ts +1 -1
- package/dist/queries/index.js +42 -42
- package/dist/queries/isolated.d.ts +3 -4
- package/dist/queries/isolated.js +3 -3
- package/dist/queries/members.d.ts +1 -1
- package/dist/queries/members.js +2 -2
- package/dist/queries/methods.d.ts +1 -1
- package/dist/queries/methods.js +2 -1
- package/dist/queries/outline.d.ts +1 -1
- package/dist/queries/outline.js +2 -2
- package/dist/queries/passthrough-candidates.d.ts +1 -1
- package/dist/queries/passthrough-candidates.js +2 -2
- package/dist/queries/redundant-reexports.d.ts +1 -1
- package/dist/queries/redundant-reexports.js +3 -3
- package/dist/queries/refs.d.ts +1 -1
- package/dist/queries/refs.js +2 -2
- package/dist/queries/similar-chains.d.ts +1 -1
- package/dist/queries/similar-chains.js +2 -2
- package/dist/queries/similar-files.d.ts +1 -1
- package/dist/queries/similar-files.js +2 -2
- package/dist/queries/similar-signatures.d.ts +5 -3
- package/dist/queries/similar-signatures.js +2 -1
- package/dist/queries/similar.d.ts +1 -1
- package/dist/queries/similar.js +2 -2
- package/dist/queries/slice.d.ts +1 -1
- package/dist/queries/slice.js +2 -2
- package/dist/queries/stale-abstractions.d.ts +1 -1
- package/dist/queries/stale-abstractions.js +2 -2
- package/dist/queries/stats.d.ts +1 -1
- package/dist/queries/surface.d.ts +1 -1
- package/dist/queries/surface.js +2 -2
- package/dist/queries/symbols.d.ts +1 -1
- package/dist/queries/symbols.js +2 -2
- package/dist/queries/system.d.ts +1 -1
- package/dist/queries/system.js +2 -2
- package/dist/queries/trace.d.ts +1 -1
- package/dist/queries/trace.js +2 -2
- package/dist/queries/wrapper-candidates.d.ts +1 -1
- package/dist/queries/wrapper-candidates.js +2 -2
- package/dist/reindex-worker.js +213 -62
- package/package.json +1 -1
- package/skills/scip-language-playbook/SKILL.md +371 -0
- package/dist/chunk-4JCSOF2O.js +0 -97
- package/dist/chunk-AXQKUYKF.js +0 -1442
- package/dist/chunk-CPVAQJEC.js +0 -46
- package/dist/chunk-EOROMIFO.js +0 -41
- package/dist/chunk-GU2H5QRN.js +0 -28
- package/dist/chunk-LQJUPXQY.js +0 -109
- package/dist/chunk-MPGIHELS.js +0 -39
- package/dist/chunk-TOIEB3LG.js +0 -78
- package/dist/chunk-UQEQ6AHX.js +0 -60
- package/dist/chunk-VJJKSGIX.js +0 -121
- package/dist/chunk-YGGFLMTM.js +0 -83
- package/dist/chunk-ZEUCXQBN.js +0 -71
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ For goal-oriented usage guides (not just command reference), see **[Agent Guide]
|
|
|
19
19
|
```bash
|
|
20
20
|
# Install
|
|
21
21
|
npm install -g scip-query
|
|
22
|
+
scip-query install-skills # installs built-in Codex/Claude skills, including scip-language-playbook
|
|
22
23
|
|
|
23
24
|
# Index your project (auto-detects language)
|
|
24
25
|
scip-query reindex
|
|
@@ -3,37 +3,37 @@ import {
|
|
|
3
3
|
} from "./chunk-74RFWB5T.js";
|
|
4
4
|
import {
|
|
5
5
|
wrapperCandidates
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AS7N27JK.js";
|
|
7
7
|
import {
|
|
8
8
|
similarAll
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-I2JM34UV.js";
|
|
10
10
|
import {
|
|
11
11
|
staleAbstractions
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5RKYZSQ6.js";
|
|
13
13
|
import {
|
|
14
14
|
isolated
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-VISMEWYP.js";
|
|
16
16
|
import {
|
|
17
17
|
passthroughCandidates
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-5AJJGPZE.js";
|
|
19
19
|
import {
|
|
20
20
|
drift
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-HRDPUTIQ.js";
|
|
22
22
|
import {
|
|
23
23
|
extractCandidates
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-IV6NZ426.js";
|
|
25
25
|
import {
|
|
26
26
|
complexityHotspots
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-SL674KAW.js";
|
|
28
28
|
import {
|
|
29
29
|
cycles
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-VU7FDTWV.js";
|
|
31
31
|
import {
|
|
32
32
|
dead
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-SRELHCMG.js";
|
|
34
34
|
import {
|
|
35
35
|
isEntrySurface
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-X3J4VPWM.js";
|
|
37
37
|
|
|
38
38
|
// src/queries/health.ts
|
|
39
39
|
function health(db, opts = {}) {
|
|
@@ -218,4 +218,4 @@ function health(db, opts = {}) {
|
|
|
218
218
|
export {
|
|
219
219
|
health
|
|
220
220
|
};
|
|
221
|
-
//# sourceMappingURL=chunk-
|
|
221
|
+
//# sourceMappingURL=chunk-2F2WH5WQ.js.map
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
findFirstSymbolMatch,
|
|
3
3
|
getCalleeRowsForSymbol,
|
|
4
4
|
getCallerRowsForSymbol
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-QGCEAVJD.js";
|
|
6
6
|
import {
|
|
7
7
|
shortenSymbol
|
|
8
8
|
} from "./chunk-QIXNAB5K.js";
|
|
@@ -43,4 +43,4 @@ function uniqueRows(rows) {
|
|
|
43
43
|
export {
|
|
44
44
|
callGraph
|
|
45
45
|
};
|
|
46
|
-
//# sourceMappingURL=chunk-
|
|
46
|
+
//# sourceMappingURL=chunk-2UISVZGQ.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAllDefinitions
|
|
3
|
+
} from "./chunk-QGCEAVJD.js";
|
|
1
4
|
import {
|
|
2
5
|
leafSuffix,
|
|
3
6
|
parseSymbol,
|
|
@@ -143,24 +146,18 @@ function kindCounts(db, opts = {}) {
|
|
|
143
146
|
}));
|
|
144
147
|
}
|
|
145
148
|
function loadKindRows(db, scope) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
JOIN documents d ON der.document_id = d.id
|
|
159
|
-
WHERE 1 = 1
|
|
160
|
-
${db.pathExclusionsFor("d")}
|
|
161
|
-
${scopeFilter}
|
|
162
|
-
ORDER BY d.relative_path, der.start_line`
|
|
163
|
-
).filter((row) => !db.isIgnored(row.relative_path));
|
|
149
|
+
return getAllDefinitions(db, { scope }).map(mapDefinitionToKindRow);
|
|
150
|
+
}
|
|
151
|
+
function mapDefinitionToKindRow(definition) {
|
|
152
|
+
return {
|
|
153
|
+
symbol: definition.symbol,
|
|
154
|
+
kind: definition.kind,
|
|
155
|
+
documentation: definition.documentation,
|
|
156
|
+
enclosing_symbol: definition.enclosingSymbol,
|
|
157
|
+
relative_path: definition.relativePath,
|
|
158
|
+
start_line: definition.startLine,
|
|
159
|
+
end_line: definition.endLine
|
|
160
|
+
};
|
|
164
161
|
}
|
|
165
162
|
function resolveKindNumber(row) {
|
|
166
163
|
if (row.kind !== null && row.kind !== 0) {
|
|
@@ -216,4 +213,4 @@ export {
|
|
|
216
213
|
byKind,
|
|
217
214
|
kindCounts
|
|
218
215
|
};
|
|
219
|
-
//# sourceMappingURL=chunk-
|
|
216
|
+
//# sourceMappingURL=chunk-4ZT7UGWW.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getCalleeRowsForSymbol,
|
|
3
|
+
getDefinitionsForFile
|
|
4
|
+
} from "./chunk-QGCEAVJD.js";
|
|
5
|
+
import {
|
|
6
|
+
isFunctionLikeSymbol,
|
|
7
|
+
shortenSymbol
|
|
8
|
+
} from "./chunk-QIXNAB5K.js";
|
|
9
|
+
|
|
10
|
+
// src/queries/passthrough-candidates.ts
|
|
11
|
+
function passthroughCandidates(db, opts) {
|
|
12
|
+
const { scope, maxLoc = 15, limit = 30 } = opts ?? {};
|
|
13
|
+
const symbols = getScopedDefinitions(db, scope).filter((definition) => definitionLoc(definition) >= 3 && definitionLoc(definition) <= maxLoc);
|
|
14
|
+
const results = [];
|
|
15
|
+
for (const sym of symbols) {
|
|
16
|
+
if (db.isIgnored(sym.relativePath) || !isFunctionLikeSymbol(sym.symbol)) continue;
|
|
17
|
+
const rawCallees = getCalleeRowsForSymbol(db, sym);
|
|
18
|
+
const callees = rawCallees.some((callee2) => isFunctionLikeSymbol(callee2.symbol)) ? rawCallees.filter((callee2) => isFunctionLikeSymbol(callee2.symbol)) : rawCallees;
|
|
19
|
+
const uniqueCallees = /* @__PURE__ */ new Map();
|
|
20
|
+
for (const c of callees) {
|
|
21
|
+
if (!uniqueCallees.has(c.symbol)) {
|
|
22
|
+
uniqueCallees.set(c.symbol, { symbol: c.symbol, file: c.file });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (uniqueCallees.size !== 1) continue;
|
|
26
|
+
const [, callee] = [...uniqueCallees.entries()][0];
|
|
27
|
+
results.push({
|
|
28
|
+
symbol: sym.symbol,
|
|
29
|
+
shortName: shortenSymbol(sym.symbol),
|
|
30
|
+
file: sym.relativePath,
|
|
31
|
+
startLine: sym.startLine,
|
|
32
|
+
endLine: sym.endLine,
|
|
33
|
+
loc: definitionLoc(sym),
|
|
34
|
+
forwardsTo: callee.symbol,
|
|
35
|
+
forwardsToShort: shortenSymbol(callee.symbol),
|
|
36
|
+
forwardsToFile: callee.file
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
results.sort((a, b) => a.loc - b.loc || a.file.localeCompare(b.file));
|
|
40
|
+
return results.slice(0, limit);
|
|
41
|
+
}
|
|
42
|
+
function getScopedDefinitions(db, scope) {
|
|
43
|
+
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
44
|
+
return db.all(
|
|
45
|
+
`SELECT relative_path
|
|
46
|
+
FROM documents
|
|
47
|
+
WHERE 1 = 1
|
|
48
|
+
${db.pathExclusionsFor("documents")}
|
|
49
|
+
${scopeFilter}
|
|
50
|
+
ORDER BY relative_path`
|
|
51
|
+
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
52
|
+
}
|
|
53
|
+
function definitionLoc(definition) {
|
|
54
|
+
return definition.endLine - definition.startLine + 1;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export {
|
|
58
|
+
passthroughCandidates
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=chunk-5AJJGPZE.js.map
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getDefinitionsForFile
|
|
3
|
+
} from "./chunk-QGCEAVJD.js";
|
|
4
|
+
import {
|
|
5
|
+
shortenSymbol
|
|
6
|
+
} from "./chunk-QIXNAB5K.js";
|
|
7
|
+
|
|
8
|
+
// src/queries/stale-abstractions.ts
|
|
9
|
+
function staleAbstractions(db, opts) {
|
|
10
|
+
const { scope, minLoc = 3, limit = 30 } = opts ?? {};
|
|
11
|
+
const rows = getScopedDefinitions(db, scope).filter((definition) => definition.isTypeLike && definitionLoc(definition) >= minLoc).map((definition) => ({
|
|
12
|
+
symbol: definition.symbol,
|
|
13
|
+
file: definition.relativePath,
|
|
14
|
+
start_line: definition.startLine,
|
|
15
|
+
end_line: definition.endLine,
|
|
16
|
+
loc: definitionLoc(definition),
|
|
17
|
+
consumers: countCrossFileConsumers(db, definition)
|
|
18
|
+
})).filter((row) => row.consumers <= 1).sort((left, right) => right.loc - left.loc || left.file.localeCompare(right.file) || left.start_line - right.start_line);
|
|
19
|
+
const filesWithFunctions = getFilesWithFunctions(db, scope);
|
|
20
|
+
return rows.filter((r) => !db.isIgnored(r.file)).filter((r) => isTrueStaleAbstraction(r, filesWithFunctions)).map((r) => ({
|
|
21
|
+
symbol: r.symbol,
|
|
22
|
+
shortName: shortenSymbol(r.symbol),
|
|
23
|
+
file: r.file,
|
|
24
|
+
startLine: r.start_line,
|
|
25
|
+
endLine: r.end_line,
|
|
26
|
+
loc: r.loc,
|
|
27
|
+
consumers: r.consumers
|
|
28
|
+
})).slice(0, limit);
|
|
29
|
+
}
|
|
30
|
+
function getFilesWithFunctions(db, scope) {
|
|
31
|
+
return new Set(getScopedDefinitions(db, scope).filter((definition) => definition.isFunctionLike).map((definition) => definition.relativePath));
|
|
32
|
+
}
|
|
33
|
+
function isTrueStaleAbstraction(row, filesWithFunctions) {
|
|
34
|
+
const basename = row.file.split("/").pop() ?? "";
|
|
35
|
+
const isTypeFile = basename.includes("types") || row.file.includes("/types/");
|
|
36
|
+
if (isTypeFile && row.consumers > 0) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (row.consumers === 0 && filesWithFunctions.has(row.file)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
function getScopedDefinitions(db, scope) {
|
|
45
|
+
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
46
|
+
return db.all(
|
|
47
|
+
`SELECT relative_path
|
|
48
|
+
FROM documents
|
|
49
|
+
WHERE 1 = 1
|
|
50
|
+
${db.pathExclusionsFor("documents")}
|
|
51
|
+
${scopeFilter}
|
|
52
|
+
ORDER BY relative_path`
|
|
53
|
+
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
54
|
+
}
|
|
55
|
+
function countCrossFileConsumers(db, definition) {
|
|
56
|
+
const callers = db.all(
|
|
57
|
+
`SELECT DISTINCT d.relative_path
|
|
58
|
+
FROM mentions m
|
|
59
|
+
JOIN chunks c ON m.chunk_id = c.id
|
|
60
|
+
JOIN documents d ON c.document_id = d.id
|
|
61
|
+
WHERE m.symbol_id = ?
|
|
62
|
+
AND m.role != 1
|
|
63
|
+
${db.pathExclusionsFor("d")}`,
|
|
64
|
+
definition.symbolId
|
|
65
|
+
).map((row) => row.relative_path).filter((relativePath) => relativePath !== definition.relativePath && !db.isIgnored(relativePath));
|
|
66
|
+
return new Set(callers).size;
|
|
67
|
+
}
|
|
68
|
+
function definitionLoc(definition) {
|
|
69
|
+
return definition.endLine - definition.startLine + 1;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
staleAbstractions
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=chunk-5RKYZSQ6.js.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findFirstSymbolMatch,
|
|
3
|
+
getSourceReferenceSites,
|
|
4
|
+
getSourceText
|
|
5
|
+
} from "./chunk-QGCEAVJD.js";
|
|
6
|
+
import {
|
|
7
|
+
isFunctionLikeSymbol
|
|
8
|
+
} from "./chunk-QIXNAB5K.js";
|
|
9
|
+
|
|
10
|
+
// src/queries/refs.ts
|
|
11
|
+
function refs(db, symbolPattern) {
|
|
12
|
+
const match = findFirstSymbolMatch(db, symbolPattern);
|
|
13
|
+
if (match) {
|
|
14
|
+
const includeDefinitionSite = !isFunctionLikeSymbol(match.symbol);
|
|
15
|
+
const definitionRows = includeDefinitionSite ? [{
|
|
16
|
+
relativePath: match.relativePath,
|
|
17
|
+
line: match.startLine
|
|
18
|
+
}] : [];
|
|
19
|
+
const sourceSites = getSourceReferenceSites(db, match).filter((site) => !db.isIgnored(site.file)).map((site) => ({
|
|
20
|
+
relativePath: site.file,
|
|
21
|
+
line: site.line
|
|
22
|
+
}));
|
|
23
|
+
if (sourceSites.length > 0) {
|
|
24
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
25
|
+
const rows2 = [...definitionRows, ...sourceSites, ...getRubySemanticRefs(db, match)].filter((site) => {
|
|
26
|
+
const key = `${site.relativePath}:${site.line}`;
|
|
27
|
+
if (seen2.has(key)) return false;
|
|
28
|
+
seen2.add(key);
|
|
29
|
+
return true;
|
|
30
|
+
});
|
|
31
|
+
return rows2;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const rows = db.all(
|
|
35
|
+
`SELECT DISTINCT d.relative_path, c.start_line
|
|
36
|
+
FROM mentions m
|
|
37
|
+
JOIN chunks c ON m.chunk_id = c.id
|
|
38
|
+
JOIN documents d ON c.document_id = d.id
|
|
39
|
+
JOIN global_symbols gs ON m.symbol_id = gs.id
|
|
40
|
+
WHERE m.symbol_id = ?
|
|
41
|
+
AND ${db.localSymbolPredicate}
|
|
42
|
+
AND m.role != 1
|
|
43
|
+
ORDER BY d.relative_path, c.start_line`,
|
|
44
|
+
match?.symbolId ?? -1
|
|
45
|
+
);
|
|
46
|
+
const referenceRows = rows.filter((r) => !db.isIgnored(r.relative_path)).map((r) => ({
|
|
47
|
+
relativePath: r.relative_path,
|
|
48
|
+
line: r.start_line
|
|
49
|
+
}));
|
|
50
|
+
if (!match || db.isIgnored(match.relativePath) || isFunctionLikeSymbol(match.symbol)) {
|
|
51
|
+
return referenceRows;
|
|
52
|
+
}
|
|
53
|
+
const seen = new Set(referenceRows.map((row) => `${row.relativePath}:${row.line}`));
|
|
54
|
+
if (!seen.has(`${match.relativePath}:${match.startLine}`)) {
|
|
55
|
+
referenceRows.unshift({
|
|
56
|
+
relativePath: match.relativePath,
|
|
57
|
+
line: match.startLine
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
for (const row of getRubySemanticRefs(db, match)) {
|
|
61
|
+
const key = `${row.relativePath}:${row.line}`;
|
|
62
|
+
if (seen.has(key)) continue;
|
|
63
|
+
seen.add(key);
|
|
64
|
+
referenceRows.push(row);
|
|
65
|
+
}
|
|
66
|
+
return referenceRows;
|
|
67
|
+
}
|
|
68
|
+
function getRubySemanticRefs(db, match) {
|
|
69
|
+
if (!match.relativePath.endsWith(".rb")) {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const tokens = rubyReferenceTokens(match.symbol);
|
|
73
|
+
if (tokens.length === 0) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const rows = db.all(
|
|
77
|
+
`SELECT relative_path
|
|
78
|
+
FROM documents
|
|
79
|
+
WHERE relative_path LIKE '%.rb'
|
|
80
|
+
${db.pathExclusionsFor("documents")}
|
|
81
|
+
ORDER BY relative_path`
|
|
82
|
+
);
|
|
83
|
+
const results = [];
|
|
84
|
+
for (const row of rows) {
|
|
85
|
+
if (db.isIgnored(row.relative_path)) continue;
|
|
86
|
+
const source = getSourceText(db, row.relative_path);
|
|
87
|
+
if (!source) continue;
|
|
88
|
+
const lines = source.split("\n");
|
|
89
|
+
for (let index = 0; index < lines.length; index++) {
|
|
90
|
+
const line = lines[index] ?? "";
|
|
91
|
+
if (tokens.some((token) => new RegExp(`@${token}\\b|\\b${token}:`).test(line))) {
|
|
92
|
+
results.push({
|
|
93
|
+
relativePath: row.relative_path,
|
|
94
|
+
line: index
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return results;
|
|
100
|
+
}
|
|
101
|
+
function rubyReferenceTokens(rawSymbol) {
|
|
102
|
+
const leaf = rawSymbol.split(":").pop() ?? rawSymbol;
|
|
103
|
+
const snake = leaf.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^A-Za-z0-9_]+/g, "_").toLowerCase().replace(/^_+|_+$/g, "");
|
|
104
|
+
const parts = snake.split("_").filter(Boolean);
|
|
105
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
106
|
+
if (snake) candidates.add(snake);
|
|
107
|
+
if (parts.length >= 1) candidates.add(parts[parts.length - 1]);
|
|
108
|
+
if (parts.length >= 2) candidates.add(parts.slice(-2).join("_"));
|
|
109
|
+
return [...candidates];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
refs
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=chunk-7YBLWIXY.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-4TYLS5XX.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveIndexedPaths
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QGCEAVJD.js";
|
|
7
7
|
import {
|
|
8
8
|
shortenSymbol
|
|
9
9
|
} from "./chunk-QIXNAB5K.js";
|
|
@@ -79,4 +79,4 @@ function system(db, modulePattern) {
|
|
|
79
79
|
export {
|
|
80
80
|
system
|
|
81
81
|
};
|
|
82
|
-
//# sourceMappingURL=chunk-
|
|
82
|
+
//# sourceMappingURL=chunk-A4GWYETB.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findFirstSymbolMatch,
|
|
3
3
|
getCalleeRowsForSymbol
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QGCEAVJD.js";
|
|
5
5
|
import {
|
|
6
6
|
shortenSymbol
|
|
7
7
|
} from "./chunk-QIXNAB5K.js";
|
|
@@ -97,4 +97,4 @@ function forwardSlice(db, match) {
|
|
|
97
97
|
export {
|
|
98
98
|
slice
|
|
99
99
|
};
|
|
100
|
-
//# sourceMappingURL=chunk-
|
|
100
|
+
//# sourceMappingURL=chunk-A5BGEBM7.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveIndexedFile
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QGCEAVJD.js";
|
|
4
4
|
|
|
5
5
|
// src/queries/coupling.ts
|
|
6
6
|
function coupling(db, file1, file2) {
|
|
@@ -81,4 +81,4 @@ export {
|
|
|
81
81
|
coupling,
|
|
82
82
|
topCoupling
|
|
83
83
|
};
|
|
84
|
-
//# sourceMappingURL=chunk-
|
|
84
|
+
//# sourceMappingURL=chunk-A7YY7IDA.js.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildFileDepGraph,
|
|
3
|
+
getCallerRowsForSymbol,
|
|
4
|
+
getDefinitionsForFile
|
|
5
|
+
} from "./chunk-QGCEAVJD.js";
|
|
6
|
+
import {
|
|
7
|
+
isFunctionLikeSymbol,
|
|
8
|
+
shortenSymbol
|
|
9
|
+
} from "./chunk-QIXNAB5K.js";
|
|
10
|
+
|
|
11
|
+
// src/queries/wrapper-candidates.ts
|
|
12
|
+
import { basename, extname } from "path";
|
|
13
|
+
function wrapperCandidates(db, opts) {
|
|
14
|
+
const { scope, maxLoc = 15, limit = 30 } = opts ?? {};
|
|
15
|
+
const reverseFanIn = buildReverseFileFanIn(buildFileDepGraph(db, scope));
|
|
16
|
+
const symbols = getScopedDefinitions(db, scope).filter((definition) => definitionLoc(definition) <= maxLoc && definitionLoc(definition) >= 2);
|
|
17
|
+
const results = [];
|
|
18
|
+
for (const symbol of symbols) {
|
|
19
|
+
if (db.isIgnored(symbol.relativePath) || !isFunctionLikeSymbol(symbol.symbol)) continue;
|
|
20
|
+
const symbolStem = basename(symbol.relativePath, extname(symbol.relativePath));
|
|
21
|
+
const callerRows = dedupeRows(
|
|
22
|
+
getCallerRowsForSymbol(db, symbol, { limit: 200 }).filter((row) => row.file !== symbol.relativePath)
|
|
23
|
+
).filter((row) => basename(row.file, extname(row.file)) !== symbolStem);
|
|
24
|
+
if (callerRows.length !== 1) continue;
|
|
25
|
+
const caller = callerRows[0];
|
|
26
|
+
const callerDefinition = getDefinitionsForFile(db, caller.file).find((definition) => definition.symbol === caller.symbol);
|
|
27
|
+
const useDefinitionFanIn = callerDefinition?.isFunctionLike ?? false;
|
|
28
|
+
let callerFanIn;
|
|
29
|
+
if (useDefinitionFanIn && callerDefinition) {
|
|
30
|
+
callerFanIn = new Set(
|
|
31
|
+
getCallerRowsForSymbol(db, callerDefinition, { limit: 500 }).filter((row) => row.file !== callerDefinition.relativePath).map((row) => row.file)
|
|
32
|
+
).size;
|
|
33
|
+
} else {
|
|
34
|
+
callerFanIn = fallbackCallerFanIn(db, reverseFanIn, caller.file);
|
|
35
|
+
}
|
|
36
|
+
if (callerFanIn <= 3) continue;
|
|
37
|
+
results.push({
|
|
38
|
+
symbol: symbol.symbol,
|
|
39
|
+
shortName: shortenSymbol(symbol.symbol),
|
|
40
|
+
file: symbol.relativePath,
|
|
41
|
+
startLine: symbol.startLine,
|
|
42
|
+
endLine: symbol.endLine,
|
|
43
|
+
loc: definitionLoc(symbol),
|
|
44
|
+
singleCaller: caller.symbol,
|
|
45
|
+
singleCallerShort: useDefinitionFanIn ? shortenSymbol(caller.symbol) : basename(caller.file),
|
|
46
|
+
callerFanIn
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
results.sort((left, right) => right.callerFanIn - left.callerFanIn || right.loc - left.loc);
|
|
50
|
+
return results.slice(0, limit);
|
|
51
|
+
}
|
|
52
|
+
function definitionLoc(definition) {
|
|
53
|
+
return definition.endLine - definition.startLine + 1;
|
|
54
|
+
}
|
|
55
|
+
function getScopedDefinitions(db, scope) {
|
|
56
|
+
const scopeFilter = scope ? `AND relative_path LIKE '%${scope}%'` : "";
|
|
57
|
+
return db.all(
|
|
58
|
+
`SELECT relative_path
|
|
59
|
+
FROM documents
|
|
60
|
+
WHERE 1 = 1
|
|
61
|
+
${db.pathExclusionsFor("documents")}
|
|
62
|
+
${scopeFilter}
|
|
63
|
+
ORDER BY relative_path`
|
|
64
|
+
).flatMap((row) => getDefinitionsForFile(db, row.relative_path)).filter((row) => !db.isIgnored(row.relativePath));
|
|
65
|
+
}
|
|
66
|
+
function dedupeRows(rows) {
|
|
67
|
+
const seen = /* @__PURE__ */ new Set();
|
|
68
|
+
const unique = [];
|
|
69
|
+
for (const row of rows) {
|
|
70
|
+
const key = `${row.symbol}|${row.file}`;
|
|
71
|
+
if (seen.has(key)) continue;
|
|
72
|
+
seen.add(key);
|
|
73
|
+
unique.push(row);
|
|
74
|
+
}
|
|
75
|
+
return unique;
|
|
76
|
+
}
|
|
77
|
+
function buildReverseFileFanIn(graph) {
|
|
78
|
+
const reverse = /* @__PURE__ */ new Map();
|
|
79
|
+
for (const [fromFile, deps] of graph) {
|
|
80
|
+
if (!reverse.has(fromFile)) {
|
|
81
|
+
reverse.set(fromFile, reverse.get(fromFile) ?? 0);
|
|
82
|
+
}
|
|
83
|
+
for (const dep of deps) {
|
|
84
|
+
reverse.set(dep, (reverse.get(dep) ?? 0) + 1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return reverse;
|
|
88
|
+
}
|
|
89
|
+
function fallbackCallerFanIn(db, reverseFanIn, callerFile) {
|
|
90
|
+
const functionLikeFanIn = getDefinitionsForFile(db, callerFile).filter((definition) => definition.isFunctionLike).map((definition) => new Set(
|
|
91
|
+
getCallerRowsForSymbol(db, definition, { limit: 500 }).filter((row) => row.file !== definition.relativePath).map((row) => row.file)
|
|
92
|
+
).size).sort((left, right) => right - left)[0] ?? 0;
|
|
93
|
+
if (functionLikeFanIn > 0) {
|
|
94
|
+
return functionLikeFanIn;
|
|
95
|
+
}
|
|
96
|
+
const direct = reverseFanIn.get(callerFile) ?? 0;
|
|
97
|
+
if (direct > 0) {
|
|
98
|
+
return direct;
|
|
99
|
+
}
|
|
100
|
+
const stem = basename(callerFile, extname(callerFile));
|
|
101
|
+
let best = 0;
|
|
102
|
+
for (const [file, fanIn] of reverseFanIn) {
|
|
103
|
+
if (file === callerFile) continue;
|
|
104
|
+
if (basename(file, extname(file)) !== stem) continue;
|
|
105
|
+
if (fanIn > best) {
|
|
106
|
+
best = fanIn;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return best;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
wrapperCandidates
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=chunk-AS7N27JK.js.map
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getAllDefinitions,
|
|
3
|
+
getCalleeRowsForSymbol,
|
|
4
|
+
getCallerRowsForSymbol
|
|
5
|
+
} from "./chunk-QGCEAVJD.js";
|
|
1
6
|
import {
|
|
2
7
|
shortenSymbol
|
|
3
8
|
} from "./chunk-QIXNAB5K.js";
|
|
@@ -39,7 +44,7 @@ function bottlenecks(db, opts = {}) {
|
|
|
39
44
|
minFanOut,
|
|
40
45
|
limit
|
|
41
46
|
);
|
|
42
|
-
|
|
47
|
+
const indexedResults = rows.filter((r) => !db.isIgnored(r.defined_in)).map((r) => ({
|
|
43
48
|
symbol: r.symbol,
|
|
44
49
|
shortName: shortenSymbol(r.symbol),
|
|
45
50
|
fanIn: r.fan_in,
|
|
@@ -47,9 +52,28 @@ function bottlenecks(db, opts = {}) {
|
|
|
47
52
|
score: r.fan_in * r.fan_out,
|
|
48
53
|
definedIn: r.defined_in
|
|
49
54
|
}));
|
|
55
|
+
if (indexedResults.length > 0) {
|
|
56
|
+
return indexedResults;
|
|
57
|
+
}
|
|
58
|
+
return getAllDefinitions(db, { scope }).filter((definition) => !db.isIgnored(definition.relativePath)).map((definition) => {
|
|
59
|
+
const fanIn = new Set(
|
|
60
|
+
getCallerRowsForSymbol(db, definition, { limit: 500 }).map((row) => row.file)
|
|
61
|
+
).size;
|
|
62
|
+
const fanOut = new Set(
|
|
63
|
+
getCalleeRowsForSymbol(db, definition, { limit: 500 }).filter((row) => row.file !== definition.relativePath).map((row) => `${row.symbol}|${row.file}`)
|
|
64
|
+
).size;
|
|
65
|
+
return {
|
|
66
|
+
symbol: definition.symbol,
|
|
67
|
+
shortName: shortenSymbol(definition.symbol),
|
|
68
|
+
fanIn,
|
|
69
|
+
fanOut,
|
|
70
|
+
score: fanIn * fanOut,
|
|
71
|
+
definedIn: definition.relativePath
|
|
72
|
+
};
|
|
73
|
+
}).filter((row) => row.fanIn >= minFanIn && row.fanOut >= minFanOut).sort((left, right) => right.score - left.score || right.fanIn - left.fanIn).slice(0, limit);
|
|
50
74
|
}
|
|
51
75
|
|
|
52
76
|
export {
|
|
53
77
|
bottlenecks
|
|
54
78
|
};
|
|
55
|
-
//# sourceMappingURL=chunk-
|
|
79
|
+
//# sourceMappingURL=chunk-CQRYLK33.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findFirstSymbolMatch
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-QGCEAVJD.js";
|
|
4
4
|
import {
|
|
5
5
|
isDirectChildSymbol,
|
|
6
6
|
leafSuffix,
|
|
@@ -34,4 +34,4 @@ function members(db, symbolPattern) {
|
|
|
34
34
|
export {
|
|
35
35
|
members
|
|
36
36
|
};
|
|
37
|
-
//# sourceMappingURL=chunk-
|
|
37
|
+
//# sourceMappingURL=chunk-CQUNEJYM.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cleanSignature
|
|
3
|
+
} from "./chunk-4TYLS5XX.js";
|
|
4
|
+
import {
|
|
5
|
+
getDefinitionsForFile,
|
|
6
|
+
resolveIndexedPaths
|
|
7
|
+
} from "./chunk-QGCEAVJD.js";
|
|
8
|
+
import {
|
|
9
|
+
shortenSymbol
|
|
10
|
+
} from "./chunk-QIXNAB5K.js";
|
|
11
|
+
|
|
12
|
+
// src/queries/symbols.ts
|
|
13
|
+
function symbols(db, filePattern) {
|
|
14
|
+
const resolvedPaths = resolveIndexedPaths(db, filePattern);
|
|
15
|
+
if (resolvedPaths.length === 0) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
return resolvedPaths.flatMap((relativePath) => getDefinitionsForFile(db, relativePath)).filter((row) => !db.isIgnored(row.relativePath)).map((row) => {
|
|
19
|
+
const docRow = db.get(
|
|
20
|
+
`SELECT REPLACE(SUBSTR(documentation, INSTR(documentation, '|') + 1), char(10), ' ') AS sig
|
|
21
|
+
FROM global_symbols
|
|
22
|
+
WHERE id = ?`,
|
|
23
|
+
row.symbolId
|
|
24
|
+
);
|
|
25
|
+
return {
|
|
26
|
+
startLine: row.startLine,
|
|
27
|
+
endLine: row.endLine,
|
|
28
|
+
symbol: row.symbol,
|
|
29
|
+
shortName: shortenSymbol(row.symbol),
|
|
30
|
+
signature: cleanSignature(docRow?.sig ?? null)
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export {
|
|
36
|
+
symbols
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=chunk-D4I3ZMN5.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
findFirstSymbolMatch,
|
|
3
3
|
resolveIndexedFile
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QGCEAVJD.js";
|
|
5
5
|
import {
|
|
6
6
|
shortenSymbol
|
|
7
7
|
} from "./chunk-QIXNAB5K.js";
|
|
@@ -76,4 +76,4 @@ function readFileRange(db, filePath, startLine, endLine, context) {
|
|
|
76
76
|
export {
|
|
77
77
|
code
|
|
78
78
|
};
|
|
79
|
-
//# sourceMappingURL=chunk-
|
|
79
|
+
//# sourceMappingURL=chunk-E7J7Q7UW.js.map
|