@crowley/rag-mcp 1.0.5 → 1.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/dist/annotations.d.ts +16 -0
- package/dist/annotations.js +158 -0
- package/dist/context-enrichment.js +7 -0
- package/dist/formatters.d.ts +2 -0
- package/dist/formatters.js +12 -0
- package/dist/index.js +99 -47
- package/dist/schemas.d.ts +97 -0
- package/dist/schemas.js +128 -0
- package/dist/tool-middleware.d.ts +40 -0
- package/dist/tool-middleware.js +216 -0
- package/dist/tool-registry.js +2 -1
- package/dist/tools/advanced.d.ts +2 -2
- package/dist/tools/advanced.js +200 -275
- package/dist/tools/agents.d.ts +2 -2
- package/dist/tools/agents.js +59 -78
- package/dist/tools/analytics.d.ts +2 -2
- package/dist/tools/analytics.js +170 -210
- package/dist/tools/architecture.d.ts +2 -2
- package/dist/tools/architecture.js +506 -669
- package/dist/tools/ask.d.ts +2 -2
- package/dist/tools/ask.js +164 -219
- package/dist/tools/cache.d.ts +2 -2
- package/dist/tools/cache.js +63 -82
- package/dist/tools/clustering.d.ts +2 -2
- package/dist/tools/clustering.js +154 -215
- package/dist/tools/confluence.d.ts +2 -2
- package/dist/tools/confluence.js +80 -116
- package/dist/tools/database.d.ts +2 -2
- package/dist/tools/database.js +303 -380
- package/dist/tools/feedback.d.ts +2 -2
- package/dist/tools/feedback.js +143 -184
- package/dist/tools/guidelines.d.ts +2 -2
- package/dist/tools/guidelines.js +123 -135
- package/dist/tools/indexing.d.ts +2 -2
- package/dist/tools/indexing.js +100 -108
- package/dist/tools/memory.d.ts +2 -2
- package/dist/tools/memory.js +299 -485
- package/dist/tools/pm.d.ts +2 -2
- package/dist/tools/pm.js +367 -615
- package/dist/tools/quality.d.ts +8 -0
- package/dist/tools/quality.js +60 -0
- package/dist/tools/review.d.ts +2 -2
- package/dist/tools/review.js +142 -189
- package/dist/tools/search.d.ts +2 -2
- package/dist/tools/search.js +230 -305
- package/dist/tools/session.d.ts +2 -2
- package/dist/tools/session.js +288 -345
- package/dist/tools/suggestions.d.ts +2 -2
- package/dist/tools/suggestions.js +517 -512
- package/dist/types.d.ts +19 -2
- package/package.json +4 -2
package/dist/tools/search.js
CHANGED
|
@@ -3,355 +3,280 @@
|
|
|
3
3
|
* documentation search, and project statistics.
|
|
4
4
|
*/
|
|
5
5
|
import { formatCodeResults, formatNavigationResults, truncate } from "../formatters.js";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { TOOL_ANNOTATIONS } from "../annotations.js";
|
|
6
8
|
/**
|
|
7
9
|
* Create the search tools module with project-specific descriptions.
|
|
8
10
|
*/
|
|
9
11
|
export function createSearchTools(projectName) {
|
|
10
|
-
|
|
12
|
+
return [
|
|
11
13
|
{
|
|
12
14
|
name: "search_codebase",
|
|
13
15
|
description: `Search the ${projectName} codebase. Returns file locations, symbols, and graph connections. Use Read tool to view the actual code at returned locations.`,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
service: {
|
|
39
|
-
type: "string",
|
|
40
|
-
description: "Filter by service/class name (e.g., 'EmbeddingService')",
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
required: ["query"],
|
|
16
|
+
schema: z.object({
|
|
17
|
+
query: z.string().describe("Search query for finding code"),
|
|
18
|
+
limit: z.number().optional().describe("Max results to return (default: 5)"),
|
|
19
|
+
language: z.string().optional().describe("Filter by language (typescript, python, vue, etc.)"),
|
|
20
|
+
path: z.string().optional().describe("Filter by path pattern (e.g., 'src/modules/*')"),
|
|
21
|
+
layer: z.string().optional().describe("Filter by architectural layer (api, service, util, model, middleware, test, parser, types, config, other)"),
|
|
22
|
+
service: z.string().optional().describe("Filter by service/class name (e.g., 'EmbeddingService')"),
|
|
23
|
+
}),
|
|
24
|
+
annotations: TOOL_ANNOTATIONS["search_codebase"],
|
|
25
|
+
handler: async (args, ctx) => {
|
|
26
|
+
const { query, limit = 5, language, path, layer, service } = args;
|
|
27
|
+
const response = await ctx.api.post("/api/search", {
|
|
28
|
+
collection: `${ctx.collectionPrefix}codebase`,
|
|
29
|
+
query,
|
|
30
|
+
limit,
|
|
31
|
+
mode: "navigate",
|
|
32
|
+
filters: { language, path, layer, service },
|
|
33
|
+
});
|
|
34
|
+
const results = response.data.results;
|
|
35
|
+
if (!results || results.length === 0) {
|
|
36
|
+
return "No results found for this query.";
|
|
37
|
+
}
|
|
38
|
+
return formatNavigationResults(results);
|
|
44
39
|
},
|
|
45
40
|
},
|
|
46
41
|
{
|
|
47
42
|
name: "search_similar",
|
|
48
43
|
description: "Find code similar to a given snippet.",
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
44
|
+
schema: z.object({
|
|
45
|
+
code: z.string().describe("Code snippet to find similar code for"),
|
|
46
|
+
limit: z.number().optional().describe("Max results (default: 5)"),
|
|
47
|
+
}),
|
|
48
|
+
annotations: TOOL_ANNOTATIONS["search_similar"],
|
|
49
|
+
handler: async (args, ctx) => {
|
|
50
|
+
const { code, limit = 5 } = args;
|
|
51
|
+
const response = await ctx.api.post("/api/search-similar", {
|
|
52
|
+
collection: `${ctx.collectionPrefix}codebase`,
|
|
53
|
+
code,
|
|
54
|
+
limit,
|
|
55
|
+
});
|
|
56
|
+
const results = response.data.results;
|
|
57
|
+
if (!results || results.length === 0) {
|
|
58
|
+
return "No similar code found.";
|
|
59
|
+
}
|
|
60
|
+
return formatCodeResults(results, 400);
|
|
63
61
|
},
|
|
64
62
|
},
|
|
65
63
|
{
|
|
66
64
|
name: "grouped_search",
|
|
67
65
|
description: `Search ${projectName} codebase grouped by file. Returns file locations with symbols and connections. Use Read tool to view the actual code.`,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
description: "Filter by service/class name",
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
required: ["query"],
|
|
66
|
+
schema: z.object({
|
|
67
|
+
query: z.string().describe("Search query"),
|
|
68
|
+
groupBy: z.string().optional().describe("Field to group by (default: 'file')"),
|
|
69
|
+
limit: z.number().optional().describe("Max groups to return (default: 10)"),
|
|
70
|
+
language: z.string().optional().describe("Filter by language"),
|
|
71
|
+
layer: z.string().optional().describe("Filter by architectural layer (api, service, util, etc.)"),
|
|
72
|
+
service: z.string().optional().describe("Filter by service/class name"),
|
|
73
|
+
}),
|
|
74
|
+
annotations: TOOL_ANNOTATIONS["grouped_search"],
|
|
75
|
+
handler: async (args, ctx) => {
|
|
76
|
+
const { query, groupBy = "file", limit = 10, language, layer, service } = args;
|
|
77
|
+
const filters = { language, layer, service };
|
|
78
|
+
const hasFilters = Object.values(filters).some(v => v !== undefined);
|
|
79
|
+
const response = await ctx.api.post("/api/search-grouped", {
|
|
80
|
+
collection: `${ctx.collectionPrefix}codebase`,
|
|
81
|
+
query,
|
|
82
|
+
groupBy,
|
|
83
|
+
limit,
|
|
84
|
+
mode: "navigate",
|
|
85
|
+
filters: hasFilters ? filters : undefined,
|
|
86
|
+
});
|
|
87
|
+
const groups = response.data.groups;
|
|
88
|
+
if (!groups || groups.length === 0) {
|
|
89
|
+
return "No results found.";
|
|
90
|
+
}
|
|
91
|
+
const allResults = groups.flatMap((g) => g.results);
|
|
92
|
+
return formatNavigationResults(allResults);
|
|
99
93
|
},
|
|
100
94
|
},
|
|
101
95
|
{
|
|
102
96
|
name: "hybrid_search",
|
|
103
97
|
description: `Hybrid search combining keyword matching and semantic similarity for ${projectName}. Returns file locations with symbols and connections. Use Read tool to view code.`,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
type: "string",
|
|
131
|
-
description: "Filter by service/class name",
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
required: ["query"],
|
|
98
|
+
schema: z.object({
|
|
99
|
+
query: z.string().describe("Search query"),
|
|
100
|
+
limit: z.number().optional().describe("Max results (default: 10)"),
|
|
101
|
+
semanticWeight: z.number().optional().describe("Weight for semantic vs keyword (0-1, default: 0.7)"),
|
|
102
|
+
language: z.string().optional().describe("Filter by language"),
|
|
103
|
+
layer: z.string().optional().describe("Filter by architectural layer (api, service, util, etc.)"),
|
|
104
|
+
service: z.string().optional().describe("Filter by service/class name"),
|
|
105
|
+
}),
|
|
106
|
+
annotations: TOOL_ANNOTATIONS["hybrid_search"],
|
|
107
|
+
handler: async (args, ctx) => {
|
|
108
|
+
const { query, limit = 10, semanticWeight = 0.7, language, layer, service } = args;
|
|
109
|
+
const filters = { language, layer, service };
|
|
110
|
+
const hasFilters = Object.values(filters).some(v => v !== undefined);
|
|
111
|
+
const response = await ctx.api.post("/api/search-hybrid", {
|
|
112
|
+
collection: `${ctx.collectionPrefix}codebase`,
|
|
113
|
+
query,
|
|
114
|
+
limit,
|
|
115
|
+
semanticWeight,
|
|
116
|
+
mode: "navigate",
|
|
117
|
+
filters: hasFilters ? filters : undefined,
|
|
118
|
+
});
|
|
119
|
+
const results = response.data.results;
|
|
120
|
+
if (!results || results.length === 0) {
|
|
121
|
+
return "No results found.";
|
|
122
|
+
}
|
|
123
|
+
return formatNavigationResults(results);
|
|
135
124
|
},
|
|
136
125
|
},
|
|
137
126
|
{
|
|
138
127
|
name: "search_docs",
|
|
139
128
|
description: `Search documentation in the ${projectName} project.`,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
129
|
+
schema: z.object({
|
|
130
|
+
query: z.string().describe("Search query"),
|
|
131
|
+
limit: z.number().optional().describe("Max results (default: 5)"),
|
|
132
|
+
}),
|
|
133
|
+
annotations: TOOL_ANNOTATIONS["search_docs"],
|
|
134
|
+
handler: async (args, ctx) => {
|
|
135
|
+
const { query, limit = 5 } = args;
|
|
136
|
+
const response = await ctx.api.post("/api/search", {
|
|
137
|
+
collection: `${ctx.collectionPrefix}docs`,
|
|
138
|
+
query,
|
|
139
|
+
limit,
|
|
140
|
+
});
|
|
141
|
+
const results = response.data.results;
|
|
142
|
+
if (!results || results.length === 0) {
|
|
143
|
+
return "No documentation found for this query.";
|
|
144
|
+
}
|
|
145
|
+
return results
|
|
146
|
+
.map((r) => `**${r.file}**\n` +
|
|
147
|
+
truncate(r.content, 500))
|
|
148
|
+
.join("\n\n---\n\n");
|
|
154
149
|
},
|
|
155
150
|
},
|
|
156
151
|
{
|
|
157
152
|
name: "get_project_stats",
|
|
158
153
|
description: `Get statistics about the ${projectName} codebase.`,
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
schema: z.object({}),
|
|
155
|
+
outputSchema: z.object({
|
|
156
|
+
projectName: z.string(),
|
|
157
|
+
totalFiles: z.number(),
|
|
158
|
+
totalLines: z.number().optional(),
|
|
159
|
+
vectorCount: z.number(),
|
|
160
|
+
lastIndexed: z.string().optional(),
|
|
161
|
+
languages: z.record(z.string(), z.number()).optional(),
|
|
162
|
+
}),
|
|
163
|
+
annotations: TOOL_ANNOTATIONS["get_project_stats"],
|
|
164
|
+
handler: async (_args, ctx) => {
|
|
165
|
+
const response = await ctx.api.get(`/api/stats/${ctx.collectionPrefix}codebase`);
|
|
166
|
+
const stats = response.data;
|
|
167
|
+
let text = `**${ctx.projectName} Project Statistics**\n\n`;
|
|
168
|
+
text += `- Total Files: ${stats.totalFiles}\n`;
|
|
169
|
+
text += `- Total Lines: ${stats.totalLines?.toLocaleString() || "N/A"}\n`;
|
|
170
|
+
text += `- Vector Count: ${stats.vectorCount}\n`;
|
|
171
|
+
text += `- Last Indexed: ${stats.lastIndexed ? new Date(stats.lastIndexed).toLocaleString() : "Never"}\n`;
|
|
172
|
+
if (stats.languages) {
|
|
173
|
+
text += `\n**Languages:**\n`;
|
|
174
|
+
for (const [lang, count] of Object.entries(stats.languages)) {
|
|
175
|
+
text += `- ${lang}: ${count} files\n`;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
text,
|
|
180
|
+
structured: {
|
|
181
|
+
projectName: ctx.projectName,
|
|
182
|
+
totalFiles: stats.totalFiles,
|
|
183
|
+
totalLines: stats.totalLines,
|
|
184
|
+
vectorCount: stats.vectorCount,
|
|
185
|
+
lastIndexed: stats.lastIndexed,
|
|
186
|
+
languages: stats.languages,
|
|
187
|
+
},
|
|
188
|
+
};
|
|
162
189
|
},
|
|
163
190
|
},
|
|
164
191
|
{
|
|
165
192
|
name: "find_symbol",
|
|
166
193
|
description: `Find a function, class, type, or interface by name in ${projectName}. Fast symbol lookup without full-text search.`,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
kind:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
194
|
+
schema: z.object({
|
|
195
|
+
symbol: z.string().describe("Symbol name to find (function, class, type, etc.)"),
|
|
196
|
+
kind: z.string().optional().describe("Filter by kind: function, class, interface, type, enum, const"),
|
|
197
|
+
limit: z.number().optional().describe("Max results (default: 10)"),
|
|
198
|
+
}),
|
|
199
|
+
outputSchema: z.object({
|
|
200
|
+
symbols: z.array(z.object({
|
|
201
|
+
kind: z.string(),
|
|
202
|
+
name: z.string(),
|
|
203
|
+
file: z.string(),
|
|
204
|
+
startLine: z.number(),
|
|
205
|
+
endLine: z.number(),
|
|
206
|
+
signature: z.string(),
|
|
207
|
+
exported: z.boolean(),
|
|
208
|
+
})),
|
|
209
|
+
}),
|
|
210
|
+
annotations: TOOL_ANNOTATIONS["find_symbol"],
|
|
211
|
+
handler: async (args, ctx) => {
|
|
212
|
+
const { symbol, kind, limit = 10 } = args;
|
|
213
|
+
const response = await ctx.api.post("/api/find-symbol", {
|
|
214
|
+
projectName: ctx.projectName,
|
|
215
|
+
symbol,
|
|
216
|
+
kind,
|
|
217
|
+
limit,
|
|
218
|
+
});
|
|
219
|
+
const results = response.data.results;
|
|
220
|
+
if (!results || results.length === 0) {
|
|
221
|
+
return `No symbol "${symbol}" found.`;
|
|
222
|
+
}
|
|
223
|
+
const text = results
|
|
224
|
+
.map((r) => `**${r.kind} ${r.name}** in \`${r.file}\` (lines ${r.startLine}-${r.endLine})\n` +
|
|
225
|
+
`\`${truncate(r.signature, 150)}\`` +
|
|
226
|
+
(r.exports ? " _(exported)_" : ""))
|
|
227
|
+
.join("\n\n");
|
|
228
|
+
return {
|
|
229
|
+
text,
|
|
230
|
+
structured: {
|
|
231
|
+
symbols: results.map((r) => ({
|
|
232
|
+
kind: r.kind,
|
|
233
|
+
name: r.name,
|
|
234
|
+
file: r.file,
|
|
235
|
+
startLine: r.startLine,
|
|
236
|
+
endLine: r.endLine,
|
|
237
|
+
signature: r.signature,
|
|
238
|
+
exported: !!r.exports,
|
|
239
|
+
})),
|
|
182
240
|
},
|
|
183
|
-
}
|
|
184
|
-
required: ["symbol"],
|
|
241
|
+
};
|
|
185
242
|
},
|
|
186
243
|
},
|
|
187
244
|
{
|
|
188
245
|
name: "search_graph",
|
|
189
246
|
description: `Search ${projectName} codebase with graph expansion. Returns file locations plus connected files via import/call relationships. Use Read tool to view code.`,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
expandHops
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
247
|
+
schema: z.object({
|
|
248
|
+
query: z.string().describe("Search query"),
|
|
249
|
+
limit: z.number().optional().describe("Max direct results (default: 5)"),
|
|
250
|
+
expandHops: z.number().optional().describe("Number of graph hops to expand (default: 1)"),
|
|
251
|
+
}),
|
|
252
|
+
annotations: TOOL_ANNOTATIONS["search_graph"],
|
|
253
|
+
handler: async (args, ctx) => {
|
|
254
|
+
const { query, limit = 5, expandHops = 1 } = args;
|
|
255
|
+
const response = await ctx.api.post("/api/search-graph", {
|
|
256
|
+
collection: `${ctx.collectionPrefix}codebase`,
|
|
257
|
+
query,
|
|
258
|
+
limit,
|
|
259
|
+
expandHops,
|
|
260
|
+
mode: "navigate",
|
|
261
|
+
});
|
|
262
|
+
const { results, graphExpanded, expandedFiles } = response.data;
|
|
263
|
+
if ((!results || results.length === 0) && (!graphExpanded || graphExpanded.length === 0)) {
|
|
264
|
+
return "No results found.";
|
|
265
|
+
}
|
|
266
|
+
let output = "";
|
|
267
|
+
if (results && results.length > 0) {
|
|
268
|
+
output += "**Direct matches:**\n\n";
|
|
269
|
+
output += formatNavigationResults(results);
|
|
270
|
+
}
|
|
271
|
+
if (graphExpanded && graphExpanded.length > 0) {
|
|
272
|
+
output += "\n\n---\n\n**Graph-connected files:**\n\n";
|
|
273
|
+
output += formatNavigationResults(graphExpanded);
|
|
274
|
+
}
|
|
275
|
+
if (expandedFiles && expandedFiles.length > 0) {
|
|
276
|
+
output += `\n\n_Graph expanded to ${expandedFiles.length} additional files._`;
|
|
277
|
+
}
|
|
278
|
+
return output;
|
|
209
279
|
},
|
|
210
280
|
},
|
|
211
281
|
];
|
|
212
|
-
const handlers = {
|
|
213
|
-
search_codebase: async (args, ctx) => {
|
|
214
|
-
const { query, limit = 5, language, path, layer, service } = args;
|
|
215
|
-
const response = await ctx.api.post("/api/search", {
|
|
216
|
-
collection: `${ctx.collectionPrefix}codebase`,
|
|
217
|
-
query,
|
|
218
|
-
limit,
|
|
219
|
-
mode: "navigate",
|
|
220
|
-
filters: { language, path, layer, service },
|
|
221
|
-
});
|
|
222
|
-
const results = response.data.results;
|
|
223
|
-
if (!results || results.length === 0) {
|
|
224
|
-
return "No results found for this query.";
|
|
225
|
-
}
|
|
226
|
-
return formatNavigationResults(results);
|
|
227
|
-
},
|
|
228
|
-
search_similar: async (args, ctx) => {
|
|
229
|
-
const { code, limit = 5 } = args;
|
|
230
|
-
const response = await ctx.api.post("/api/search-similar", {
|
|
231
|
-
collection: `${ctx.collectionPrefix}codebase`,
|
|
232
|
-
code,
|
|
233
|
-
limit,
|
|
234
|
-
});
|
|
235
|
-
const results = response.data.results;
|
|
236
|
-
if (!results || results.length === 0) {
|
|
237
|
-
return "No similar code found.";
|
|
238
|
-
}
|
|
239
|
-
return formatCodeResults(results, 400);
|
|
240
|
-
},
|
|
241
|
-
grouped_search: async (args, ctx) => {
|
|
242
|
-
const { query, groupBy = "file", limit = 10, language, layer, service } = args;
|
|
243
|
-
const filters = { language, layer, service };
|
|
244
|
-
const hasFilters = Object.values(filters).some(v => v !== undefined);
|
|
245
|
-
const response = await ctx.api.post("/api/search-grouped", {
|
|
246
|
-
collection: `${ctx.collectionPrefix}codebase`,
|
|
247
|
-
query,
|
|
248
|
-
groupBy,
|
|
249
|
-
limit,
|
|
250
|
-
mode: "navigate",
|
|
251
|
-
filters: hasFilters ? filters : undefined,
|
|
252
|
-
});
|
|
253
|
-
const groups = response.data.groups;
|
|
254
|
-
if (!groups || groups.length === 0) {
|
|
255
|
-
return "No results found.";
|
|
256
|
-
}
|
|
257
|
-
const allResults = groups.flatMap((g) => g.results);
|
|
258
|
-
return formatNavigationResults(allResults);
|
|
259
|
-
},
|
|
260
|
-
hybrid_search: async (args, ctx) => {
|
|
261
|
-
const { query, limit = 10, semanticWeight = 0.7, language, layer, service } = args;
|
|
262
|
-
const filters = { language, layer, service };
|
|
263
|
-
const hasFilters = Object.values(filters).some(v => v !== undefined);
|
|
264
|
-
const response = await ctx.api.post("/api/search-hybrid", {
|
|
265
|
-
collection: `${ctx.collectionPrefix}codebase`,
|
|
266
|
-
query,
|
|
267
|
-
limit,
|
|
268
|
-
semanticWeight,
|
|
269
|
-
mode: "navigate",
|
|
270
|
-
filters: hasFilters ? filters : undefined,
|
|
271
|
-
});
|
|
272
|
-
const results = response.data.results;
|
|
273
|
-
if (!results || results.length === 0) {
|
|
274
|
-
return "No results found.";
|
|
275
|
-
}
|
|
276
|
-
return formatNavigationResults(results);
|
|
277
|
-
},
|
|
278
|
-
search_docs: async (args, ctx) => {
|
|
279
|
-
const { query, limit = 5 } = args;
|
|
280
|
-
const response = await ctx.api.post("/api/search", {
|
|
281
|
-
collection: `${ctx.collectionPrefix}docs`,
|
|
282
|
-
query,
|
|
283
|
-
limit,
|
|
284
|
-
});
|
|
285
|
-
const results = response.data.results;
|
|
286
|
-
if (!results || results.length === 0) {
|
|
287
|
-
return "No documentation found for this query.";
|
|
288
|
-
}
|
|
289
|
-
return results
|
|
290
|
-
.map((r) => `**${r.file}**\n` +
|
|
291
|
-
truncate(r.content, 500))
|
|
292
|
-
.join("\n\n---\n\n");
|
|
293
|
-
},
|
|
294
|
-
find_symbol: async (args, ctx) => {
|
|
295
|
-
const { symbol, kind, limit = 10 } = args;
|
|
296
|
-
const response = await ctx.api.post("/api/find-symbol", {
|
|
297
|
-
projectName: ctx.projectName,
|
|
298
|
-
symbol,
|
|
299
|
-
kind,
|
|
300
|
-
limit,
|
|
301
|
-
});
|
|
302
|
-
const results = response.data.results;
|
|
303
|
-
if (!results || results.length === 0) {
|
|
304
|
-
return `No symbol "${symbol}" found.`;
|
|
305
|
-
}
|
|
306
|
-
return results
|
|
307
|
-
.map((r) => `**${r.kind} ${r.name}** in \`${r.file}\` (lines ${r.startLine}-${r.endLine})\n` +
|
|
308
|
-
`\`${truncate(r.signature, 150)}\`` +
|
|
309
|
-
(r.exports ? " _(exported)_" : ""))
|
|
310
|
-
.join("\n\n");
|
|
311
|
-
},
|
|
312
|
-
search_graph: async (args, ctx) => {
|
|
313
|
-
const { query, limit = 5, expandHops = 1 } = args;
|
|
314
|
-
const response = await ctx.api.post("/api/search-graph", {
|
|
315
|
-
collection: `${ctx.collectionPrefix}codebase`,
|
|
316
|
-
query,
|
|
317
|
-
limit,
|
|
318
|
-
expandHops,
|
|
319
|
-
mode: "navigate",
|
|
320
|
-
});
|
|
321
|
-
const { results, graphExpanded, expandedFiles } = response.data;
|
|
322
|
-
if ((!results || results.length === 0) && (!graphExpanded || graphExpanded.length === 0)) {
|
|
323
|
-
return "No results found.";
|
|
324
|
-
}
|
|
325
|
-
let output = "";
|
|
326
|
-
if (results && results.length > 0) {
|
|
327
|
-
output += "**Direct matches:**\n\n";
|
|
328
|
-
output += formatNavigationResults(results);
|
|
329
|
-
}
|
|
330
|
-
if (graphExpanded && graphExpanded.length > 0) {
|
|
331
|
-
output += "\n\n---\n\n**Graph-connected files:**\n\n";
|
|
332
|
-
output += formatNavigationResults(graphExpanded);
|
|
333
|
-
}
|
|
334
|
-
if (expandedFiles && expandedFiles.length > 0) {
|
|
335
|
-
output += `\n\n_Graph expanded to ${expandedFiles.length} additional files._`;
|
|
336
|
-
}
|
|
337
|
-
return output;
|
|
338
|
-
},
|
|
339
|
-
get_project_stats: async (_args, ctx) => {
|
|
340
|
-
const response = await ctx.api.get(`/api/stats/${ctx.collectionPrefix}codebase`);
|
|
341
|
-
const stats = response.data;
|
|
342
|
-
let result = `**${ctx.projectName} Project Statistics**\n\n`;
|
|
343
|
-
result += `- Total Files: ${stats.totalFiles}\n`;
|
|
344
|
-
result += `- Total Lines: ${stats.totalLines?.toLocaleString() || "N/A"}\n`;
|
|
345
|
-
result += `- Vector Count: ${stats.vectorCount}\n`;
|
|
346
|
-
result += `- Last Indexed: ${stats.lastIndexed ? new Date(stats.lastIndexed).toLocaleString() : "Never"}\n`;
|
|
347
|
-
if (stats.languages) {
|
|
348
|
-
result += `\n**Languages:**\n`;
|
|
349
|
-
for (const [lang, count] of Object.entries(stats.languages)) {
|
|
350
|
-
result += `- ${lang}: ${count} files\n`;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
return result;
|
|
354
|
-
},
|
|
355
|
-
};
|
|
356
|
-
return { tools, handlers };
|
|
357
282
|
}
|
package/dist/tools/session.d.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Session tools module - context summarization, session lifecycle management,
|
|
3
3
|
* change tracking, and usage pattern analysis.
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
5
|
+
import type { ToolSpec, ToolContext } from "../types.js";
|
|
6
6
|
/**
|
|
7
7
|
* Create the session tools module with project-specific descriptions.
|
|
8
8
|
* Accepts a mutable ctx reference to update activeSessionId on start/end.
|
|
9
9
|
*/
|
|
10
|
-
export declare function createSessionTools(projectName: string, sharedCtx?: ToolContext):
|
|
10
|
+
export declare function createSessionTools(projectName: string, sharedCtx?: ToolContext): ToolSpec[];
|