@jafreck/lore 0.3.7 → 0.3.8
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 +23 -122
- package/dist/cli.d.ts +2 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +63 -29
- package/dist/cli.js.map +1 -1
- package/dist/db/read-only.d.ts +22 -43
- package/dist/db/read-only.d.ts.map +1 -1
- package/dist/db/read-only.js +80 -156
- package/dist/db/read-only.js.map +1 -1
- package/dist/db/schema.d.ts +9 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +164 -85
- package/dist/db/schema.js.map +1 -1
- package/dist/discovery/poller.d.ts +6 -16
- package/dist/discovery/poller.d.ts.map +1 -1
- package/dist/discovery/poller.js +21 -52
- package/dist/discovery/poller.js.map +1 -1
- package/dist/discovery/scip-flush.d.ts +44 -0
- package/dist/discovery/scip-flush.d.ts.map +1 -0
- package/dist/discovery/scip-flush.js +67 -0
- package/dist/discovery/scip-flush.js.map +1 -0
- package/dist/discovery/watcher.d.ts +6 -16
- package/dist/discovery/watcher.d.ts.map +1 -1
- package/dist/discovery/watcher.js +22 -54
- package/dist/discovery/watcher.js.map +1 -1
- package/dist/docs/docs.d.ts +0 -2
- package/dist/docs/docs.d.ts.map +1 -1
- package/dist/docs/docs.js +0 -27
- package/dist/docs/docs.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/indexer/index.d.ts +19 -10
- package/dist/indexer/index.d.ts.map +1 -1
- package/dist/indexer/index.js +99 -24
- package/dist/indexer/index.js.map +1 -1
- package/dist/indexer/pipeline.d.ts +25 -14
- package/dist/indexer/pipeline.d.ts.map +1 -1
- package/dist/indexer/pipeline.js +8 -7
- package/dist/indexer/pipeline.js.map +1 -1
- package/dist/indexer/stages/docs-index.d.ts +1 -3
- package/dist/indexer/stages/docs-index.d.ts.map +1 -1
- package/dist/indexer/stages/docs-index.js +1 -25
- package/dist/indexer/stages/docs-index.js.map +1 -1
- package/dist/indexer/stages/index.d.ts +4 -2
- package/dist/indexer/stages/index.d.ts.map +1 -1
- package/dist/indexer/stages/index.js +3 -2
- package/dist/indexer/stages/index.js.map +1 -1
- package/dist/indexer/stages/lsp-enrichment.d.ts.map +1 -1
- package/dist/indexer/stages/lsp-enrichment.js +20 -1
- package/dist/indexer/stages/lsp-enrichment.js.map +1 -1
- package/dist/indexer/stages/overlay-cleanup.d.ts +31 -0
- package/dist/indexer/stages/overlay-cleanup.d.ts.map +1 -0
- package/dist/indexer/stages/overlay-cleanup.js +64 -0
- package/dist/indexer/stages/overlay-cleanup.js.map +1 -0
- package/dist/indexer/stages/reverse-deps.d.ts +13 -0
- package/dist/indexer/stages/reverse-deps.d.ts.map +1 -0
- package/dist/indexer/stages/reverse-deps.js +81 -0
- package/dist/indexer/stages/reverse-deps.js.map +1 -0
- package/dist/indexer/stages/{scip-source.d.ts → scip-indexer.d.ts} +38 -9
- package/dist/indexer/stages/scip-indexer.d.ts.map +1 -0
- package/dist/indexer/stages/{scip-source.js → scip-indexer.js} +350 -91
- package/dist/indexer/stages/scip-indexer.js.map +1 -0
- package/dist/indexer/stages/source-index.d.ts +3 -3
- package/dist/indexer/stages/source-index.d.ts.map +1 -1
- package/dist/indexer/stages/source-index.js +116 -69
- package/dist/indexer/stages/source-index.js.map +1 -1
- package/dist/lsp/enrichment.d.ts.map +1 -1
- package/dist/lsp/enrichment.js +1 -18
- package/dist/lsp/enrichment.js.map +1 -1
- package/dist/parsing/extractors/go.d.ts.map +1 -1
- package/dist/parsing/extractors/go.js +0 -38
- package/dist/parsing/extractors/go.js.map +1 -1
- package/dist/parsing/extractors/javascript.d.ts.map +1 -1
- package/dist/parsing/extractors/javascript.js +0 -47
- package/dist/parsing/extractors/javascript.js.map +1 -1
- package/dist/parsing/extractors/python.d.ts.map +1 -1
- package/dist/parsing/extractors/python.js +0 -22
- package/dist/parsing/extractors/python.js.map +1 -1
- package/dist/parsing/extractors/types.d.ts +0 -16
- package/dist/parsing/extractors/types.d.ts.map +1 -1
- package/dist/parsing/extractors/types.js +1 -1
- package/dist/parsing/extractors/types.js.map +1 -1
- package/dist/parsing/extractors/typescript.js +2 -2
- package/dist/parsing/extractors/typescript.js.map +1 -1
- package/dist/resolution/call-graph.d.ts +3 -1
- package/dist/resolution/call-graph.d.ts.map +1 -1
- package/dist/resolution/call-graph.js +15 -13
- package/dist/resolution/call-graph.js.map +1 -1
- package/dist/resolution/resolution-method.d.ts +1 -1
- package/dist/resolution/resolution-method.d.ts.map +1 -1
- package/dist/resolution/resolution-method.js +2 -0
- package/dist/resolution/resolution-method.js.map +1 -1
- package/dist/runtime.d.ts +0 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js.map +1 -1
- package/dist/scip/compdb.d.ts +38 -0
- package/dist/scip/compdb.d.ts.map +1 -0
- package/dist/scip/compdb.js +138 -0
- package/dist/scip/compdb.js.map +1 -0
- package/dist/scip/enrichment.d.ts +6 -1
- package/dist/scip/enrichment.d.ts.map +1 -1
- package/dist/scip/enrichment.js +59 -2
- package/dist/scip/enrichment.js.map +1 -1
- package/dist/scip/installer.d.ts +59 -0
- package/dist/scip/installer.d.ts.map +1 -0
- package/dist/scip/installer.js +302 -0
- package/dist/scip/installer.js.map +1 -0
- package/dist/scip/registry.d.ts +1 -1
- package/dist/scip/registry.d.ts.map +1 -1
- package/dist/scip/registry.js +33 -5
- package/dist/scip/registry.js.map +1 -1
- package/dist/server/server.d.ts +2 -6
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +6 -56
- package/dist/server/server.js.map +1 -1
- package/dist/server/tool-registry.d.ts +2 -2
- package/dist/server/tool-registry.d.ts.map +1 -1
- package/dist/server/tool-registry.js +41 -20
- package/dist/server/tool-registry.js.map +1 -1
- package/dist/server/tools/cohesion.d.ts +46 -0
- package/dist/server/tools/cohesion.d.ts.map +1 -0
- package/dist/server/tools/cohesion.js +100 -0
- package/dist/server/tools/cohesion.js.map +1 -0
- package/dist/server/tools/dependents.d.ts +139 -0
- package/dist/server/tools/dependents.d.ts.map +1 -0
- package/dist/server/tools/dependents.js +354 -0
- package/dist/server/tools/dependents.js.map +1 -0
- package/dist/server/tools/diff.d.ts +73 -0
- package/dist/server/tools/diff.d.ts.map +1 -0
- package/dist/server/tools/diff.js +157 -0
- package/dist/server/tools/diff.js.map +1 -0
- package/dist/server/tools/structure.d.ts +77 -0
- package/dist/server/tools/structure.d.ts.map +1 -0
- package/dist/server/tools/structure.js +309 -0
- package/dist/server/tools/structure.js.map +1 -0
- package/dist/server/tools/test-map.d.ts +7 -0
- package/dist/server/tools/test-map.d.ts.map +1 -1
- package/dist/server/tools/test-map.js +18 -1
- package/dist/server/tools/test-map.js.map +1 -1
- package/dist/server/tools/trace.d.ts +84 -0
- package/dist/server/tools/trace.d.ts.map +1 -0
- package/dist/server/tools/trace.js +317 -0
- package/dist/server/tools/trace.js.map +1 -0
- package/dist/testing/coverage.d.ts +11 -0
- package/dist/testing/coverage.d.ts.map +1 -1
- package/dist/testing/coverage.js +34 -2
- package/dist/testing/coverage.js.map +1 -1
- package/dist/testing/test-mapper.d.ts +1 -1
- package/dist/testing/test-mapper.d.ts.map +1 -1
- package/dist/testing/test-mapper.js +1 -0
- package/dist/testing/test-mapper.js.map +1 -1
- package/package.json +3 -1
- package/dist/indexer/stages/scip-enrichment.d.ts +0 -43
- package/dist/indexer/stages/scip-enrichment.d.ts.map +0 -1
- package/dist/indexer/stages/scip-enrichment.js +0 -172
- package/dist/indexer/stages/scip-enrichment.js.map +0 -1
- package/dist/indexer/stages/scip-source.d.ts.map +0 -1
- package/dist/indexer/stages/scip-source.js.map +0 -1
- package/dist/server/tools/notes.d.ts +0 -165
- package/dist/server/tools/notes.d.ts.map +0 -1
- package/dist/server/tools/notes.js +0 -214
- package/dist/server/tools/notes.js.map +0 -1
- package/dist/server/tools/routes.d.ts +0 -38
- package/dist/server/tools/routes.d.ts.map +0 -1
- package/dist/server/tools/routes.js +0 -38
- package/dist/server/tools/routes.js.map +0 -1
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module lore-server/tools/dependents
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: unified reverse-dependency / blast-radius queries.
|
|
5
|
+
*
|
|
6
|
+
* Given a symbol name or file path, returns all dependents across edge types
|
|
7
|
+
* (callers, importers, subclasses, type references) in a single call.
|
|
8
|
+
* This is a higher-level abstraction over `lore_graph` that resolves names
|
|
9
|
+
* internally and aggregates across edge kinds.
|
|
10
|
+
*/
|
|
11
|
+
import { getSymbolsByName, getFileByPath, getFileById, } from '../../db/read-only.js';
|
|
12
|
+
// ─── Tool definition ──────────────────────────────────────────────────────────
|
|
13
|
+
export const toolDef = {
|
|
14
|
+
name: 'lore_dependents',
|
|
15
|
+
description: 'Find everything affected by changing a symbol or file — unified blast-radius / reverse-dependency query. ' +
|
|
16
|
+
'Takes a name or path (not a numeric ID) and returns callers, importers, subclasses, and type references in one call. ' +
|
|
17
|
+
'For kind="symbol", resolves the query to a symbol and returns callers, subclasses, and type-referencers. ' +
|
|
18
|
+
'For kind="file", resolves the query to a file and returns files that import it plus symbols in other files that call into its symbols. ' +
|
|
19
|
+
'Set depth > 1 for transitive closure (up to 5 hops). Set compact=true to reduce token count.',
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
query: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
description: 'Symbol name, class name, or file path to find dependents of.',
|
|
26
|
+
},
|
|
27
|
+
kind: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
enum: ['symbol', 'file'],
|
|
30
|
+
description: '"symbol" resolves query as a symbol name; "file" resolves query as a file path.',
|
|
31
|
+
},
|
|
32
|
+
depth: {
|
|
33
|
+
type: 'number',
|
|
34
|
+
description: 'Transitive hops (default 1, max 5). depth=1 returns direct dependents only. ' +
|
|
35
|
+
'depth=N follows dependents N hops deep.',
|
|
36
|
+
minimum: 1,
|
|
37
|
+
maximum: 5,
|
|
38
|
+
},
|
|
39
|
+
branch: {
|
|
40
|
+
type: 'string',
|
|
41
|
+
description: 'Optional branch name to filter results.',
|
|
42
|
+
},
|
|
43
|
+
compact: {
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
description: 'If true, omit provenance fields (line, character, resolution details) to reduce token count. Default false.',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
required: ['query', 'kind'],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
// ─── Query helpers ────────────────────────────────────────────────────────────
|
|
52
|
+
function queryCallers(db, symbolIds, branch, limit) {
|
|
53
|
+
if (symbolIds.length === 0)
|
|
54
|
+
return [];
|
|
55
|
+
const placeholders = symbolIds.map(() => '?').join(', ');
|
|
56
|
+
const conditions = [`sr.callee_id IN (${placeholders})`];
|
|
57
|
+
const params = [...symbolIds];
|
|
58
|
+
if (branch !== undefined) {
|
|
59
|
+
conditions.push('f.branch = ?');
|
|
60
|
+
params.push(branch);
|
|
61
|
+
}
|
|
62
|
+
params.push(limit);
|
|
63
|
+
return db
|
|
64
|
+
.prepare(`SELECT sr.caller_id,
|
|
65
|
+
s.name AS caller_name,
|
|
66
|
+
s.kind AS caller_kind,
|
|
67
|
+
f.path AS caller_file,
|
|
68
|
+
sr.call_line + 1 AS line,
|
|
69
|
+
CASE WHEN sr.call_character IS NULL THEN NULL ELSE sr.call_character + 1 END AS character,
|
|
70
|
+
sr.resolution_method
|
|
71
|
+
FROM symbol_refs sr
|
|
72
|
+
JOIN symbols s ON s.id = sr.caller_id
|
|
73
|
+
JOIN files f ON f.id = s.file_id
|
|
74
|
+
WHERE ${conditions.join(' AND ')}
|
|
75
|
+
LIMIT ?`)
|
|
76
|
+
.all(...params);
|
|
77
|
+
}
|
|
78
|
+
function queryImporters(db, fileIds, branch, limit) {
|
|
79
|
+
if (fileIds.length === 0)
|
|
80
|
+
return [];
|
|
81
|
+
const placeholders = fileIds.map(() => '?').join(', ');
|
|
82
|
+
const conditions = [`fi.resolved_id IN (${placeholders})`];
|
|
83
|
+
const params = [...fileIds];
|
|
84
|
+
if (branch !== undefined) {
|
|
85
|
+
conditions.push('f.branch = ?');
|
|
86
|
+
params.push(branch);
|
|
87
|
+
}
|
|
88
|
+
params.push(limit);
|
|
89
|
+
return db
|
|
90
|
+
.prepare(`SELECT fi.file_id,
|
|
91
|
+
f.path AS file_path,
|
|
92
|
+
fi.raw_import
|
|
93
|
+
FROM file_imports fi
|
|
94
|
+
JOIN files f ON f.id = fi.file_id
|
|
95
|
+
WHERE ${conditions.join(' AND ')}
|
|
96
|
+
LIMIT ?`)
|
|
97
|
+
.all(...params);
|
|
98
|
+
}
|
|
99
|
+
function querySubclasses(db, symbolIds, branch, limit) {
|
|
100
|
+
if (symbolIds.length === 0)
|
|
101
|
+
return [];
|
|
102
|
+
const placeholders = symbolIds.map(() => '?').join(', ');
|
|
103
|
+
const conditions = [
|
|
104
|
+
`rel.target_symbol_id IN (${placeholders})`,
|
|
105
|
+
"rel.relationship_type IN ('extends', 'implements')",
|
|
106
|
+
];
|
|
107
|
+
const params = [...symbolIds];
|
|
108
|
+
if (branch !== undefined) {
|
|
109
|
+
conditions.push('f.branch = ?');
|
|
110
|
+
params.push(branch);
|
|
111
|
+
}
|
|
112
|
+
params.push(limit);
|
|
113
|
+
return db
|
|
114
|
+
.prepare(`SELECT rel.source_symbol_id AS symbol_id,
|
|
115
|
+
s.name AS symbol_name,
|
|
116
|
+
s.kind AS symbol_kind,
|
|
117
|
+
f.path AS file,
|
|
118
|
+
rel.relationship_type,
|
|
119
|
+
CASE WHEN rel.line IS NULL THEN NULL ELSE rel.line + 1 END AS line,
|
|
120
|
+
CASE WHEN rel.character IS NULL THEN NULL ELSE rel.character + 1 END AS character,
|
|
121
|
+
rel.resolution_method
|
|
122
|
+
FROM symbol_relationships rel
|
|
123
|
+
JOIN symbols s ON s.id = rel.source_symbol_id
|
|
124
|
+
JOIN files f ON f.id = s.file_id
|
|
125
|
+
WHERE ${conditions.join(' AND ')}
|
|
126
|
+
LIMIT ?`)
|
|
127
|
+
.all(...params);
|
|
128
|
+
}
|
|
129
|
+
function queryTypeReferences(db, symbolIds, branch, limit) {
|
|
130
|
+
if (symbolIds.length === 0)
|
|
131
|
+
return [];
|
|
132
|
+
const placeholders = symbolIds.map(() => '?').join(', ');
|
|
133
|
+
const conditions = [`tr.type_id IN (${placeholders})`];
|
|
134
|
+
const params = [...symbolIds];
|
|
135
|
+
if (branch !== undefined) {
|
|
136
|
+
conditions.push('f.branch = ?');
|
|
137
|
+
params.push(branch);
|
|
138
|
+
}
|
|
139
|
+
params.push(limit);
|
|
140
|
+
return db
|
|
141
|
+
.prepare(`SELECT tr.symbol_id,
|
|
142
|
+
COALESCE(s.name, '') AS symbol_name,
|
|
143
|
+
COALESCE(s.kind, '') AS symbol_kind,
|
|
144
|
+
f.path AS file,
|
|
145
|
+
tr.ref_kind,
|
|
146
|
+
tr.ref_line + 1 AS line,
|
|
147
|
+
CASE WHEN tr.ref_character IS NULL THEN NULL ELSE tr.ref_character + 1 END AS character,
|
|
148
|
+
tr.resolution_method
|
|
149
|
+
FROM type_refs tr
|
|
150
|
+
JOIN files f ON f.id = tr.file_id
|
|
151
|
+
LEFT JOIN symbols s ON s.id = tr.symbol_id
|
|
152
|
+
WHERE ${conditions.join(' AND ')}
|
|
153
|
+
LIMIT ?`)
|
|
154
|
+
.all(...params);
|
|
155
|
+
}
|
|
156
|
+
/** For kind="file", find all symbols defined in the given file(s) so we can query their callers. */
|
|
157
|
+
function getSymbolIdsInFiles(db, fileIds, branch) {
|
|
158
|
+
if (fileIds.length === 0)
|
|
159
|
+
return [];
|
|
160
|
+
const placeholders = fileIds.map(() => '?').join(', ');
|
|
161
|
+
const conditions = [`s.file_id IN (${placeholders})`];
|
|
162
|
+
const params = [...fileIds];
|
|
163
|
+
if (branch !== undefined) {
|
|
164
|
+
conditions.push('f.branch = ?');
|
|
165
|
+
params.push(branch);
|
|
166
|
+
}
|
|
167
|
+
const rows = db
|
|
168
|
+
.prepare(`SELECT s.id
|
|
169
|
+
FROM symbols s
|
|
170
|
+
JOIN files f ON f.id = s.file_id
|
|
171
|
+
WHERE ${conditions.join(' AND ')}`)
|
|
172
|
+
.all(...params);
|
|
173
|
+
return rows.map((r) => r.id);
|
|
174
|
+
}
|
|
175
|
+
// ─── Compact helpers ──────────────────────────────────────────────────────────
|
|
176
|
+
function compactCaller(row) {
|
|
177
|
+
return {
|
|
178
|
+
caller_id: row.caller_id,
|
|
179
|
+
caller_name: row.caller_name,
|
|
180
|
+
caller_kind: row.caller_kind,
|
|
181
|
+
caller_file: row.caller_file,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function compactImporter(row) {
|
|
185
|
+
return {
|
|
186
|
+
file_id: row.file_id,
|
|
187
|
+
file_path: row.file_path,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function compactSubclass(row) {
|
|
191
|
+
return {
|
|
192
|
+
symbol_id: row.symbol_id,
|
|
193
|
+
symbol_name: row.symbol_name,
|
|
194
|
+
symbol_kind: row.symbol_kind,
|
|
195
|
+
file: row.file,
|
|
196
|
+
relationship_type: row.relationship_type,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function compactTypeRef(row) {
|
|
200
|
+
return {
|
|
201
|
+
symbol_id: row.symbol_id,
|
|
202
|
+
symbol_name: row.symbol_name,
|
|
203
|
+
symbol_kind: row.symbol_kind,
|
|
204
|
+
file: row.file,
|
|
205
|
+
ref_kind: row.ref_kind,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// ─── Multi-hop expansion ──────────────────────────────────────────────────────
|
|
209
|
+
function expandCallers(db, seedIds, branch, depth, limit) {
|
|
210
|
+
const all = [];
|
|
211
|
+
const seen = new Set();
|
|
212
|
+
let frontier = seedIds;
|
|
213
|
+
for (let hop = 0; hop < depth && frontier.length > 0 && all.length < limit; hop++) {
|
|
214
|
+
const remaining = limit - all.length;
|
|
215
|
+
const rows = queryCallers(db, frontier, branch, remaining);
|
|
216
|
+
const nextFrontier = [];
|
|
217
|
+
for (const row of rows) {
|
|
218
|
+
if (seen.has(row.caller_id))
|
|
219
|
+
continue;
|
|
220
|
+
seen.add(row.caller_id);
|
|
221
|
+
all.push(row);
|
|
222
|
+
nextFrontier.push(row.caller_id);
|
|
223
|
+
}
|
|
224
|
+
frontier = nextFrontier;
|
|
225
|
+
}
|
|
226
|
+
return all;
|
|
227
|
+
}
|
|
228
|
+
function expandImporters(db, seedIds, branch, depth, limit) {
|
|
229
|
+
const all = [];
|
|
230
|
+
const seen = new Set();
|
|
231
|
+
let frontier = seedIds;
|
|
232
|
+
for (let hop = 0; hop < depth && frontier.length > 0 && all.length < limit; hop++) {
|
|
233
|
+
const remaining = limit - all.length;
|
|
234
|
+
const rows = queryImporters(db, frontier, branch, remaining);
|
|
235
|
+
const nextFrontier = [];
|
|
236
|
+
for (const row of rows) {
|
|
237
|
+
if (seen.has(row.file_id))
|
|
238
|
+
continue;
|
|
239
|
+
seen.add(row.file_id);
|
|
240
|
+
all.push(row);
|
|
241
|
+
nextFrontier.push(row.file_id);
|
|
242
|
+
}
|
|
243
|
+
frontier = nextFrontier;
|
|
244
|
+
}
|
|
245
|
+
return all;
|
|
246
|
+
}
|
|
247
|
+
function expandSubclasses(db, seedIds, branch, depth, limit) {
|
|
248
|
+
const all = [];
|
|
249
|
+
const seen = new Set();
|
|
250
|
+
let frontier = seedIds;
|
|
251
|
+
for (let hop = 0; hop < depth && frontier.length > 0 && all.length < limit; hop++) {
|
|
252
|
+
const remaining = limit - all.length;
|
|
253
|
+
const rows = querySubclasses(db, frontier, branch, remaining);
|
|
254
|
+
const nextFrontier = [];
|
|
255
|
+
for (const row of rows) {
|
|
256
|
+
if (seen.has(row.symbol_id))
|
|
257
|
+
continue;
|
|
258
|
+
seen.add(row.symbol_id);
|
|
259
|
+
all.push(row);
|
|
260
|
+
nextFrontier.push(row.symbol_id);
|
|
261
|
+
}
|
|
262
|
+
frontier = nextFrontier;
|
|
263
|
+
}
|
|
264
|
+
return all;
|
|
265
|
+
}
|
|
266
|
+
// ─── Handler ──────────────────────────────────────────────────────────────────
|
|
267
|
+
const DEFAULT_LIMIT = 200;
|
|
268
|
+
/** Unified reverse-dependency / blast-radius query. */
|
|
269
|
+
export function handler(db, args) {
|
|
270
|
+
const depth = Math.max(1, Math.min(args.depth ?? 1, 5));
|
|
271
|
+
const compact = args.compact ?? false;
|
|
272
|
+
const limit = DEFAULT_LIMIT;
|
|
273
|
+
if (args.kind === 'file') {
|
|
274
|
+
return handleFileDependents(db, args, depth, compact, limit);
|
|
275
|
+
}
|
|
276
|
+
return handleSymbolDependents(db, args, depth, compact, limit);
|
|
277
|
+
}
|
|
278
|
+
function handleFileDependents(db, args, depth, compact, limit) {
|
|
279
|
+
const file = getFileByPath(db, args.query, args.branch);
|
|
280
|
+
if (!file) {
|
|
281
|
+
return { error: `No file found matching path "${args.query}"` };
|
|
282
|
+
}
|
|
283
|
+
const target = {
|
|
284
|
+
id: file.id,
|
|
285
|
+
name: file.path,
|
|
286
|
+
kind: 'file',
|
|
287
|
+
file: file.path,
|
|
288
|
+
};
|
|
289
|
+
// Get importers of this file
|
|
290
|
+
const importerRows = expandImporters(db, [file.id], args.branch, depth, limit);
|
|
291
|
+
// Get symbols defined in this file, then find callers from other files
|
|
292
|
+
const symbolIds = getSymbolIdsInFiles(db, [file.id], args.branch);
|
|
293
|
+
const callerRows = expandCallers(db, symbolIds, args.branch, depth, limit)
|
|
294
|
+
// Exclude callers that are within the same file
|
|
295
|
+
.filter((row) => row.caller_file !== file.path);
|
|
296
|
+
// For files, subclasses and type_references target symbols within the file
|
|
297
|
+
const subclassRows = expandSubclasses(db, symbolIds, args.branch, depth, limit);
|
|
298
|
+
const typeRefRows = queryTypeReferences(db, symbolIds, args.branch, limit);
|
|
299
|
+
return buildResult(target, callerRows, importerRows, subclassRows, typeRefRows, compact, depth);
|
|
300
|
+
}
|
|
301
|
+
function handleSymbolDependents(db, args, depth, compact, limit) {
|
|
302
|
+
const symbols = getSymbolsByName(db, args.query, {
|
|
303
|
+
branch: args.branch,
|
|
304
|
+
matchMode: 'exact',
|
|
305
|
+
});
|
|
306
|
+
if (symbols.length === 0) {
|
|
307
|
+
return { error: `No symbol found matching name "${args.query}"` };
|
|
308
|
+
}
|
|
309
|
+
// If multiple matches, use the first but if many are ambiguous, report
|
|
310
|
+
if (symbols.length > 5) {
|
|
311
|
+
return {
|
|
312
|
+
error: `Ambiguous: ${symbols.length} symbols match "${args.query}". Narrow your query with a more specific name.`,
|
|
313
|
+
candidates: symbols.slice(0, 10).map((s) => {
|
|
314
|
+
const file = getFileById(db, s.file_id, args.branch);
|
|
315
|
+
return { id: s.id, name: s.name, kind: s.kind, file: file?.path ?? '' };
|
|
316
|
+
}),
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
// Use the best match (first result). If there are a few, aggregate across all.
|
|
320
|
+
const symbolIds = symbols.map((s) => s.id);
|
|
321
|
+
const primarySymbol = symbols[0];
|
|
322
|
+
const primaryFile = getFileById(db, primarySymbol.file_id, args.branch);
|
|
323
|
+
const target = {
|
|
324
|
+
id: primarySymbol.id,
|
|
325
|
+
name: primarySymbol.name,
|
|
326
|
+
kind: primarySymbol.kind,
|
|
327
|
+
file: primaryFile?.path,
|
|
328
|
+
};
|
|
329
|
+
const callerRows = expandCallers(db, symbolIds, args.branch, depth, limit);
|
|
330
|
+
const subclassRows = expandSubclasses(db, symbolIds, args.branch, depth, limit);
|
|
331
|
+
const typeRefRows = queryTypeReferences(db, symbolIds, args.branch, limit);
|
|
332
|
+
// For symbols, importers are files that import the file containing this symbol
|
|
333
|
+
const fileIds = [...new Set(symbols.map((s) => s.file_id))];
|
|
334
|
+
const importerRows = expandImporters(db, fileIds, args.branch, depth, limit);
|
|
335
|
+
return buildResult(target, callerRows, importerRows, subclassRows, typeRefRows, compact, depth);
|
|
336
|
+
}
|
|
337
|
+
function buildResult(target, callerRows, importerRows, subclassRows, typeRefRows, compact, depth) {
|
|
338
|
+
const callers = compact ? callerRows.map(compactCaller) : callerRows;
|
|
339
|
+
const importers = compact ? importerRows.map(compactImporter) : importerRows;
|
|
340
|
+
const subclasses = compact ? subclassRows.map(compactSubclass) : subclassRows;
|
|
341
|
+
const typeRefs = compact ? typeRefRows.map(compactTypeRef) : typeRefRows;
|
|
342
|
+
return {
|
|
343
|
+
target,
|
|
344
|
+
dependents: {
|
|
345
|
+
callers,
|
|
346
|
+
importers,
|
|
347
|
+
subclasses,
|
|
348
|
+
type_references: typeRefs,
|
|
349
|
+
},
|
|
350
|
+
depth_used: depth,
|
|
351
|
+
total_count: callers.length + importers.length + subclasses.length + typeRefs.length,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
//# sourceMappingURL=dependents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependents.js","sourceRoot":"","sources":["../../../src/server/tools/dependents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module lore-server/tools/diff
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: compare exported symbols between two indexed branches.
|
|
5
|
+
*/
|
|
6
|
+
import type { Database } from '../../db/read-only.js';
|
|
7
|
+
export declare const toolDef: {
|
|
8
|
+
readonly name: "lore_diff";
|
|
9
|
+
readonly description: string;
|
|
10
|
+
readonly inputSchema: {
|
|
11
|
+
readonly type: "object";
|
|
12
|
+
readonly properties: {
|
|
13
|
+
readonly old_branch: {
|
|
14
|
+
readonly type: "string";
|
|
15
|
+
readonly description: "The baseline branch to diff from.";
|
|
16
|
+
};
|
|
17
|
+
readonly new_branch: {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
readonly description: "The target branch to diff to. Defaults to the most recently indexed branch.";
|
|
20
|
+
};
|
|
21
|
+
readonly path_prefix: {
|
|
22
|
+
readonly type: "string";
|
|
23
|
+
readonly description: "Limit results to files whose path starts with this prefix.";
|
|
24
|
+
};
|
|
25
|
+
readonly kind: {
|
|
26
|
+
readonly type: "string";
|
|
27
|
+
readonly description: "Limit results to symbols of this kind (e.g. \"function\", \"class\").";
|
|
28
|
+
};
|
|
29
|
+
readonly limit: {
|
|
30
|
+
readonly type: "integer";
|
|
31
|
+
readonly description: "Max entries per result array (default 50, max 500).";
|
|
32
|
+
readonly minimum: 1;
|
|
33
|
+
readonly maximum: 500;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
readonly required: readonly ["old_branch"];
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export interface DiffArgs {
|
|
40
|
+
old_branch: string;
|
|
41
|
+
new_branch?: string;
|
|
42
|
+
path_prefix?: string;
|
|
43
|
+
kind?: string;
|
|
44
|
+
limit?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface DiffEntry {
|
|
47
|
+
name: string;
|
|
48
|
+
kind: string;
|
|
49
|
+
file_path: string;
|
|
50
|
+
signature: string | null;
|
|
51
|
+
}
|
|
52
|
+
export interface ChangedEntry {
|
|
53
|
+
name: string;
|
|
54
|
+
kind: string;
|
|
55
|
+
file_path: string;
|
|
56
|
+
old_signature: string | null;
|
|
57
|
+
new_signature: string | null;
|
|
58
|
+
}
|
|
59
|
+
export interface DiffResult {
|
|
60
|
+
old_branch: string;
|
|
61
|
+
new_branch: string;
|
|
62
|
+
added: DiffEntry[];
|
|
63
|
+
removed: DiffEntry[];
|
|
64
|
+
changed: ChangedEntry[];
|
|
65
|
+
summary: {
|
|
66
|
+
added_count: number;
|
|
67
|
+
removed_count: number;
|
|
68
|
+
changed_count: number;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Compare exported symbols between two indexed branches. */
|
|
72
|
+
export declare function handler(db: Database.Database, args: DiffArgs): DiffResult;
|
|
73
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/server/tools/diff.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAItD,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCV,CAAC;AAIX,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAID,6DAA6D;AAC7D,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,GAAG,UAAU,CA0GzE"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module lore-server/tools/diff
|
|
3
|
+
*
|
|
4
|
+
* MCP tool: compare exported symbols between two indexed branches.
|
|
5
|
+
*/
|
|
6
|
+
// ─── Tool definition ──────────────────────────────────────────────────────────
|
|
7
|
+
export const toolDef = {
|
|
8
|
+
name: 'lore_diff',
|
|
9
|
+
description: 'Compare exported symbols between two indexed branches. ' +
|
|
10
|
+
'Returns added, removed, and changed (signature-different) symbols.',
|
|
11
|
+
inputSchema: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
old_branch: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
description: 'The baseline branch to diff from.',
|
|
17
|
+
},
|
|
18
|
+
new_branch: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
description: 'The target branch to diff to. Defaults to the most recently indexed branch.',
|
|
21
|
+
},
|
|
22
|
+
path_prefix: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'Limit results to files whose path starts with this prefix.',
|
|
25
|
+
},
|
|
26
|
+
kind: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
description: 'Limit results to symbols of this kind (e.g. "function", "class").',
|
|
29
|
+
},
|
|
30
|
+
limit: {
|
|
31
|
+
type: 'integer',
|
|
32
|
+
description: 'Max entries per result array (default 50, max 500).',
|
|
33
|
+
minimum: 1,
|
|
34
|
+
maximum: 500,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: ['old_branch'],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
// ─── Handler ──────────────────────────────────────────────────────────────────
|
|
41
|
+
/** Compare exported symbols between two indexed branches. */
|
|
42
|
+
export function handler(db, args) {
|
|
43
|
+
const oldBranch = args.old_branch;
|
|
44
|
+
const newBranch = args.new_branch ?? resolveDefaultBranch(db, oldBranch);
|
|
45
|
+
const limit = Math.min(Math.max(1, args.limit ?? 50), 500);
|
|
46
|
+
const filterClauses = [];
|
|
47
|
+
const filterParams = [];
|
|
48
|
+
// Separate filter clauses for the changed query which uses different aliases
|
|
49
|
+
const changedFilterClauses = [];
|
|
50
|
+
const changedFilterParams = [];
|
|
51
|
+
if (args.path_prefix) {
|
|
52
|
+
const prefixPattern = escapeLikePrefix(args.path_prefix);
|
|
53
|
+
filterClauses.push('AND f.path LIKE ? ESCAPE \'\\\'');
|
|
54
|
+
filterParams.push(prefixPattern);
|
|
55
|
+
changedFilterClauses.push('AND f_new.path LIKE ? ESCAPE \'\\\'');
|
|
56
|
+
changedFilterParams.push(prefixPattern);
|
|
57
|
+
}
|
|
58
|
+
if (args.kind) {
|
|
59
|
+
filterClauses.push('AND s.kind = ?');
|
|
60
|
+
filterParams.push(args.kind);
|
|
61
|
+
changedFilterClauses.push('AND s_new.kind = ?');
|
|
62
|
+
changedFilterParams.push(args.kind);
|
|
63
|
+
}
|
|
64
|
+
const filters = filterClauses.join(' ');
|
|
65
|
+
const changedFilters = changedFilterClauses.join(' ');
|
|
66
|
+
// Added: exported symbols in new_branch not present in old_branch
|
|
67
|
+
const added = db.prepare(`SELECT s.name, s.kind, f.path AS file_path, s.signature
|
|
68
|
+
FROM symbols s
|
|
69
|
+
JOIN files f ON f.id = s.file_id
|
|
70
|
+
WHERE f.branch = ?
|
|
71
|
+
AND s.is_exported = 1
|
|
72
|
+
${filters}
|
|
73
|
+
AND NOT EXISTS (
|
|
74
|
+
SELECT 1
|
|
75
|
+
FROM symbols s2
|
|
76
|
+
JOIN files f2 ON f2.id = s2.file_id
|
|
77
|
+
WHERE f2.branch = ?
|
|
78
|
+
AND s2.name = s.name
|
|
79
|
+
AND s2.kind = s.kind
|
|
80
|
+
AND f2.path = f.path
|
|
81
|
+
AND s2.is_exported = 1
|
|
82
|
+
)
|
|
83
|
+
ORDER BY f.path, s.name
|
|
84
|
+
LIMIT ?`).all(newBranch, ...filterParams, oldBranch, limit);
|
|
85
|
+
// Removed: exported symbols in old_branch not present in new_branch
|
|
86
|
+
const removed = db.prepare(`SELECT s.name, s.kind, f.path AS file_path, s.signature
|
|
87
|
+
FROM symbols s
|
|
88
|
+
JOIN files f ON f.id = s.file_id
|
|
89
|
+
WHERE f.branch = ?
|
|
90
|
+
AND s.is_exported = 1
|
|
91
|
+
${filters}
|
|
92
|
+
AND NOT EXISTS (
|
|
93
|
+
SELECT 1
|
|
94
|
+
FROM symbols s2
|
|
95
|
+
JOIN files f2 ON f2.id = s2.file_id
|
|
96
|
+
WHERE f2.branch = ?
|
|
97
|
+
AND s2.name = s.name
|
|
98
|
+
AND s2.kind = s.kind
|
|
99
|
+
AND f2.path = f.path
|
|
100
|
+
AND s2.is_exported = 1
|
|
101
|
+
)
|
|
102
|
+
ORDER BY f.path, s.name
|
|
103
|
+
LIMIT ?`).all(oldBranch, ...filterParams, newBranch, limit);
|
|
104
|
+
// Changed: same name/kind/path but different signature across branches
|
|
105
|
+
const changed = db.prepare(`SELECT s_new.name,
|
|
106
|
+
s_new.kind,
|
|
107
|
+
f_new.path AS file_path,
|
|
108
|
+
s_old.signature AS old_signature,
|
|
109
|
+
s_new.signature AS new_signature
|
|
110
|
+
FROM symbols s_new
|
|
111
|
+
JOIN files f_new ON f_new.id = s_new.file_id
|
|
112
|
+
JOIN files f_old ON f_old.path = f_new.path AND f_old.branch = ?
|
|
113
|
+
JOIN symbols s_old ON s_old.file_id = f_old.id
|
|
114
|
+
AND s_old.name = s_new.name
|
|
115
|
+
AND s_old.kind = s_new.kind
|
|
116
|
+
AND s_old.is_exported = 1
|
|
117
|
+
WHERE f_new.branch = ?
|
|
118
|
+
AND s_new.is_exported = 1
|
|
119
|
+
${changedFilters}
|
|
120
|
+
AND COALESCE(s_new.signature, '') != COALESCE(s_old.signature, '')
|
|
121
|
+
ORDER BY f_new.path, s_new.name
|
|
122
|
+
LIMIT ?`).all(oldBranch, newBranch, ...changedFilterParams, limit);
|
|
123
|
+
return {
|
|
124
|
+
old_branch: oldBranch,
|
|
125
|
+
new_branch: newBranch,
|
|
126
|
+
added,
|
|
127
|
+
removed,
|
|
128
|
+
changed,
|
|
129
|
+
summary: {
|
|
130
|
+
added_count: added.length,
|
|
131
|
+
removed_count: removed.length,
|
|
132
|
+
changed_count: changed.length,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
137
|
+
/**
|
|
138
|
+
* Resolve the default new_branch by picking the most recently indexed branch
|
|
139
|
+
* from the files table that is different from old_branch.
|
|
140
|
+
*/
|
|
141
|
+
function resolveDefaultBranch(db, oldBranch) {
|
|
142
|
+
const row = db.prepare(`SELECT branch FROM files
|
|
143
|
+
WHERE branch != ?
|
|
144
|
+
ORDER BY indexed_at DESC
|
|
145
|
+
LIMIT 1`).get(oldBranch);
|
|
146
|
+
if (!row) {
|
|
147
|
+
throw new Error(`Cannot resolve new_branch: no other indexed branch found besides '${oldBranch}'. ` +
|
|
148
|
+
'Please specify new_branch explicitly.');
|
|
149
|
+
}
|
|
150
|
+
return row.branch;
|
|
151
|
+
}
|
|
152
|
+
/** Escape a path prefix for use with LIKE … ESCAPE '\\'. */
|
|
153
|
+
function escapeLikePrefix(prefix) {
|
|
154
|
+
const escaped = prefix.replace(/\\/g, '\\\\').replace(/%/g, '\\%').replace(/_/g, '\\_');
|
|
155
|
+
return escaped + '%';
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/server/tools/diff.ts"],"names":[],"mappings":"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"}
|