@crowley/rag-mcp 1.5.0 → 1.6.1
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/__tests__/tool-middleware.test.js +51 -51
- package/dist/__tests__/tools/memory.test.js +78 -63
- package/dist/api-client.d.ts +49 -2
- package/dist/api-client.js +139 -7
- package/dist/connection-pool.d.ts +15 -0
- package/dist/connection-pool.js +24 -0
- package/dist/context-enrichment.js +5 -3
- package/dist/formatters.js +12 -8
- package/dist/http-transport.d.ts +15 -0
- package/dist/http-transport.js +109 -0
- package/dist/index.js +27 -4
- package/dist/schemas.js +3 -12
- package/dist/tool-middleware.js +13 -8
- package/dist/tool-registry.js +11 -4
- package/dist/tools/advanced.js +64 -19
- package/dist/tools/agents.js +42 -13
- package/dist/tools/analytics.js +17 -5
- package/dist/tools/architecture.js +115 -31
- package/dist/tools/ask.js +23 -8
- package/dist/tools/cache.js +12 -3
- package/dist/tools/clustering.js +53 -17
- package/dist/tools/confluence.js +26 -8
- package/dist/tools/database.js +87 -24
- package/dist/tools/feedback.js +22 -6
- package/dist/tools/guidelines.js +15 -2
- package/dist/tools/indexing.js +34 -8
- package/dist/tools/memory.js +199 -39
- package/dist/tools/pm.js +38 -11
- package/dist/tools/quality.js +7 -2
- package/dist/tools/review.js +25 -7
- package/dist/tools/search.js +92 -31
- package/dist/tools/session.js +58 -26
- package/dist/tools/suggestions.js +75 -22
- package/dist/types.d.ts +2 -2
- package/dist/validation-hooks.js +27 -11
- package/package.json +2 -2
package/dist/tools/memory.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* batch_remember, validate_memory, review_memories,
|
|
6
6
|
* promote_memory, run_quality_gates, memory_maintenance
|
|
7
7
|
*/
|
|
8
|
-
import { formatMemoryResults, truncate, paginationFooter, PREVIEW } from "../formatters.js";
|
|
8
|
+
import { formatMemoryResults, truncate, paginationFooter, PREVIEW, } from "../formatters.js";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { TOOL_ANNOTATIONS } from "../annotations.js";
|
|
11
11
|
const typeEmojis = {
|
|
@@ -15,6 +15,7 @@ const typeEmojis = {
|
|
|
15
15
|
todo: "\u{1F4CB}",
|
|
16
16
|
conversation: "\u{1F4AC}",
|
|
17
17
|
note: "\u{1F4DD}",
|
|
18
|
+
procedure: "\u{1F4D6}",
|
|
18
19
|
};
|
|
19
20
|
const statusEmojis = {
|
|
20
21
|
pending: "\u23F3",
|
|
@@ -29,8 +30,22 @@ export function createMemoryTools(projectName) {
|
|
|
29
30
|
description: "Store important information in agent memory. Use this to save decisions, insights, context, todos, or important conversations for future reference.",
|
|
30
31
|
schema: z.object({
|
|
31
32
|
content: z.string().describe("Information to remember"),
|
|
32
|
-
type: z
|
|
33
|
-
|
|
33
|
+
type: z
|
|
34
|
+
.enum([
|
|
35
|
+
"decision",
|
|
36
|
+
"insight",
|
|
37
|
+
"context",
|
|
38
|
+
"todo",
|
|
39
|
+
"conversation",
|
|
40
|
+
"note",
|
|
41
|
+
"procedure",
|
|
42
|
+
])
|
|
43
|
+
.optional()
|
|
44
|
+
.describe("Type of memory (default: note)"),
|
|
45
|
+
tags: z
|
|
46
|
+
.array(z.string())
|
|
47
|
+
.optional()
|
|
48
|
+
.describe("Tags for categorization (e.g., ['feature-x', 'important'])"),
|
|
34
49
|
relatedTo: z.string().optional().describe("Related feature or topic"),
|
|
35
50
|
}),
|
|
36
51
|
annotations: TOOL_ANNOTATIONS["remember"],
|
|
@@ -61,9 +76,27 @@ export function createMemoryTools(projectName) {
|
|
|
61
76
|
description: "Retrieve relevant memories based on context. Searches agent memory for past decisions, insights, and notes related to the query.",
|
|
62
77
|
schema: z.object({
|
|
63
78
|
query: z.string().describe("What to recall (semantic search)"),
|
|
64
|
-
type: z
|
|
65
|
-
|
|
66
|
-
|
|
79
|
+
type: z
|
|
80
|
+
.enum([
|
|
81
|
+
"decision",
|
|
82
|
+
"insight",
|
|
83
|
+
"context",
|
|
84
|
+
"todo",
|
|
85
|
+
"conversation",
|
|
86
|
+
"note",
|
|
87
|
+
"procedure",
|
|
88
|
+
"all",
|
|
89
|
+
])
|
|
90
|
+
.optional()
|
|
91
|
+
.describe("Filter by memory type (default: all)"),
|
|
92
|
+
limit: z.coerce
|
|
93
|
+
.number()
|
|
94
|
+
.optional()
|
|
95
|
+
.describe("Max memories to retrieve (default: 5)"),
|
|
96
|
+
graphRecall: z
|
|
97
|
+
.boolean()
|
|
98
|
+
.optional()
|
|
99
|
+
.describe("Enable graph-aware recall with spreading activation (default: false)"),
|
|
67
100
|
}),
|
|
68
101
|
annotations: TOOL_ANNOTATIONS["recall"],
|
|
69
102
|
handler: async (args, ctx) => {
|
|
@@ -90,10 +123,27 @@ export function createMemoryTools(projectName) {
|
|
|
90
123
|
name: "list_memories",
|
|
91
124
|
description: "List recent memories or filter by type/tags. Shows what the agent has remembered.",
|
|
92
125
|
schema: z.object({
|
|
93
|
-
type: z
|
|
126
|
+
type: z
|
|
127
|
+
.enum([
|
|
128
|
+
"decision",
|
|
129
|
+
"insight",
|
|
130
|
+
"context",
|
|
131
|
+
"todo",
|
|
132
|
+
"conversation",
|
|
133
|
+
"note",
|
|
134
|
+
"all",
|
|
135
|
+
])
|
|
136
|
+
.optional()
|
|
137
|
+
.describe("Filter by type"),
|
|
94
138
|
tag: z.string().optional().describe("Filter by tag"),
|
|
95
|
-
limit: z.coerce
|
|
96
|
-
|
|
139
|
+
limit: z.coerce
|
|
140
|
+
.number()
|
|
141
|
+
.optional()
|
|
142
|
+
.describe("Max results (default: 10)"),
|
|
143
|
+
offset: z.coerce
|
|
144
|
+
.number()
|
|
145
|
+
.optional()
|
|
146
|
+
.describe("Pagination offset (default: 0)"),
|
|
97
147
|
}),
|
|
98
148
|
annotations: TOOL_ANNOTATIONS["list_memories"],
|
|
99
149
|
handler: async (args, ctx) => {
|
|
@@ -130,9 +180,25 @@ export function createMemoryTools(projectName) {
|
|
|
130
180
|
name: "forget",
|
|
131
181
|
description: "Delete a specific memory by ID or clear memories by type.",
|
|
132
182
|
schema: z.object({
|
|
133
|
-
memoryId: z
|
|
134
|
-
|
|
135
|
-
|
|
183
|
+
memoryId: z
|
|
184
|
+
.string()
|
|
185
|
+
.optional()
|
|
186
|
+
.describe("Specific memory ID to delete"),
|
|
187
|
+
type: z
|
|
188
|
+
.enum([
|
|
189
|
+
"decision",
|
|
190
|
+
"insight",
|
|
191
|
+
"context",
|
|
192
|
+
"todo",
|
|
193
|
+
"conversation",
|
|
194
|
+
"note",
|
|
195
|
+
])
|
|
196
|
+
.optional()
|
|
197
|
+
.describe("Delete all memories of this type"),
|
|
198
|
+
olderThanDays: z.coerce
|
|
199
|
+
.number()
|
|
200
|
+
.optional()
|
|
201
|
+
.describe("Delete memories older than N days"),
|
|
136
202
|
}),
|
|
137
203
|
annotations: TOOL_ANNOTATIONS["forget"],
|
|
138
204
|
handler: async (args, ctx) => {
|
|
@@ -164,7 +230,9 @@ export function createMemoryTools(projectName) {
|
|
|
164
230
|
description: "Update status of a todo/task in memory.",
|
|
165
231
|
schema: z.object({
|
|
166
232
|
todoId: z.string().describe("Todo memory ID"),
|
|
167
|
-
status: z
|
|
233
|
+
status: z
|
|
234
|
+
.enum(["pending", "in_progress", "done", "cancelled"])
|
|
235
|
+
.describe("New status"),
|
|
168
236
|
note: z.string().optional().describe("Optional note about the update"),
|
|
169
237
|
}),
|
|
170
238
|
annotations: TOOL_ANNOTATIONS["update_todo"],
|
|
@@ -191,12 +259,54 @@ export function createMemoryTools(projectName) {
|
|
|
191
259
|
name: "batch_remember",
|
|
192
260
|
description: `Efficiently store multiple memories at once in ${projectName}. Faster than individual remember calls.`,
|
|
193
261
|
schema: z.object({
|
|
194
|
-
items: z
|
|
262
|
+
items: z
|
|
263
|
+
.array(z.object({
|
|
195
264
|
content: z.string().describe("Content to remember"),
|
|
196
|
-
type: z
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
265
|
+
type: z
|
|
266
|
+
.enum([
|
|
267
|
+
"decision",
|
|
268
|
+
"insight",
|
|
269
|
+
"context",
|
|
270
|
+
"todo",
|
|
271
|
+
"conversation",
|
|
272
|
+
"note",
|
|
273
|
+
"procedure",
|
|
274
|
+
])
|
|
275
|
+
.optional()
|
|
276
|
+
.describe("Memory type (default: note)"),
|
|
277
|
+
tags: z
|
|
278
|
+
.array(z.string())
|
|
279
|
+
.optional()
|
|
280
|
+
.describe("Tags for categorization"),
|
|
281
|
+
relatedTo: z
|
|
282
|
+
.string()
|
|
283
|
+
.optional()
|
|
284
|
+
.describe("Related feature or topic"),
|
|
285
|
+
metadata: z
|
|
286
|
+
.record(z.string(), z.unknown())
|
|
287
|
+
.optional()
|
|
288
|
+
.describe("Custom metadata (factEntities, factDateTs, etc.)"),
|
|
289
|
+
factCategory: z
|
|
290
|
+
.enum([
|
|
291
|
+
"personal_info",
|
|
292
|
+
"preference",
|
|
293
|
+
"event",
|
|
294
|
+
"temporal",
|
|
295
|
+
"update",
|
|
296
|
+
"plan",
|
|
297
|
+
])
|
|
298
|
+
.optional()
|
|
299
|
+
.describe("Structured fact category for temporal retrieval"),
|
|
300
|
+
factEntities: z
|
|
301
|
+
.array(z.string())
|
|
302
|
+
.optional()
|
|
303
|
+
.describe("Named entities: file names, service names, external systems"),
|
|
304
|
+
factDateTs: z
|
|
305
|
+
.number()
|
|
306
|
+
.optional()
|
|
307
|
+
.describe("Unix timestamp (seconds) for temporal filtering"),
|
|
308
|
+
}))
|
|
309
|
+
.describe("Array of memories to store"),
|
|
200
310
|
}),
|
|
201
311
|
annotations: TOOL_ANNOTATIONS["batch_remember"],
|
|
202
312
|
handler: async (args, ctx) => {
|
|
@@ -229,7 +339,9 @@ export function createMemoryTools(projectName) {
|
|
|
229
339
|
description: `Validate or reject an auto-extracted memory in ${projectName}. Helps improve future extraction accuracy.`,
|
|
230
340
|
schema: z.object({
|
|
231
341
|
memoryId: z.string().describe("ID of the memory to validate"),
|
|
232
|
-
validated: z
|
|
342
|
+
validated: z
|
|
343
|
+
.boolean()
|
|
344
|
+
.describe("true to confirm the memory is valuable, false to reject it"),
|
|
233
345
|
}),
|
|
234
346
|
annotations: TOOL_ANNOTATIONS["validate_memory"],
|
|
235
347
|
handler: async (args, ctx) => {
|
|
@@ -250,8 +362,14 @@ export function createMemoryTools(projectName) {
|
|
|
250
362
|
name: "review_memories",
|
|
251
363
|
description: `Get auto-extracted memories pending review in ${projectName}. Shows unvalidated learnings that need human confirmation.`,
|
|
252
364
|
schema: z.object({
|
|
253
|
-
limit: z.coerce
|
|
254
|
-
|
|
365
|
+
limit: z.coerce
|
|
366
|
+
.number()
|
|
367
|
+
.optional()
|
|
368
|
+
.describe("Max memories to return (default: 20)"),
|
|
369
|
+
offset: z.coerce
|
|
370
|
+
.number()
|
|
371
|
+
.optional()
|
|
372
|
+
.describe("Pagination offset (default: 0)"),
|
|
255
373
|
}),
|
|
256
374
|
annotations: TOOL_ANNOTATIONS["review_memories"],
|
|
257
375
|
handler: async (args, ctx) => {
|
|
@@ -285,10 +403,21 @@ export function createMemoryTools(projectName) {
|
|
|
285
403
|
description: `Promote a quarantine memory to durable storage in ${projectName}. Requires a reason for promotion. Optionally runs quality gates before promotion.`,
|
|
286
404
|
schema: z.object({
|
|
287
405
|
memoryId: z.string().describe("ID of the memory to promote"),
|
|
288
|
-
reason: z
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
406
|
+
reason: z
|
|
407
|
+
.enum(["human_validated", "pr_merged", "tests_passed"])
|
|
408
|
+
.describe("Reason for promotion"),
|
|
409
|
+
evidence: z
|
|
410
|
+
.string()
|
|
411
|
+
.optional()
|
|
412
|
+
.describe("Optional evidence supporting the promotion"),
|
|
413
|
+
runGates: z
|
|
414
|
+
.boolean()
|
|
415
|
+
.optional()
|
|
416
|
+
.describe("Run quality gates before promotion (default: false)"),
|
|
417
|
+
affectedFiles: z
|
|
418
|
+
.array(z.string())
|
|
419
|
+
.optional()
|
|
420
|
+
.describe("Files affected by this memory (for quality gate checking)"),
|
|
292
421
|
}),
|
|
293
422
|
annotations: TOOL_ANNOTATIONS["promote_memory"],
|
|
294
423
|
handler: async (args, ctx) => {
|
|
@@ -320,8 +449,14 @@ export function createMemoryTools(projectName) {
|
|
|
320
449
|
name: "run_quality_gates",
|
|
321
450
|
description: `Run quality gates (typecheck, tests, blast radius) for ${projectName}.`,
|
|
322
451
|
schema: z.object({
|
|
323
|
-
affectedFiles: z
|
|
324
|
-
|
|
452
|
+
affectedFiles: z
|
|
453
|
+
.array(z.string())
|
|
454
|
+
.optional()
|
|
455
|
+
.describe("Files to check (for related tests and blast radius)"),
|
|
456
|
+
skipGates: z
|
|
457
|
+
.array(z.string())
|
|
458
|
+
.optional()
|
|
459
|
+
.describe("Gates to skip (typecheck, test, blast_radius)"),
|
|
325
460
|
}),
|
|
326
461
|
annotations: TOOL_ANNOTATIONS["run_quality_gates"],
|
|
327
462
|
handler: async (args, ctx) => {
|
|
@@ -359,12 +494,27 @@ export function createMemoryTools(projectName) {
|
|
|
359
494
|
name: "memory_maintenance",
|
|
360
495
|
description: `Run memory maintenance for ${projectName}: quarantine cleanup (expire old auto-memories), feedback-driven promote/prune, and compaction (merge similar durable memories).`,
|
|
361
496
|
schema: z.object({
|
|
362
|
-
operations: z
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
497
|
+
operations: z
|
|
498
|
+
.object({
|
|
499
|
+
quarantine_cleanup: z
|
|
500
|
+
.boolean()
|
|
501
|
+
.optional()
|
|
502
|
+
.describe("Remove expired quarantine memories (default: true)"),
|
|
503
|
+
feedback_maintenance: z
|
|
504
|
+
.boolean()
|
|
505
|
+
.optional()
|
|
506
|
+
.describe("Auto-promote/prune by feedback (default: true)"),
|
|
507
|
+
compaction: z
|
|
508
|
+
.boolean()
|
|
509
|
+
.optional()
|
|
510
|
+
.describe("Merge similar durable memories (default: false)"),
|
|
511
|
+
compaction_dry_run: z
|
|
512
|
+
.boolean()
|
|
513
|
+
.optional()
|
|
514
|
+
.describe("Preview compaction without changes (default: true)"),
|
|
515
|
+
})
|
|
516
|
+
.optional()
|
|
517
|
+
.describe("Which operations to run (default: quarantine_cleanup + feedback_maintenance)"),
|
|
368
518
|
}),
|
|
369
519
|
annotations: TOOL_ANNOTATIONS["memory_maintenance"],
|
|
370
520
|
handler: async (args, ctx) => {
|
|
@@ -381,7 +531,9 @@ export function createMemoryTools(projectName) {
|
|
|
381
531
|
result += `## Quarantine Cleanup\n`;
|
|
382
532
|
if (qc.rejected.length > 0) {
|
|
383
533
|
result += `**Expired** (${qc.rejected.length}): removed from quarantine\n`;
|
|
384
|
-
qc.rejected.slice(0, 10).forEach((id) => {
|
|
534
|
+
qc.rejected.slice(0, 10).forEach((id) => {
|
|
535
|
+
result += ` \u{1F5D1}\u{FE0F} ${id}\n`;
|
|
536
|
+
});
|
|
385
537
|
if (qc.rejected.length > 10)
|
|
386
538
|
result += ` ... and ${qc.rejected.length - 10} more\n`;
|
|
387
539
|
}
|
|
@@ -389,7 +541,9 @@ export function createMemoryTools(projectName) {
|
|
|
389
541
|
result += `No expired quarantine memories.\n`;
|
|
390
542
|
}
|
|
391
543
|
if (qc.errors.length > 0) {
|
|
392
|
-
qc.errors.forEach((e) => {
|
|
544
|
+
qc.errors.forEach((e) => {
|
|
545
|
+
result += ` \u26A0\u{FE0F} ${e}\n`;
|
|
546
|
+
});
|
|
393
547
|
}
|
|
394
548
|
result += `\n`;
|
|
395
549
|
}
|
|
@@ -399,24 +553,30 @@ export function createMemoryTools(projectName) {
|
|
|
399
553
|
result += `## Feedback Maintenance\n`;
|
|
400
554
|
if (fm.promoted.length > 0) {
|
|
401
555
|
result += `**Promoted** (${fm.promoted.length}): moved to durable\n`;
|
|
402
|
-
fm.promoted.forEach((id) => {
|
|
556
|
+
fm.promoted.forEach((id) => {
|
|
557
|
+
result += ` \u2705 ${id}\n`;
|
|
558
|
+
});
|
|
403
559
|
}
|
|
404
560
|
if (fm.pruned.length > 0) {
|
|
405
561
|
result += `**Pruned** (${fm.pruned.length}): removed\n`;
|
|
406
|
-
fm.pruned.forEach((id) => {
|
|
562
|
+
fm.pruned.forEach((id) => {
|
|
563
|
+
result += ` \u{1F5D1}\u{FE0F} ${id}\n`;
|
|
564
|
+
});
|
|
407
565
|
}
|
|
408
566
|
if (fm.promoted.length === 0 && fm.pruned.length === 0) {
|
|
409
567
|
result += `No feedback-based actions needed.\n`;
|
|
410
568
|
}
|
|
411
569
|
if (fm.errors.length > 0) {
|
|
412
|
-
fm.errors.forEach((e) => {
|
|
570
|
+
fm.errors.forEach((e) => {
|
|
571
|
+
result += ` \u26A0\u{FE0F} ${e}\n`;
|
|
572
|
+
});
|
|
413
573
|
}
|
|
414
574
|
result += `\n`;
|
|
415
575
|
}
|
|
416
576
|
// Compaction section
|
|
417
577
|
if (data.compaction) {
|
|
418
578
|
const cp = data.compaction;
|
|
419
|
-
result += `## Compaction${cp.dryRun ?
|
|
579
|
+
result += `## Compaction${cp.dryRun ? " (dry run)" : ""}\n`;
|
|
420
580
|
if (cp.clusters.length > 0) {
|
|
421
581
|
result += `**${cp.totalClusters} cluster(s)** of similar memories found\n\n`;
|
|
422
582
|
cp.clusters.slice(0, 5).forEach((c, i) => {
|
package/dist/tools/pm.js
CHANGED
|
@@ -14,8 +14,13 @@ export function createPmTools(projectName) {
|
|
|
14
14
|
name: "search_requirements",
|
|
15
15
|
description: `Search technical requirements and product documentation for ${projectName}. Finds relevant requirements, user stories, and specifications from Confluence.`,
|
|
16
16
|
schema: z.object({
|
|
17
|
-
query: z
|
|
18
|
-
|
|
17
|
+
query: z
|
|
18
|
+
.string()
|
|
19
|
+
.describe("Search query for requirements (e.g., 'video inspection flow', 'payment integration')"),
|
|
20
|
+
limit: z.coerce
|
|
21
|
+
.number()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Max results (default: 5)"),
|
|
19
24
|
}),
|
|
20
25
|
annotations: TOOL_ANNOTATIONS["search_requirements"],
|
|
21
26
|
handler: async (args, ctx) => {
|
|
@@ -42,8 +47,13 @@ export function createPmTools(projectName) {
|
|
|
42
47
|
name: "analyze_requirements",
|
|
43
48
|
description: `Analyze technical requirements and compare with existing implementation in ${projectName}. Identifies gaps, missing features, and implementation status.`,
|
|
44
49
|
schema: z.object({
|
|
45
|
-
feature: z
|
|
46
|
-
|
|
50
|
+
feature: z
|
|
51
|
+
.string()
|
|
52
|
+
.describe("Feature or requirement to analyze (e.g., 'video inspection', 'notifications')"),
|
|
53
|
+
detailed: z
|
|
54
|
+
.boolean()
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("Include detailed code references (default: false)"),
|
|
47
57
|
}),
|
|
48
58
|
annotations: TOOL_ANNOTATIONS["analyze_requirements"],
|
|
49
59
|
handler: async (args, ctx) => {
|
|
@@ -107,7 +117,10 @@ export function createPmTools(projectName) {
|
|
|
107
117
|
description: `Estimate development effort for a feature based on requirements and codebase analysis. Returns complexity assessment, affected files, and risk factors.`,
|
|
108
118
|
schema: z.object({
|
|
109
119
|
feature: z.string().describe("Feature description to estimate"),
|
|
110
|
-
includeSubtasks: z
|
|
120
|
+
includeSubtasks: z
|
|
121
|
+
.boolean()
|
|
122
|
+
.optional()
|
|
123
|
+
.describe("Break down into subtasks (default: true)"),
|
|
111
124
|
}),
|
|
112
125
|
annotations: TOOL_ANNOTATIONS["estimate_feature"],
|
|
113
126
|
handler: async (args, ctx) => {
|
|
@@ -235,13 +248,22 @@ export function createPmTools(projectName) {
|
|
|
235
248
|
name: "list_requirements",
|
|
236
249
|
description: `List all documented requirements/features for ${projectName} from Confluence. Groups by category or status.`,
|
|
237
250
|
schema: z.object({
|
|
238
|
-
category: z
|
|
239
|
-
|
|
240
|
-
|
|
251
|
+
category: z
|
|
252
|
+
.string()
|
|
253
|
+
.optional()
|
|
254
|
+
.describe("Filter by category (optional)"),
|
|
255
|
+
limit: z.coerce
|
|
256
|
+
.number()
|
|
257
|
+
.optional()
|
|
258
|
+
.describe("Max results (default: 20)"),
|
|
259
|
+
offset: z.coerce
|
|
260
|
+
.number()
|
|
261
|
+
.optional()
|
|
262
|
+
.describe("Pagination offset (default: 0)"),
|
|
241
263
|
}),
|
|
242
264
|
annotations: TOOL_ANNOTATIONS["list_requirements"],
|
|
243
265
|
handler: async (args, ctx) => {
|
|
244
|
-
const { category, limit = 20, offset = 0 } = args;
|
|
266
|
+
const { category, limit = 20, offset = 0, } = args;
|
|
245
267
|
const query = category || "requirements features specifications";
|
|
246
268
|
const response = await ctx.api.post("/api/search", {
|
|
247
269
|
collection: `${ctx.collectionPrefix}confluence`,
|
|
@@ -274,7 +296,9 @@ export function createPmTools(projectName) {
|
|
|
274
296
|
name: "ask_pm",
|
|
275
297
|
description: `Ask product management questions about ${projectName}. Answers questions about requirements, features, priorities, and project status using both documentation and codebase.`,
|
|
276
298
|
schema: z.object({
|
|
277
|
-
question: z
|
|
299
|
+
question: z
|
|
300
|
+
.string()
|
|
301
|
+
.describe("PM question (e.g., 'What features are planned for video inspection?', 'What\\'s the status of notifications?')"),
|
|
278
302
|
}),
|
|
279
303
|
annotations: TOOL_ANNOTATIONS["ask_pm"],
|
|
280
304
|
handler: async (args, ctx) => {
|
|
@@ -335,7 +359,10 @@ export function createPmTools(projectName) {
|
|
|
335
359
|
description: `Generate technical specification from requirements. Creates a structured spec document based on Confluence requirements and existing codebase patterns.`,
|
|
336
360
|
schema: z.object({
|
|
337
361
|
feature: z.string().describe("Feature to generate spec for"),
|
|
338
|
-
format: z
|
|
362
|
+
format: z
|
|
363
|
+
.enum(["markdown", "jira", "brief"])
|
|
364
|
+
.optional()
|
|
365
|
+
.describe("Output format (default: markdown)"),
|
|
339
366
|
}),
|
|
340
367
|
annotations: TOOL_ANNOTATIONS["generate_spec"],
|
|
341
368
|
handler: async (args, ctx) => {
|
package/dist/tools/quality.js
CHANGED
|
@@ -12,7 +12,10 @@ export function createQualityTools(projectName) {
|
|
|
12
12
|
name: "get_quality_report",
|
|
13
13
|
description: `Get LLM quality metrics for ${projectName}. Shows JSON parse rates, latency percentiles, thinking trace rates, and alerts.`,
|
|
14
14
|
schema: z.object({
|
|
15
|
-
endpoint: z
|
|
15
|
+
endpoint: z
|
|
16
|
+
.string()
|
|
17
|
+
.optional()
|
|
18
|
+
.describe("Filter by specific endpoint (e.g., '/api/ask')"),
|
|
16
19
|
}),
|
|
17
20
|
annotations: TOOL_ANNOTATIONS["get_quality_report"] || {
|
|
18
21
|
title: "Get Quality Report",
|
|
@@ -20,7 +23,9 @@ export function createQualityTools(projectName) {
|
|
|
20
23
|
openWorldHint: false,
|
|
21
24
|
},
|
|
22
25
|
handler: async (args, ctx) => {
|
|
23
|
-
const params = args.endpoint
|
|
26
|
+
const params = args.endpoint
|
|
27
|
+
? `?endpoint=${encodeURIComponent(args.endpoint)}`
|
|
28
|
+
: "";
|
|
24
29
|
const response = await ctx.api.get(`/api/quality/report${params}`);
|
|
25
30
|
const data = response.data;
|
|
26
31
|
let result = `## Quality Report\n\n`;
|
package/dist/tools/review.js
CHANGED
|
@@ -14,12 +14,18 @@ export function createReviewTools(projectName) {
|
|
|
14
14
|
schema: z.object({
|
|
15
15
|
code: z.string().describe("Code to review"),
|
|
16
16
|
filePath: z.string().optional().describe("File path for context"),
|
|
17
|
-
reviewType: z
|
|
18
|
-
|
|
17
|
+
reviewType: z
|
|
18
|
+
.enum(["security", "performance", "patterns", "style", "general"])
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Type of review focus (default: general)"),
|
|
21
|
+
diff: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("Git diff to review instead of full code"),
|
|
19
25
|
}),
|
|
20
26
|
annotations: TOOL_ANNOTATIONS["review_code"],
|
|
21
27
|
handler: async (args, ctx) => {
|
|
22
|
-
const { code, filePath, reviewType = "general", diff } = args;
|
|
28
|
+
const { code, filePath, reviewType = "general", diff, } = args;
|
|
23
29
|
const response = await ctx.api.post("/api/review", {
|
|
24
30
|
code: code || diff,
|
|
25
31
|
filePath,
|
|
@@ -76,9 +82,18 @@ export function createReviewTools(projectName) {
|
|
|
76
82
|
schema: z.object({
|
|
77
83
|
code: z.string().describe("Code to generate tests for"),
|
|
78
84
|
filePath: z.string().optional().describe("File path for context"),
|
|
79
|
-
framework: z
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
framework: z
|
|
86
|
+
.enum(["jest", "vitest", "pytest", "mocha"])
|
|
87
|
+
.optional()
|
|
88
|
+
.describe("Test framework to use (default: jest)"),
|
|
89
|
+
testType: z
|
|
90
|
+
.enum(["unit", "integration", "e2e"])
|
|
91
|
+
.optional()
|
|
92
|
+
.describe("Type of tests to generate (default: unit)"),
|
|
93
|
+
coverage: z
|
|
94
|
+
.enum(["minimal", "standard", "comprehensive"])
|
|
95
|
+
.optional()
|
|
96
|
+
.describe("Coverage level (default: comprehensive)"),
|
|
82
97
|
}),
|
|
83
98
|
annotations: TOOL_ANNOTATIONS["generate_tests"],
|
|
84
99
|
handler: async (args, ctx) => {
|
|
@@ -115,7 +130,10 @@ export function createReviewTools(projectName) {
|
|
|
115
130
|
description: "Analyze existing tests for coverage and quality.",
|
|
116
131
|
schema: z.object({
|
|
117
132
|
testCode: z.string().describe("Test code to analyze"),
|
|
118
|
-
sourceCode: z
|
|
133
|
+
sourceCode: z
|
|
134
|
+
.string()
|
|
135
|
+
.optional()
|
|
136
|
+
.describe("Optional source code being tested"),
|
|
119
137
|
}),
|
|
120
138
|
annotations: TOOL_ANNOTATIONS["analyze_tests"],
|
|
121
139
|
handler: async (args, ctx) => {
|