@vheins/local-memory-mcp 0.8.45 → 0.8.47
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/{chunk-Z4FZBRE2.js → chunk-MPT4WE42.js} +1824 -1777
- package/dist/dashboard/public/assets/{index-DSdSQ0sh.css → index-BaWIMG1g.css} +1 -1
- package/dist/dashboard/public/assets/{index-BESxlve8.js → index-DEY6a44I.js} +2 -2
- package/dist/dashboard/public/index.html +2 -2
- package/dist/dashboard/server.js +1 -1
- package/dist/mcp/server.js +44 -3
- package/dist/prompts/create-task.md +1 -1
- package/dist/prompts/csl-scrapper.md +6 -15
- package/dist/prompts/memory-agent-core.md +2 -2
- package/dist/prompts/memory-index-policy.md +3 -2
- package/dist/prompts/project-briefing.md +1 -1
- package/dist/prompts/review-and-audit.md +2 -2
- package/dist/prompts/session-planner.md +1 -1
- package/dist/prompts/task-management-guidelines.md +3 -2
- package/dist/prompts/task-memory-executor.md +3 -2
- package/dist/prompts/tool-usage-guidelines.md +4 -1
- package/package.json +1 -1
|
@@ -1,3 +1,49 @@
|
|
|
1
|
+
// src/mcp/capabilities.ts
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
var pkgVersion = "0.1.0";
|
|
6
|
+
if ("0.8.47") {
|
|
7
|
+
pkgVersion = "0.8.47";
|
|
8
|
+
} else {
|
|
9
|
+
let searchDir = __dirname;
|
|
10
|
+
for (let i = 0; i < 5; i++) {
|
|
11
|
+
const candidate = path.join(searchDir, "package.json");
|
|
12
|
+
try {
|
|
13
|
+
if (fs.existsSync(candidate)) {
|
|
14
|
+
const pkg = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
15
|
+
if (pkg.name === "@vheins/local-memory-mcp" && pkg.version) {
|
|
16
|
+
pkgVersion = pkg.version;
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
searchDir = path.dirname(searchDir);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
var MCP_PROTOCOL_VERSION = "2025-03-26";
|
|
26
|
+
var CAPABILITIES = {
|
|
27
|
+
serverInfo: {
|
|
28
|
+
name: "mcp-memory-local",
|
|
29
|
+
version: pkgVersion
|
|
30
|
+
},
|
|
31
|
+
capabilities: {
|
|
32
|
+
completions: {},
|
|
33
|
+
logging: {},
|
|
34
|
+
resources: {
|
|
35
|
+
subscribe: true,
|
|
36
|
+
listChanged: true
|
|
37
|
+
},
|
|
38
|
+
tools: {
|
|
39
|
+
listChanged: false
|
|
40
|
+
},
|
|
41
|
+
prompts: {
|
|
42
|
+
listChanged: true
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
1
47
|
// src/mcp/utils/logger.ts
|
|
2
48
|
import fs from "fs";
|
|
3
49
|
var LEVELS = {
|
|
@@ -139,108 +185,6 @@ function createFileSink(logDir, maxFiles = 5) {
|
|
|
139
185
|
};
|
|
140
186
|
}
|
|
141
187
|
|
|
142
|
-
// src/mcp/session.ts
|
|
143
|
-
import path from "path";
|
|
144
|
-
import { fileURLToPath } from "url";
|
|
145
|
-
function createSessionContext() {
|
|
146
|
-
return {
|
|
147
|
-
roots: [],
|
|
148
|
-
supportsRoots: false,
|
|
149
|
-
supportsSampling: false,
|
|
150
|
-
supportsSamplingTools: false,
|
|
151
|
-
supportsElicitation: false,
|
|
152
|
-
supportsElicitationForm: false,
|
|
153
|
-
supportsElicitationUrl: false
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
function updateSessionFromInitialize(session, params) {
|
|
157
|
-
const capabilities = params?.capabilities || {};
|
|
158
|
-
session.clientInfo = params?.clientInfo;
|
|
159
|
-
session.clientCapabilities = capabilities;
|
|
160
|
-
session.supportsRoots = Boolean(capabilities.roots);
|
|
161
|
-
session.supportsSampling = Boolean(capabilities.sampling);
|
|
162
|
-
const sampling = capabilities.sampling;
|
|
163
|
-
session.supportsSamplingTools = Boolean(sampling?.tools);
|
|
164
|
-
session.supportsElicitation = Boolean(capabilities.elicitation);
|
|
165
|
-
session.supportsElicitationForm = supportsElicitationMode(capabilities.elicitation, "form");
|
|
166
|
-
session.supportsElicitationUrl = supportsElicitationMode(capabilities.elicitation, "url");
|
|
167
|
-
}
|
|
168
|
-
function supportsElicitationMode(capability, mode) {
|
|
169
|
-
if (!capability || typeof capability !== "object") {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
const cap = capability;
|
|
173
|
-
if (mode === "form") {
|
|
174
|
-
return Object.keys(cap).length === 0 || typeof cap.form === "object";
|
|
175
|
-
}
|
|
176
|
-
return typeof cap.url === "object";
|
|
177
|
-
}
|
|
178
|
-
function updateSessionRoots(session, roots) {
|
|
179
|
-
const normalized = normalizeRoots(roots);
|
|
180
|
-
const previous = JSON.stringify(session.roots);
|
|
181
|
-
const next = JSON.stringify(normalized);
|
|
182
|
-
session.roots = normalized;
|
|
183
|
-
return previous !== next;
|
|
184
|
-
}
|
|
185
|
-
function normalizeRoots(roots) {
|
|
186
|
-
if (!Array.isArray(roots)) return [];
|
|
187
|
-
const seen = /* @__PURE__ */ new Set();
|
|
188
|
-
const normalized = [];
|
|
189
|
-
for (const root of roots) {
|
|
190
|
-
if (!root || typeof root !== "object") continue;
|
|
191
|
-
const r = root;
|
|
192
|
-
const uri = typeof r.uri === "string" ? r.uri : void 0;
|
|
193
|
-
const name = typeof r.name === "string" ? r.name : void 0;
|
|
194
|
-
if (!uri || seen.has(uri)) continue;
|
|
195
|
-
seen.add(uri);
|
|
196
|
-
normalized.push({ uri, name });
|
|
197
|
-
}
|
|
198
|
-
return normalized;
|
|
199
|
-
}
|
|
200
|
-
function extractRootsFromResult(result) {
|
|
201
|
-
return normalizeRoots(result?.roots);
|
|
202
|
-
}
|
|
203
|
-
function getFilesystemRoots(session) {
|
|
204
|
-
if (!session) return [];
|
|
205
|
-
const resolved = [];
|
|
206
|
-
for (const root of session.roots) {
|
|
207
|
-
if (!root.uri.startsWith("file://")) continue;
|
|
208
|
-
try {
|
|
209
|
-
resolved.push(path.resolve(fileURLToPath(root.uri)));
|
|
210
|
-
} catch {
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return resolved;
|
|
214
|
-
}
|
|
215
|
-
function isPathWithinRoots(targetPath, session) {
|
|
216
|
-
const roots = getFilesystemRoots(session);
|
|
217
|
-
if (roots.length === 0) return true;
|
|
218
|
-
const normalizedTarget = path.resolve(targetPath);
|
|
219
|
-
return roots.some((rootPath) => {
|
|
220
|
-
const relative = path.relative(rootPath, normalizedTarget);
|
|
221
|
-
return relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
function findContainingRoot(targetPath, session) {
|
|
225
|
-
const roots = getFilesystemRoots(session);
|
|
226
|
-
if (roots.length === 0) return null;
|
|
227
|
-
const normalizedTarget = path.resolve(targetPath);
|
|
228
|
-
for (const rootPath of roots) {
|
|
229
|
-
const relative = path.relative(rootPath, normalizedTarget);
|
|
230
|
-
if (relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative)) {
|
|
231
|
-
return rootPath;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return null;
|
|
235
|
-
}
|
|
236
|
-
function inferRepoFromSession(session) {
|
|
237
|
-
const roots = getFilesystemRoots(session);
|
|
238
|
-
if (roots.length === 1) {
|
|
239
|
-
return path.basename(roots[0]);
|
|
240
|
-
}
|
|
241
|
-
return void 0;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
188
|
// src/mcp/storage/sqlite.ts
|
|
245
189
|
import Database from "better-sqlite3";
|
|
246
190
|
import path3 from "path";
|
|
@@ -2343,6 +2287,13 @@ var HandoffEntity = class extends BaseEntity {
|
|
|
2343
2287
|
]);
|
|
2344
2288
|
return result.changes > 0;
|
|
2345
2289
|
}
|
|
2290
|
+
updatePendingHandoffsForTask(task_id, status) {
|
|
2291
|
+
const result = this.run(
|
|
2292
|
+
"UPDATE handoffs SET status = ?, updated_at = ? WHERE task_id = ? AND status = 'pending'",
|
|
2293
|
+
[status, (/* @__PURE__ */ new Date()).toISOString(), task_id]
|
|
2294
|
+
);
|
|
2295
|
+
return result.changes;
|
|
2296
|
+
}
|
|
2346
2297
|
claimTask(params) {
|
|
2347
2298
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2348
2299
|
const id = randomUUID();
|
|
@@ -2383,6 +2334,13 @@ var HandoffEntity = class extends BaseEntity {
|
|
|
2383
2334
|
const result = this.run(sql, params);
|
|
2384
2335
|
return result.changes > 0;
|
|
2385
2336
|
}
|
|
2337
|
+
releaseClaimsForTask(task_id) {
|
|
2338
|
+
const result = this.run("UPDATE claims SET released_at = ? WHERE task_id = ? AND released_at IS NULL", [
|
|
2339
|
+
(/* @__PURE__ */ new Date()).toISOString(),
|
|
2340
|
+
task_id
|
|
2341
|
+
]);
|
|
2342
|
+
return result.changes;
|
|
2343
|
+
}
|
|
2386
2344
|
listClaims(params) {
|
|
2387
2345
|
const conditions = ["repo = ?"];
|
|
2388
2346
|
const values = [params.repo];
|
|
@@ -2619,1124 +2577,1011 @@ var SQLiteStore = class _SQLiteStore {
|
|
|
2619
2577
|
}
|
|
2620
2578
|
};
|
|
2621
2579
|
|
|
2622
|
-
// src/mcp/
|
|
2623
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2580
|
+
// src/mcp/session.ts
|
|
2624
2581
|
import path4 from "path";
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2582
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2583
|
+
function createSessionContext() {
|
|
2584
|
+
return {
|
|
2585
|
+
roots: [],
|
|
2586
|
+
supportsRoots: false,
|
|
2587
|
+
supportsSampling: false,
|
|
2588
|
+
supportsSamplingTools: false,
|
|
2589
|
+
supportsElicitation: false,
|
|
2590
|
+
supportsElicitationForm: false,
|
|
2591
|
+
supportsElicitationUrl: false
|
|
2592
|
+
};
|
|
2593
|
+
}
|
|
2594
|
+
function updateSessionFromInitialize(session, params) {
|
|
2595
|
+
const capabilities = params?.capabilities || {};
|
|
2596
|
+
session.clientInfo = params?.clientInfo;
|
|
2597
|
+
session.clientCapabilities = capabilities;
|
|
2598
|
+
session.supportsRoots = Boolean(capabilities.roots);
|
|
2599
|
+
session.supportsSampling = Boolean(capabilities.sampling);
|
|
2600
|
+
const sampling = capabilities.sampling;
|
|
2601
|
+
session.supportsSamplingTools = Boolean(sampling?.tools);
|
|
2602
|
+
session.supportsElicitation = Boolean(capabilities.elicitation);
|
|
2603
|
+
session.supportsElicitationForm = supportsElicitationMode(capabilities.elicitation, "form");
|
|
2604
|
+
session.supportsElicitationUrl = supportsElicitationMode(capabilities.elicitation, "url");
|
|
2605
|
+
}
|
|
2606
|
+
function supportsElicitationMode(capability, mode) {
|
|
2607
|
+
if (!capability || typeof capability !== "object") {
|
|
2608
|
+
return false;
|
|
2609
|
+
}
|
|
2610
|
+
const cap = capability;
|
|
2611
|
+
if (mode === "form") {
|
|
2612
|
+
return Object.keys(cap).length === 0 || typeof cap.form === "object";
|
|
2613
|
+
}
|
|
2614
|
+
return typeof cap.url === "object";
|
|
2615
|
+
}
|
|
2616
|
+
function updateSessionRoots(session, roots) {
|
|
2617
|
+
const normalized = normalizeRoots(roots);
|
|
2618
|
+
const previous = JSON.stringify(session.roots);
|
|
2619
|
+
const next = JSON.stringify(normalized);
|
|
2620
|
+
session.roots = normalized;
|
|
2621
|
+
return previous !== next;
|
|
2622
|
+
}
|
|
2623
|
+
function normalizeRoots(roots) {
|
|
2624
|
+
if (!Array.isArray(roots)) return [];
|
|
2625
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2626
|
+
const normalized = [];
|
|
2627
|
+
for (const root of roots) {
|
|
2628
|
+
if (!root || typeof root !== "object") continue;
|
|
2629
|
+
const r = root;
|
|
2630
|
+
const uri = typeof r.uri === "string" ? r.uri : void 0;
|
|
2631
|
+
const name = typeof r.name === "string" ? r.name : void 0;
|
|
2632
|
+
if (!uri || seen.has(uri)) continue;
|
|
2633
|
+
seen.add(uri);
|
|
2634
|
+
normalized.push({ uri, name });
|
|
2635
|
+
}
|
|
2636
|
+
return normalized;
|
|
2637
|
+
}
|
|
2638
|
+
function extractRootsFromResult(result) {
|
|
2639
|
+
return normalizeRoots(result?.roots);
|
|
2640
|
+
}
|
|
2641
|
+
function getFilesystemRoots(session) {
|
|
2642
|
+
if (!session) return [];
|
|
2643
|
+
const resolved = [];
|
|
2644
|
+
for (const root of session.roots) {
|
|
2645
|
+
if (!root.uri.startsWith("file://")) continue;
|
|
2633
2646
|
try {
|
|
2634
|
-
|
|
2635
|
-
const pkg = JSON.parse(fs.readFileSync(candidate, "utf8"));
|
|
2636
|
-
if (pkg.name === "@vheins/local-memory-mcp" && pkg.version) {
|
|
2637
|
-
pkgVersion = pkg.version;
|
|
2638
|
-
break;
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2647
|
+
resolved.push(path4.resolve(fileURLToPath2(root.uri)));
|
|
2641
2648
|
} catch {
|
|
2642
2649
|
}
|
|
2643
|
-
searchDir = path4.dirname(searchDir);
|
|
2644
2650
|
}
|
|
2651
|
+
return resolved;
|
|
2645
2652
|
}
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
listChanged: true
|
|
2653
|
+
function isPathWithinRoots(targetPath, session) {
|
|
2654
|
+
const roots = getFilesystemRoots(session);
|
|
2655
|
+
if (roots.length === 0) return true;
|
|
2656
|
+
const normalizedTarget = path4.resolve(targetPath);
|
|
2657
|
+
return roots.some((rootPath) => {
|
|
2658
|
+
const relative = path4.relative(rootPath, normalizedTarget);
|
|
2659
|
+
return relative === "" || !relative.startsWith("..") && !path4.isAbsolute(relative);
|
|
2660
|
+
});
|
|
2661
|
+
}
|
|
2662
|
+
function findContainingRoot(targetPath, session) {
|
|
2663
|
+
const roots = getFilesystemRoots(session);
|
|
2664
|
+
if (roots.length === 0) return null;
|
|
2665
|
+
const normalizedTarget = path4.resolve(targetPath);
|
|
2666
|
+
for (const rootPath of roots) {
|
|
2667
|
+
const relative = path4.relative(rootPath, normalizedTarget);
|
|
2668
|
+
if (relative === "" || !relative.startsWith("..") && !path4.isAbsolute(relative)) {
|
|
2669
|
+
return rootPath;
|
|
2664
2670
|
}
|
|
2665
2671
|
}
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
// src/mcp/utils/pagination.ts
|
|
2669
|
-
function encodeCursor(offset) {
|
|
2670
|
-
return Buffer.from(String(offset), "utf8").toString("base64");
|
|
2671
|
-
}
|
|
2672
|
-
function decodeCursor(cursor) {
|
|
2673
|
-
if (cursor === void 0 || cursor === null || cursor === "") {
|
|
2674
|
-
return 0;
|
|
2675
|
-
}
|
|
2676
|
-
if (typeof cursor !== "string" || cursor.trim() === "") {
|
|
2677
|
-
throw invalidPaginationParams("Invalid cursor");
|
|
2678
|
-
}
|
|
2679
|
-
let decoded;
|
|
2680
|
-
try {
|
|
2681
|
-
decoded = Buffer.from(cursor, "base64").toString("utf8");
|
|
2682
|
-
} catch {
|
|
2683
|
-
throw invalidPaginationParams("Invalid cursor");
|
|
2684
|
-
}
|
|
2685
|
-
if (!/^\d+$/.test(decoded)) {
|
|
2686
|
-
throw invalidPaginationParams("Invalid cursor");
|
|
2687
|
-
}
|
|
2688
|
-
const offset = Number.parseInt(decoded, 10);
|
|
2689
|
-
if (!Number.isFinite(offset) || offset < 0) {
|
|
2690
|
-
throw invalidPaginationParams("Invalid cursor");
|
|
2691
|
-
}
|
|
2692
|
-
return offset;
|
|
2693
|
-
}
|
|
2694
|
-
function invalidPaginationParams(message) {
|
|
2695
|
-
const error = new Error(message);
|
|
2696
|
-
error.code = -32602;
|
|
2697
|
-
return error;
|
|
2672
|
+
return null;
|
|
2698
2673
|
}
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
const unique = [...new Set(candidates.filter(Boolean))];
|
|
2704
|
-
const needle = input.trim().toLowerCase();
|
|
2705
|
-
if (!needle) {
|
|
2706
|
-
return unique.slice(0, MAX_COMPLETION_VALUES);
|
|
2674
|
+
function inferRepoFromSession(session) {
|
|
2675
|
+
const roots = getFilesystemRoots(session);
|
|
2676
|
+
if (roots.length === 1) {
|
|
2677
|
+
return path4.basename(roots[0]);
|
|
2707
2678
|
}
|
|
2708
|
-
return
|
|
2709
|
-
}
|
|
2710
|
-
function scoreCompletionValue(value, needle) {
|
|
2711
|
-
const haystack = value.toLowerCase();
|
|
2712
|
-
if (haystack === needle) return 100;
|
|
2713
|
-
if (haystack.startsWith(needle)) return 75;
|
|
2714
|
-
if (haystack.includes(needle)) return 50;
|
|
2715
|
-
const compactNeedle = needle.replace(/[\s_-]+/g, "");
|
|
2716
|
-
const compactHaystack = haystack.replace(/[\s_-]+/g, "");
|
|
2717
|
-
if (compactNeedle && compactHaystack.includes(compactNeedle)) return 25;
|
|
2718
|
-
return 0;
|
|
2679
|
+
return void 0;
|
|
2719
2680
|
}
|
|
2720
2681
|
|
|
2721
|
-
// src/mcp/
|
|
2722
|
-
|
|
2723
|
-
var
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2682
|
+
// src/mcp/tools/schemas.ts
|
|
2683
|
+
import { z } from "zod";
|
|
2684
|
+
var MemoryScopeSchema = z.object({
|
|
2685
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2686
|
+
branch: z.string().optional(),
|
|
2687
|
+
folder: z.string().optional(),
|
|
2688
|
+
language: z.string().optional()
|
|
2689
|
+
});
|
|
2690
|
+
var MemoryTypeSchema = z.enum([
|
|
2691
|
+
"code_fact",
|
|
2692
|
+
"decision",
|
|
2693
|
+
"mistake",
|
|
2694
|
+
"pattern",
|
|
2695
|
+
"task_archive"
|
|
2696
|
+
]);
|
|
2697
|
+
var MemoryStoreSchema = z.object({
|
|
2698
|
+
code: z.string().max(20).optional(),
|
|
2699
|
+
type: MemoryTypeSchema,
|
|
2700
|
+
title: z.string().min(3).max(255),
|
|
2701
|
+
content: z.string().min(10),
|
|
2702
|
+
importance: z.number().min(1).max(5),
|
|
2703
|
+
agent: z.string().min(1),
|
|
2704
|
+
role: z.string().optional().default("unknown"),
|
|
2705
|
+
model: z.string().min(1),
|
|
2706
|
+
scope: MemoryScopeSchema,
|
|
2707
|
+
ttlDays: z.number().min(1).optional(),
|
|
2708
|
+
supersedes: z.string().uuid().optional(),
|
|
2709
|
+
tags: z.array(z.string()).optional(),
|
|
2710
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
2711
|
+
is_global: z.boolean().default(false),
|
|
2712
|
+
structured: z.boolean().default(false)
|
|
2713
|
+
});
|
|
2714
|
+
var MemoryUpdateSchema = z.object({
|
|
2715
|
+
id: z.string().uuid(),
|
|
2716
|
+
type: MemoryTypeSchema.optional(),
|
|
2717
|
+
title: z.string().min(3).max(255).optional(),
|
|
2718
|
+
content: z.string().min(10).optional(),
|
|
2719
|
+
importance: z.number().min(1).max(5).optional(),
|
|
2720
|
+
agent: z.string().optional(),
|
|
2721
|
+
role: z.string().optional(),
|
|
2722
|
+
status: z.enum(["active", "archived"]).optional(),
|
|
2723
|
+
supersedes: z.string().uuid().optional(),
|
|
2724
|
+
tags: z.array(z.string()).optional(),
|
|
2725
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
2726
|
+
is_global: z.boolean().optional(),
|
|
2727
|
+
completed_at: z.string().optional(),
|
|
2728
|
+
structured: z.boolean().default(false)
|
|
2729
|
+
}).refine(
|
|
2730
|
+
(data) => data.type !== void 0 || data.content !== void 0 || data.title !== void 0 || data.importance !== void 0 || data.status !== void 0 || data.supersedes !== void 0 || data.tags !== void 0 || data.metadata !== void 0 || data.is_global !== void 0 || data.agent !== void 0 || data.role !== void 0 || data.completed_at !== void 0,
|
|
2731
|
+
{ message: "At least one field must be provided for update" }
|
|
2732
|
+
);
|
|
2733
|
+
var MemorySearchSchema = z.object({
|
|
2734
|
+
query: z.string().min(3),
|
|
2735
|
+
prompt: z.string().optional(),
|
|
2736
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2737
|
+
types: z.array(MemoryTypeSchema).optional(),
|
|
2738
|
+
minImportance: z.number().min(1).max(5).optional(),
|
|
2739
|
+
limit: z.number().min(1).max(100).default(5),
|
|
2740
|
+
offset: z.number().min(0).default(0),
|
|
2741
|
+
includeRecap: z.boolean().default(false),
|
|
2742
|
+
current_file_path: z.string().optional(),
|
|
2743
|
+
include_archived: z.boolean().default(false),
|
|
2744
|
+
current_tags: z.array(z.string()).optional(),
|
|
2745
|
+
scope: MemoryScopeSchema.partial().optional(),
|
|
2746
|
+
structured: z.boolean().default(false)
|
|
2747
|
+
});
|
|
2748
|
+
var MemoryAcknowledgeSchema = z.object({
|
|
2749
|
+
memory_id: z.string().uuid(),
|
|
2750
|
+
status: z.enum(["used", "irrelevant", "contradictory"]),
|
|
2751
|
+
application_context: z.string().min(10).optional(),
|
|
2752
|
+
structured: z.boolean().default(false)
|
|
2753
|
+
});
|
|
2754
|
+
var MemoryRecapSchema = z.object({
|
|
2755
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2756
|
+
limit: z.number().min(1).max(50).default(20),
|
|
2757
|
+
offset: z.number().min(0).default(0),
|
|
2758
|
+
structured: z.boolean().default(false)
|
|
2759
|
+
});
|
|
2760
|
+
var MemoryDeleteSchema = z.object({
|
|
2761
|
+
repo: z.string().min(1).transform(normalizeRepo).optional(),
|
|
2762
|
+
id: z.string().uuid().optional(),
|
|
2763
|
+
ids: z.array(z.string().uuid()).min(1).optional(),
|
|
2764
|
+
structured: z.boolean().default(false)
|
|
2765
|
+
}).refine((data) => data.id !== void 0 || data.ids !== void 0, {
|
|
2766
|
+
message: "Either 'id' or 'ids' must be provided for deletion"
|
|
2767
|
+
});
|
|
2768
|
+
var MemorySummarizeSchema = z.object({
|
|
2769
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2770
|
+
signals: z.array(z.string().max(200)).min(1),
|
|
2771
|
+
structured: z.boolean().default(false)
|
|
2772
|
+
});
|
|
2773
|
+
var MemorySynthesizeSchema = z.object({
|
|
2774
|
+
repo: z.string().min(1).transform(normalizeRepo).optional(),
|
|
2775
|
+
objective: z.string().min(5),
|
|
2776
|
+
current_file_path: z.string().optional(),
|
|
2777
|
+
include_summary: z.boolean().default(true),
|
|
2778
|
+
include_tasks: z.boolean().default(true),
|
|
2779
|
+
use_tools: z.boolean().default(true),
|
|
2780
|
+
max_iterations: z.number().int().min(1).max(5).default(3),
|
|
2781
|
+
max_tokens: z.number().int().min(128).max(4e3).default(1200),
|
|
2782
|
+
structured: z.boolean().default(false)
|
|
2783
|
+
});
|
|
2784
|
+
var TaskStatusSchema = z.enum(["backlog", "pending", "in_progress", "completed", "canceled", "blocked"]);
|
|
2785
|
+
var TaskPrioritySchema = z.number().min(1).max(5);
|
|
2786
|
+
var SingleTaskCreateSchema = z.object({
|
|
2787
|
+
task_code: z.string().min(1),
|
|
2788
|
+
phase: z.string().min(1),
|
|
2789
|
+
title: z.string().min(3).max(100),
|
|
2790
|
+
description: z.string().min(1),
|
|
2791
|
+
status: TaskStatusSchema.default("backlog"),
|
|
2792
|
+
priority: TaskPrioritySchema.default(3),
|
|
2793
|
+
agent: z.string().optional(),
|
|
2794
|
+
role: z.string().optional(),
|
|
2795
|
+
doc_path: z.string().optional(),
|
|
2796
|
+
tags: z.array(z.string()).optional(),
|
|
2797
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
2798
|
+
parent_id: z.string().uuid().optional(),
|
|
2799
|
+
depends_on: z.string().uuid().optional(),
|
|
2800
|
+
est_tokens: z.number().int().min(0).optional()
|
|
2801
|
+
});
|
|
2802
|
+
var TaskCreateSchema = z.object({
|
|
2803
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2804
|
+
// Allow single task fields at top level (backward compatibility & single use)
|
|
2805
|
+
task_code: z.string().min(1).optional(),
|
|
2806
|
+
phase: z.string().min(1).optional(),
|
|
2807
|
+
title: z.string().min(3).max(100).optional(),
|
|
2808
|
+
description: z.string().min(1).optional(),
|
|
2809
|
+
status: TaskStatusSchema.optional(),
|
|
2810
|
+
priority: TaskPrioritySchema.optional(),
|
|
2811
|
+
agent: z.string().optional(),
|
|
2812
|
+
role: z.string().optional(),
|
|
2813
|
+
doc_path: z.string().optional(),
|
|
2814
|
+
tags: z.array(z.string()).optional(),
|
|
2815
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
2816
|
+
parent_id: z.string().uuid().optional(),
|
|
2817
|
+
depends_on: z.string().uuid().optional(),
|
|
2818
|
+
est_tokens: z.number().int().min(0).optional(),
|
|
2819
|
+
// Allow bulk tasks
|
|
2820
|
+
tasks: z.array(SingleTaskCreateSchema).min(1).optional(),
|
|
2821
|
+
structured: z.boolean().default(false)
|
|
2822
|
+
}).refine(
|
|
2823
|
+
(data) => {
|
|
2824
|
+
if (data.tasks) return true;
|
|
2825
|
+
return !!(data.task_code && data.phase && data.title && data.description);
|
|
2826
|
+
},
|
|
2827
|
+
{ message: "Either 'tasks' array or single task fields (task_code, phase, title, description) must be provided" }
|
|
2828
|
+
);
|
|
2829
|
+
var TaskCreateInteractiveSchema = SingleTaskCreateSchema.partial().extend({
|
|
2830
|
+
repo: z.string().min(1).transform(normalizeRepo).optional(),
|
|
2831
|
+
structured: z.boolean().default(false)
|
|
2832
|
+
});
|
|
2833
|
+
var TaskUpdateSchema = z.object({
|
|
2834
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2835
|
+
id: z.string().uuid().optional(),
|
|
2836
|
+
ids: z.array(z.string().uuid()).min(1).optional(),
|
|
2837
|
+
task_code: z.string().optional(),
|
|
2838
|
+
phase: z.string().optional(),
|
|
2839
|
+
title: z.string().min(3).max(100).optional(),
|
|
2840
|
+
description: z.string().optional(),
|
|
2841
|
+
status: TaskStatusSchema.optional(),
|
|
2842
|
+
priority: TaskPrioritySchema.optional(),
|
|
2843
|
+
agent: z.string().min(1, "agent name is required").optional(),
|
|
2844
|
+
role: z.string().min(1, "agent role is required").optional(),
|
|
2845
|
+
model: z.string().optional(),
|
|
2846
|
+
comment: z.string().min(1).optional(),
|
|
2847
|
+
doc_path: z.string().optional(),
|
|
2848
|
+
tags: z.array(z.string()).optional(),
|
|
2849
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
2850
|
+
parent_id: z.string().uuid().optional(),
|
|
2851
|
+
depends_on: z.string().uuid().optional(),
|
|
2852
|
+
est_tokens: z.number().int().min(0).optional(),
|
|
2853
|
+
force: z.boolean().optional(),
|
|
2854
|
+
structured: z.boolean().default(false)
|
|
2855
|
+
}).refine((data) => data.id !== void 0 || data.ids !== void 0 || data.task_code !== void 0, {
|
|
2856
|
+
message: "Either 'id', 'ids', or 'task_code' must be provided for update"
|
|
2857
|
+
}).refine((data) => Object.keys(data).length > 2, {
|
|
2858
|
+
message: "At least one field besides repo and id/ids must be provided for update"
|
|
2859
|
+
});
|
|
2860
|
+
var TaskListSchema = z.object({
|
|
2861
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2862
|
+
status: z.string().optional(),
|
|
2863
|
+
phase: z.string().optional(),
|
|
2864
|
+
query: z.string().optional(),
|
|
2865
|
+
limit: z.number().min(1).max(100).default(15),
|
|
2866
|
+
offset: z.number().min(0).default(0),
|
|
2867
|
+
structured: z.boolean().default(false)
|
|
2868
|
+
});
|
|
2869
|
+
var TaskSearchSchema = z.object({
|
|
2870
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2871
|
+
query: z.string().min(1),
|
|
2872
|
+
status: z.string().optional(),
|
|
2873
|
+
limit: z.number().min(1).max(100).default(10),
|
|
2874
|
+
offset: z.number().min(0).default(0),
|
|
2875
|
+
structured: z.boolean().default(false)
|
|
2876
|
+
});
|
|
2877
|
+
var TaskDeleteSchema = z.object({
|
|
2878
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2879
|
+
id: z.string().uuid().optional(),
|
|
2880
|
+
ids: z.array(z.string().uuid()).min(1).optional(),
|
|
2881
|
+
structured: z.boolean().default(false)
|
|
2882
|
+
}).refine((data) => data.id !== void 0 || data.ids !== void 0, {
|
|
2883
|
+
message: "Either 'id' or 'ids' must be provided for deletion"
|
|
2884
|
+
});
|
|
2885
|
+
var MemoryDetailSchema = z.object({
|
|
2886
|
+
id: z.string().uuid().optional(),
|
|
2887
|
+
code: z.string().max(20).optional(),
|
|
2888
|
+
structured: z.boolean().default(false)
|
|
2889
|
+
}).refine((data) => data.id !== void 0 || data.code !== void 0, {
|
|
2890
|
+
message: "Either id or code must be provided"
|
|
2891
|
+
});
|
|
2892
|
+
var TaskGetSchema = z.object({
|
|
2893
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2894
|
+
id: z.string().uuid().optional(),
|
|
2895
|
+
task_code: z.string().optional(),
|
|
2896
|
+
structured: z.boolean().default(false)
|
|
2897
|
+
}).refine((data) => data.id !== void 0 || data.task_code !== void 0, {
|
|
2898
|
+
message: "Either id or task_code must be provided"
|
|
2899
|
+
});
|
|
2900
|
+
var HandoffStatusSchema = z.enum(["pending", "accepted", "rejected", "expired"]);
|
|
2901
|
+
var HandoffCreateSchema = z.object({
|
|
2902
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2903
|
+
from_agent: z.string().min(1),
|
|
2904
|
+
to_agent: z.string().min(1).optional(),
|
|
2905
|
+
task_id: z.string().uuid().optional(),
|
|
2906
|
+
task_code: z.string().optional(),
|
|
2907
|
+
summary: z.string().min(1),
|
|
2908
|
+
context: z.record(z.string(), z.any()).optional(),
|
|
2909
|
+
expires_at: z.string().optional(),
|
|
2910
|
+
structured: z.boolean().default(false)
|
|
2911
|
+
}).refine((data) => !(data.task_id && data.task_code), {
|
|
2912
|
+
message: "Provide either task_id or task_code, not both"
|
|
2913
|
+
}).refine((data) => data.to_agent || data.task_id || data.task_code || data.context?.next_steps || data.context?.blockers || data.context?.remaining_work, {
|
|
2914
|
+
message: "Handoffs must identify a target agent, linked task, next_steps, blockers, or remaining_work. Do not create pending handoffs for completed-work summaries."
|
|
2915
|
+
});
|
|
2916
|
+
var HandoffUpdateSchema = z.object({
|
|
2917
|
+
id: z.string().uuid(),
|
|
2918
|
+
status: HandoffStatusSchema,
|
|
2919
|
+
structured: z.boolean().default(false)
|
|
2920
|
+
});
|
|
2921
|
+
var HandoffListSchema = z.object({
|
|
2922
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2923
|
+
status: HandoffStatusSchema.optional(),
|
|
2924
|
+
from_agent: z.string().min(1).optional(),
|
|
2925
|
+
to_agent: z.string().min(1).optional(),
|
|
2926
|
+
limit: z.number().min(1).max(100).default(20),
|
|
2927
|
+
offset: z.number().min(0).default(0),
|
|
2928
|
+
structured: z.boolean().default(false)
|
|
2929
|
+
});
|
|
2930
|
+
var TaskClaimSchema = z.object({
|
|
2931
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
2932
|
+
task_id: z.string().uuid().optional(),
|
|
2933
|
+
task_code: z.string().optional(),
|
|
2934
|
+
agent: z.string().min(1),
|
|
2935
|
+
role: z.string().optional(),
|
|
2936
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
2937
|
+
structured: z.boolean().default(false)
|
|
2938
|
+
}).refine((data) => data.task_id !== void 0 || data.task_code !== void 0, {
|
|
2939
|
+
message: "Either task_id or task_code must be provided"
|
|
2940
|
+
}).refine((data) => !(data.task_id && data.task_code), {
|
|
2941
|
+
message: "Provide either task_id or task_code, not both"
|
|
2942
|
+
});
|
|
2943
|
+
var StandardStoreSchema = z.object({
|
|
2944
|
+
name: z.string().min(3).max(255),
|
|
2945
|
+
content: z.string().min(10),
|
|
2946
|
+
context: z.string().optional(),
|
|
2947
|
+
version: z.string().optional(),
|
|
2948
|
+
language: z.string().optional(),
|
|
2949
|
+
stack: z.array(z.string()).optional(),
|
|
2950
|
+
repo: z.string().optional(),
|
|
2951
|
+
is_global: z.boolean().optional(),
|
|
2952
|
+
tags: z.array(z.string()).optional(),
|
|
2953
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
2954
|
+
agent: z.string().optional(),
|
|
2955
|
+
model: z.string().optional(),
|
|
2956
|
+
structured: z.boolean().default(false)
|
|
2957
|
+
});
|
|
2958
|
+
var StandardSearchSchema = z.object({
|
|
2959
|
+
query: z.string().optional(),
|
|
2960
|
+
stack: z.array(z.string()).optional(),
|
|
2961
|
+
language: z.string().optional(),
|
|
2962
|
+
version: z.string().optional(),
|
|
2963
|
+
repo: z.string().optional(),
|
|
2964
|
+
is_global: z.boolean().optional(),
|
|
2965
|
+
limit: z.number().min(1).max(100).default(20),
|
|
2966
|
+
offset: z.number().min(0).default(0),
|
|
2967
|
+
structured: z.boolean().default(false)
|
|
2968
|
+
});
|
|
2969
|
+
var TOOL_DEFINITIONS = [
|
|
2970
|
+
{
|
|
2971
|
+
name: "memory-synthesize",
|
|
2972
|
+
title: "Memory Synthesize",
|
|
2973
|
+
description: "Use client sampling to synthesize a grounded answer from local memory and tasks. Best for project briefings, tradeoff summaries, and context-aware answers.",
|
|
2974
|
+
annotations: {
|
|
2975
|
+
readOnlyHint: true,
|
|
2976
|
+
idempotentHint: true,
|
|
2977
|
+
openWorldHint: false
|
|
2978
|
+
},
|
|
2979
|
+
execution: {
|
|
2980
|
+
taskSupport: "optional"
|
|
2981
|
+
},
|
|
2982
|
+
inputSchema: {
|
|
2983
|
+
type: "object",
|
|
2984
|
+
properties: {
|
|
2985
|
+
repo: { type: "string", description: "Repository name. Optional when a single MCP root is active." },
|
|
2986
|
+
objective: { type: "string", minLength: 5, description: "Question or synthesis objective." },
|
|
2987
|
+
current_file_path: {
|
|
2988
|
+
type: "string",
|
|
2989
|
+
description: "Optional absolute file path for workspace-local grounding."
|
|
2990
|
+
},
|
|
2991
|
+
include_summary: { type: "boolean", default: true },
|
|
2992
|
+
include_tasks: { type: "boolean", default: true },
|
|
2993
|
+
use_tools: {
|
|
2994
|
+
type: "boolean",
|
|
2995
|
+
default: true,
|
|
2996
|
+
description: "Allow the sampled model to call local memory/task tools during synthesis when the client supports sampling.tools."
|
|
2997
|
+
},
|
|
2998
|
+
max_iterations: { type: "number", minimum: 1, maximum: 5, default: 3 },
|
|
2999
|
+
max_tokens: { type: "number", minimum: 128, maximum: 4e3, default: 1200 },
|
|
3000
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON results." }
|
|
3001
|
+
},
|
|
3002
|
+
required: ["objective"]
|
|
3003
|
+
},
|
|
3004
|
+
outputSchema: {
|
|
3005
|
+
type: "object",
|
|
3006
|
+
properties: {
|
|
3007
|
+
repo: { type: "string" },
|
|
3008
|
+
objective: { type: "string" },
|
|
3009
|
+
answer: { type: "string" },
|
|
3010
|
+
model: { type: "string" },
|
|
3011
|
+
stopReason: { type: "string" },
|
|
3012
|
+
iterations: { type: "number" },
|
|
3013
|
+
toolCalls: { type: "number" }
|
|
3014
|
+
},
|
|
3015
|
+
required: ["repo", "objective", "answer", "iterations", "toolCalls"]
|
|
2983
3016
|
}
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
3017
|
+
},
|
|
3018
|
+
{
|
|
3019
|
+
name: "task-create-interactive",
|
|
3020
|
+
title: "Interactive Task Create",
|
|
3021
|
+
description: "Create a task with MCP elicitation fallback for any missing required fields. Best when an agent knows a task is needed but still needs user confirmation for repo, title, or phase.",
|
|
3022
|
+
annotations: {
|
|
3023
|
+
readOnlyHint: false,
|
|
3024
|
+
idempotentHint: false,
|
|
3025
|
+
destructiveHint: false,
|
|
3026
|
+
openWorldHint: false
|
|
3027
|
+
},
|
|
3028
|
+
inputSchema: {
|
|
3029
|
+
type: "object",
|
|
3030
|
+
properties: {
|
|
3031
|
+
repo: {
|
|
3032
|
+
type: "string",
|
|
3033
|
+
description: "Repository name. Optional when it can be inferred from MCP roots or elicited from the user."
|
|
3034
|
+
},
|
|
3035
|
+
task_code: { type: "string" },
|
|
3036
|
+
phase: { type: "string" },
|
|
3037
|
+
title: { type: "string", minLength: 3, maxLength: 100 },
|
|
3038
|
+
description: { type: "string", minLength: 1 },
|
|
3039
|
+
status: { type: "string", enum: ["backlog", "pending"], default: "backlog" },
|
|
3040
|
+
priority: { type: "number", minimum: 1, maximum: 5, default: 3 },
|
|
3041
|
+
agent: { type: "string" },
|
|
3042
|
+
role: { type: "string" },
|
|
3043
|
+
doc_path: { type: "string" },
|
|
3044
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
2999
3045
|
}
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
}
|
|
3013
|
-
}
|
|
3014
|
-
]
|
|
3015
|
-
};
|
|
3016
|
-
}
|
|
3017
|
-
if (repoPath === "actions") {
|
|
3018
|
-
const actions = db.actions.getRecentActions(name, 100);
|
|
3019
|
-
const payload = JSON.stringify(actions, null, 2);
|
|
3020
|
-
return {
|
|
3021
|
-
contents: [
|
|
3022
|
-
{
|
|
3023
|
-
uri,
|
|
3024
|
-
mimeType: "application/json",
|
|
3025
|
-
text: payload,
|
|
3026
|
-
size: Buffer.byteLength(payload, "utf8"),
|
|
3027
|
-
annotations: {
|
|
3028
|
-
audience: ["assistant"],
|
|
3029
|
-
priority: 0.6,
|
|
3030
|
-
lastModified: deriveLastModifiedFromCollection(actions.map((a) => a.created_at))
|
|
3031
|
-
}
|
|
3032
|
-
}
|
|
3033
|
-
]
|
|
3034
|
-
};
|
|
3046
|
+
},
|
|
3047
|
+
outputSchema: {
|
|
3048
|
+
type: "object",
|
|
3049
|
+
properties: {
|
|
3050
|
+
repo: { type: "string" },
|
|
3051
|
+
task_code: { type: "string" },
|
|
3052
|
+
phase: { type: "string" },
|
|
3053
|
+
title: { type: "string" },
|
|
3054
|
+
status: { type: "string" },
|
|
3055
|
+
priority: { type: "number" }
|
|
3056
|
+
},
|
|
3057
|
+
required: ["repo", "task_code", "phase", "title", "status", "priority"]
|
|
3035
3058
|
}
|
|
3036
|
-
}
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
{
|
|
3046
|
-
|
|
3047
|
-
mimeType: "application/json",
|
|
3048
|
-
text: payload,
|
|
3049
|
-
size: Buffer.byteLength(payload, "utf8"),
|
|
3050
|
-
annotations: {
|
|
3051
|
-
audience: ["assistant"],
|
|
3052
|
-
priority: 0.55,
|
|
3053
|
-
lastModified: action.created_at
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
]
|
|
3057
|
-
};
|
|
3058
|
-
}
|
|
3059
|
-
throw resourceNotFound(`Unknown resource URI: ${uri}`, uri);
|
|
3060
|
-
}
|
|
3061
|
-
function parseRepoUri(uri) {
|
|
3062
|
-
const prefix = "repository://";
|
|
3063
|
-
if (!uri.startsWith(prefix)) return null;
|
|
3064
|
-
const rest = uri.slice(prefix.length);
|
|
3065
|
-
const queryStart = rest.indexOf("?");
|
|
3066
|
-
const withoutQuery = queryStart === -1 ? rest : rest.slice(0, queryStart);
|
|
3067
|
-
const queryString = queryStart === -1 ? "" : rest.slice(queryStart + 1);
|
|
3068
|
-
const slashIdx = withoutQuery.indexOf("/");
|
|
3069
|
-
if (slashIdx === -1) return null;
|
|
3070
|
-
const name = withoutQuery.slice(0, slashIdx);
|
|
3071
|
-
const path6 = withoutQuery.slice(slashIdx + 1);
|
|
3072
|
-
if (!name || !path6) return null;
|
|
3073
|
-
return { name, path: path6, query: new URLSearchParams(queryString) };
|
|
3074
|
-
}
|
|
3075
|
-
function paginateEntries(key, entries, params) {
|
|
3076
|
-
const limit = normalizeLimit(params?.limit);
|
|
3077
|
-
const offset = decodeCursor(params?.cursor);
|
|
3078
|
-
const sliced = entries.slice(offset, offset + limit);
|
|
3079
|
-
const nextOffset = offset + sliced.length;
|
|
3080
|
-
return {
|
|
3081
|
-
[key]: sliced,
|
|
3082
|
-
nextCursor: nextOffset < entries.length ? encodeCursor(nextOffset) : void 0
|
|
3083
|
-
};
|
|
3084
|
-
}
|
|
3085
|
-
function normalizeLimit(limit) {
|
|
3086
|
-
if (typeof limit !== "number" || !Number.isFinite(limit)) {
|
|
3087
|
-
return DEFAULT_PAGE_SIZE;
|
|
3088
|
-
}
|
|
3089
|
-
return Math.min(MAX_PAGE_SIZE, Math.max(1, Math.trunc(limit)));
|
|
3090
|
-
}
|
|
3091
|
-
function deriveLastModifiedFromCollection(values) {
|
|
3092
|
-
const normalized = values.filter((value) => typeof value === "string" && value.length > 0);
|
|
3093
|
-
return normalized.sort().at(-1) ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
3094
|
-
}
|
|
3095
|
-
function resourceNotFound(message, uri) {
|
|
3096
|
-
const error = new Error(message);
|
|
3097
|
-
error.code = -32002;
|
|
3098
|
-
error.data = { uri };
|
|
3099
|
-
return error;
|
|
3100
|
-
}
|
|
3101
|
-
function invalidCompletionParams(message) {
|
|
3102
|
-
const error = new Error(message);
|
|
3103
|
-
error.code = -32602;
|
|
3104
|
-
return error;
|
|
3105
|
-
}
|
|
3106
|
-
|
|
3107
|
-
// src/mcp/prompts/loader.ts
|
|
3108
|
-
import fs4 from "fs";
|
|
3109
|
-
import path5 from "path";
|
|
3110
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3111
|
-
import matter from "gray-matter";
|
|
3112
|
-
var __filename = fileURLToPath3(import.meta.url);
|
|
3113
|
-
var __dirname2 = path5.dirname(__filename);
|
|
3114
|
-
function findPromptDir() {
|
|
3115
|
-
const candidates = [
|
|
3116
|
-
// Production if chunked into dist/
|
|
3117
|
-
"./prompts",
|
|
3118
|
-
// Production if inlined into dist/mcp/
|
|
3119
|
-
"../prompts",
|
|
3120
|
-
// Dev: /src/mcp/prompts/definitions (next to loader.ts)
|
|
3121
|
-
"./definitions"
|
|
3122
|
-
].map((relPath) => path5.resolve(__dirname2, relPath));
|
|
3123
|
-
for (const dir of candidates) {
|
|
3124
|
-
if (fs4.existsSync(dir)) {
|
|
3125
|
-
const files = fs4.readdirSync(dir);
|
|
3126
|
-
if (files.some((f) => f.endsWith(".md"))) {
|
|
3127
|
-
return dir;
|
|
3059
|
+
},
|
|
3060
|
+
{
|
|
3061
|
+
name: "memory-detail",
|
|
3062
|
+
title: "Memory Detail",
|
|
3063
|
+
description: "Fetch full details of a specific memory by ID or short code. Use after memory-recap or memory-search when a pointer row is relevant and full content is needed.",
|
|
3064
|
+
inputSchema: {
|
|
3065
|
+
type: "object",
|
|
3066
|
+
properties: {
|
|
3067
|
+
id: { type: "string", format: "uuid", description: "Memory entry ID. Optional if code is provided." },
|
|
3068
|
+
code: { type: "string", description: "Short memory code. Optional if id is provided." },
|
|
3069
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON details." }
|
|
3128
3070
|
}
|
|
3129
3071
|
}
|
|
3130
|
-
}
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
return {
|
|
3146
|
-
name: data.name || name,
|
|
3147
|
-
description: data.description || "",
|
|
3148
|
-
arguments: data.arguments || [],
|
|
3149
|
-
agent: data.agent,
|
|
3150
|
-
content: content.trim()
|
|
3151
|
-
};
|
|
3152
|
-
}
|
|
3153
|
-
|
|
3154
|
-
// src/mcp/prompts/registry.ts
|
|
3155
|
-
function createPromptDefinition(loaded) {
|
|
3156
|
-
return {
|
|
3157
|
-
name: loaded.name,
|
|
3158
|
-
description: loaded.description,
|
|
3159
|
-
arguments: loaded.arguments,
|
|
3160
|
-
agent: loaded.agent,
|
|
3161
|
-
messages: [
|
|
3162
|
-
{
|
|
3163
|
-
role: "user",
|
|
3164
|
-
content: {
|
|
3165
|
-
type: "text",
|
|
3166
|
-
text: loaded.content
|
|
3072
|
+
},
|
|
3073
|
+
{
|
|
3074
|
+
name: "task-detail",
|
|
3075
|
+
title: "Task Detail",
|
|
3076
|
+
description: "Fetch full details of a specific task by ID or task code. Use this when you have a task ID or code and need to read the full description and comments.",
|
|
3077
|
+
inputSchema: {
|
|
3078
|
+
type: "object",
|
|
3079
|
+
properties: {
|
|
3080
|
+
repo: { type: "string", description: "Repository name" },
|
|
3081
|
+
id: { type: "string", format: "uuid", description: "Task ID (optional if task_code is provided)" },
|
|
3082
|
+
task_code: { type: "string", description: "Task code (e.g. TASK-001) (optional if id is provided)" },
|
|
3083
|
+
structured: {
|
|
3084
|
+
type: "boolean",
|
|
3085
|
+
default: false,
|
|
3086
|
+
description: "If true, returns structured JSON without the text content details."
|
|
3167
3087
|
}
|
|
3168
|
-
}
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
}
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3088
|
+
},
|
|
3089
|
+
required: ["repo"]
|
|
3090
|
+
}
|
|
3091
|
+
},
|
|
3092
|
+
{
|
|
3093
|
+
name: "memory-store",
|
|
3094
|
+
title: "Memory Store",
|
|
3095
|
+
description: "Store a new durable knowledge entry. Do not store coordination state here: task claims, file claims, agent registration, and handoffs belong to task-claim, task-update, and handoff-* tools. Keep 'title' concise and human-readable; put auxiliary context into 'metadata'.",
|
|
3096
|
+
annotations: {
|
|
3097
|
+
readOnlyHint: false,
|
|
3098
|
+
idempotentHint: false,
|
|
3099
|
+
destructiveHint: false,
|
|
3100
|
+
openWorldHint: false
|
|
3101
|
+
},
|
|
3102
|
+
inputSchema: {
|
|
3103
|
+
type: "object",
|
|
3104
|
+
properties: {
|
|
3105
|
+
type: {
|
|
3106
|
+
type: "string",
|
|
3107
|
+
enum: [
|
|
3108
|
+
"code_fact",
|
|
3109
|
+
"decision",
|
|
3110
|
+
"mistake",
|
|
3111
|
+
"pattern",
|
|
3112
|
+
"task_archive"
|
|
3113
|
+
],
|
|
3114
|
+
description: "Type of durable knowledge being stored. Coordination types such as file_claim are intentionally unsupported."
|
|
3115
|
+
},
|
|
3116
|
+
title: {
|
|
3117
|
+
type: "string",
|
|
3118
|
+
minLength: 3,
|
|
3119
|
+
maxLength: 100,
|
|
3120
|
+
description: "Short human-readable title for the memory. Do not embed bracketed metadata like agent/role/date prefixes here."
|
|
3121
|
+
},
|
|
3122
|
+
content: {
|
|
3123
|
+
type: "string",
|
|
3124
|
+
minLength: 10,
|
|
3125
|
+
description: "The memory content"
|
|
3126
|
+
},
|
|
3127
|
+
importance: {
|
|
3128
|
+
type: "number",
|
|
3129
|
+
minimum: 1,
|
|
3130
|
+
maximum: 5,
|
|
3131
|
+
description: "Importance score (1-5)"
|
|
3132
|
+
},
|
|
3133
|
+
agent: {
|
|
3134
|
+
type: "string",
|
|
3135
|
+
description: "Name of the agent creating this memory"
|
|
3136
|
+
},
|
|
3137
|
+
role: {
|
|
3138
|
+
type: "string",
|
|
3139
|
+
description: "Role of the agent creating this memory"
|
|
3140
|
+
},
|
|
3141
|
+
model: {
|
|
3142
|
+
type: "string",
|
|
3143
|
+
description: "AI model used by the agent"
|
|
3144
|
+
},
|
|
3145
|
+
scope: {
|
|
3146
|
+
type: "object",
|
|
3147
|
+
properties: {
|
|
3148
|
+
repo: { type: "string", description: "Repository name" },
|
|
3149
|
+
branch: { type: "string" },
|
|
3150
|
+
folder: { type: "string" },
|
|
3151
|
+
language: { type: "string" }
|
|
3152
|
+
},
|
|
3153
|
+
required: ["repo"]
|
|
3154
|
+
},
|
|
3155
|
+
tags: {
|
|
3156
|
+
type: "array",
|
|
3157
|
+
items: { type: "string" },
|
|
3158
|
+
description: "Technology stack tags (e.g., ['filament', 'laravel'])"
|
|
3159
|
+
},
|
|
3160
|
+
metadata: {
|
|
3161
|
+
type: "object",
|
|
3162
|
+
description: "Structured metadata for non-title context such as source agent, claim fields, or timestamps"
|
|
3163
|
+
},
|
|
3164
|
+
is_global: {
|
|
3165
|
+
type: "boolean",
|
|
3166
|
+
description: "If true, this memory is shared across all repositories"
|
|
3167
|
+
},
|
|
3168
|
+
ttlDays: { type: "number", minimum: 1 },
|
|
3169
|
+
supersedes: { type: "string", format: "uuid" },
|
|
3170
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON of the stored memory." }
|
|
3171
|
+
},
|
|
3172
|
+
required: ["type", "title", "content", "importance", "scope", "agent", "model"]
|
|
3173
|
+
},
|
|
3174
|
+
outputSchema: {
|
|
3175
|
+
type: "object",
|
|
3176
|
+
properties: {
|
|
3177
|
+
success: { type: "boolean" },
|
|
3178
|
+
id: { type: "string" },
|
|
3179
|
+
code: { type: "string" },
|
|
3180
|
+
repo: { type: "string" },
|
|
3181
|
+
type: { type: "string" },
|
|
3182
|
+
title: { type: "string" },
|
|
3183
|
+
error: { type: "string" },
|
|
3184
|
+
message: { type: "string" }
|
|
3185
|
+
},
|
|
3186
|
+
required: ["success"]
|
|
3187
|
+
}
|
|
3188
|
+
},
|
|
3189
|
+
{
|
|
3190
|
+
name: "memory-acknowledge",
|
|
3191
|
+
title: "Memory Acknowledge",
|
|
3192
|
+
description: "Acknowledge the use of a memory or report its irrelevance/contradiction. Mandatory after using memory to generate code.",
|
|
3193
|
+
annotations: {
|
|
3194
|
+
readOnlyHint: false,
|
|
3195
|
+
idempotentHint: false,
|
|
3196
|
+
openWorldHint: false
|
|
3197
|
+
},
|
|
3198
|
+
inputSchema: {
|
|
3199
|
+
type: "object",
|
|
3200
|
+
properties: {
|
|
3201
|
+
memory_id: { type: "string", format: "uuid" },
|
|
3202
|
+
status: { type: "string", enum: ["used", "irrelevant", "contradictory"] },
|
|
3203
|
+
application_context: { type: "string", minLength: 10 },
|
|
3204
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
3205
|
+
},
|
|
3206
|
+
required: ["memory_id", "status"]
|
|
3207
|
+
},
|
|
3208
|
+
outputSchema: {
|
|
3209
|
+
type: "object",
|
|
3210
|
+
properties: {
|
|
3211
|
+
success: { type: "boolean" },
|
|
3212
|
+
id: { type: "string" },
|
|
3213
|
+
status: { type: "string" }
|
|
3214
|
+
},
|
|
3215
|
+
required: ["success", "id", "status"]
|
|
3216
|
+
}
|
|
3217
|
+
},
|
|
3218
|
+
{
|
|
3219
|
+
name: "memory-update",
|
|
3220
|
+
title: "Memory Update",
|
|
3221
|
+
description: "Update an existing memory entry. Keep 'title' concise and move agent/role/date or claim context into 'metadata' instead of the title.",
|
|
3222
|
+
annotations: {
|
|
3223
|
+
readOnlyHint: false,
|
|
3224
|
+
idempotentHint: false,
|
|
3225
|
+
destructiveHint: false,
|
|
3226
|
+
openWorldHint: false
|
|
3227
|
+
},
|
|
3228
|
+
inputSchema: {
|
|
3229
|
+
type: "object",
|
|
3230
|
+
properties: {
|
|
3231
|
+
id: { type: "string", format: "uuid" },
|
|
3232
|
+
type: {
|
|
3233
|
+
type: "string",
|
|
3234
|
+
enum: [
|
|
3235
|
+
"code_fact",
|
|
3236
|
+
"decision",
|
|
3237
|
+
"mistake",
|
|
3238
|
+
"pattern",
|
|
3239
|
+
"task_archive"
|
|
3240
|
+
]
|
|
3241
|
+
},
|
|
3242
|
+
title: { type: "string", minLength: 3, maxLength: 100 },
|
|
3243
|
+
content: { type: "string", minLength: 10 },
|
|
3244
|
+
importance: { type: "number", minimum: 1, maximum: 5 },
|
|
3245
|
+
agent: { type: "string" },
|
|
3246
|
+
role: { type: "string" },
|
|
3247
|
+
status: { type: "string", enum: ["active", "archived"] },
|
|
3248
|
+
supersedes: { type: "string", format: "uuid" },
|
|
3249
|
+
tags: { type: "array", items: { type: "string" } },
|
|
3250
|
+
metadata: { type: "object" },
|
|
3251
|
+
is_global: { type: "boolean" },
|
|
3252
|
+
completed_at: { type: "string" },
|
|
3253
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON of the updated memory." }
|
|
3254
|
+
},
|
|
3255
|
+
required: ["id"]
|
|
3256
|
+
},
|
|
3257
|
+
outputSchema: {
|
|
3258
|
+
type: "object",
|
|
3259
|
+
properties: {
|
|
3260
|
+
success: { type: "boolean" },
|
|
3261
|
+
id: { type: "string" },
|
|
3262
|
+
repo: { type: "string" },
|
|
3263
|
+
updatedFields: {
|
|
3264
|
+
type: "array",
|
|
3265
|
+
items: { type: "string" }
|
|
3266
|
+
}
|
|
3267
|
+
},
|
|
3268
|
+
required: ["success", "id", "repo", "updatedFields"]
|
|
3269
|
+
}
|
|
3270
|
+
},
|
|
3271
|
+
{
|
|
3272
|
+
name: "memory-search",
|
|
3273
|
+
title: "Memory Search",
|
|
3274
|
+
description: "NAVIGATION LAYER: Returns a pointer table of matching memory IDs only. Returns columns [id, title, type, importance] \u2014 NO content. Retrieve full memory via memory-detail. Use 'current_tags' to find tech-stack specific knowledge from other projects.",
|
|
3275
|
+
annotations: {
|
|
3276
|
+
readOnlyHint: true,
|
|
3277
|
+
idempotentHint: true,
|
|
3278
|
+
openWorldHint: false
|
|
3279
|
+
},
|
|
3280
|
+
inputSchema: {
|
|
3281
|
+
type: "object",
|
|
3282
|
+
properties: {
|
|
3283
|
+
query: { type: "string", minLength: 3 },
|
|
3284
|
+
prompt: { type: "string" },
|
|
3285
|
+
repo: { type: "string" },
|
|
3286
|
+
current_tags: {
|
|
3287
|
+
type: "array",
|
|
3288
|
+
items: { type: "string" },
|
|
3289
|
+
description: "Active tech stack tags (e.g., ['filament', 'react'])"
|
|
3290
|
+
},
|
|
3291
|
+
types: {
|
|
3292
|
+
type: "array",
|
|
3293
|
+
items: {
|
|
3294
|
+
type: "string",
|
|
3295
|
+
enum: [
|
|
3296
|
+
"code_fact",
|
|
3297
|
+
"decision",
|
|
3298
|
+
"mistake",
|
|
3299
|
+
"pattern",
|
|
3300
|
+
"task_archive"
|
|
3301
|
+
]
|
|
3302
|
+
}
|
|
3303
|
+
},
|
|
3304
|
+
minImportance: { type: "number", minimum: 1, maximum: 5 },
|
|
3305
|
+
limit: { type: "number", minimum: 1, maximum: 100, default: 5 },
|
|
3306
|
+
offset: { type: "number", minimum: 0, default: 0 },
|
|
3307
|
+
includeRecap: { type: "boolean", default: false },
|
|
3308
|
+
current_file_path: { type: "string" },
|
|
3309
|
+
include_archived: { type: "boolean", default: false },
|
|
3310
|
+
scope: {
|
|
3311
|
+
type: "object",
|
|
3312
|
+
properties: {
|
|
3313
|
+
repo: { type: "string" },
|
|
3314
|
+
branch: { type: "string" },
|
|
3315
|
+
folder: { type: "string" },
|
|
3316
|
+
language: { type: "string" }
|
|
3317
|
+
}
|
|
3318
|
+
},
|
|
3319
|
+
structured: {
|
|
3320
|
+
type: "boolean",
|
|
3321
|
+
default: false,
|
|
3322
|
+
description: "If true, returns structured JSON without the text content summary."
|
|
3323
|
+
}
|
|
3324
|
+
},
|
|
3325
|
+
required: ["query", "repo"]
|
|
3326
|
+
},
|
|
3327
|
+
outputSchema: {
|
|
3328
|
+
type: "object",
|
|
3329
|
+
properties: {
|
|
3330
|
+
schema: { type: "string", enum: ["memory-search"] },
|
|
3331
|
+
query: { type: "string" },
|
|
3332
|
+
count: { type: "number", description: "Number of rows returned" },
|
|
3333
|
+
total: { type: "number", description: "Total matching memories" },
|
|
3334
|
+
offset: { type: "number" },
|
|
3335
|
+
limit: { type: "number" },
|
|
3336
|
+
results: {
|
|
3337
|
+
type: "object",
|
|
3338
|
+
properties: {
|
|
3339
|
+
columns: {
|
|
3340
|
+
type: "array",
|
|
3341
|
+
items: { type: "string" },
|
|
3342
|
+
description: "Column names: [id, title, type, importance]"
|
|
3343
|
+
},
|
|
3344
|
+
rows: {
|
|
3345
|
+
type: "array",
|
|
3346
|
+
items: { type: "array" },
|
|
3347
|
+
description: "Each row: [id, title, type, importance]. Fetch full content via memory-detail"
|
|
3348
|
+
}
|
|
3349
|
+
},
|
|
3350
|
+
required: ["columns", "rows"]
|
|
3351
|
+
}
|
|
3352
|
+
},
|
|
3353
|
+
required: ["schema", "query", "count", "total", "offset", "limit", "results"]
|
|
3208
3354
|
}
|
|
3209
|
-
text = text.replace(/{{current_repo}}/g, inferredRepo || "unknown-repo");
|
|
3210
|
-
return {
|
|
3211
|
-
...m,
|
|
3212
|
-
content: {
|
|
3213
|
-
...m.content,
|
|
3214
|
-
text
|
|
3215
|
-
}
|
|
3216
|
-
};
|
|
3217
|
-
});
|
|
3218
|
-
return {
|
|
3219
|
-
description: prompt.description,
|
|
3220
|
-
messages,
|
|
3221
|
-
metadata: prompt.agent ? { agent: prompt.agent } : void 0
|
|
3222
|
-
};
|
|
3223
|
-
}
|
|
3224
|
-
async function completePromptArgument(name, argName, value, contextArguments, dataSources) {
|
|
3225
|
-
void name;
|
|
3226
|
-
void contextArguments;
|
|
3227
|
-
if (argName === "task_id") {
|
|
3228
|
-
const values = dataSources.tasks.map((t) => t.id);
|
|
3229
|
-
return rankCompletionValues(values, value);
|
|
3230
|
-
}
|
|
3231
|
-
return [];
|
|
3232
|
-
}
|
|
3233
|
-
|
|
3234
|
-
// src/mcp/tools/schemas.ts
|
|
3235
|
-
import { z } from "zod";
|
|
3236
|
-
var MemoryScopeSchema = z.object({
|
|
3237
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3238
|
-
branch: z.string().optional(),
|
|
3239
|
-
folder: z.string().optional(),
|
|
3240
|
-
language: z.string().optional()
|
|
3241
|
-
});
|
|
3242
|
-
var MemoryTypeSchema = z.enum([
|
|
3243
|
-
"code_fact",
|
|
3244
|
-
"decision",
|
|
3245
|
-
"mistake",
|
|
3246
|
-
"pattern",
|
|
3247
|
-
"file_claim",
|
|
3248
|
-
"task_archive"
|
|
3249
|
-
]);
|
|
3250
|
-
var MemoryStoreSchema = z.object({
|
|
3251
|
-
code: z.string().max(20).optional(),
|
|
3252
|
-
type: MemoryTypeSchema,
|
|
3253
|
-
title: z.string().min(3).max(255),
|
|
3254
|
-
content: z.string().min(10),
|
|
3255
|
-
importance: z.number().min(1).max(5),
|
|
3256
|
-
agent: z.string().min(1),
|
|
3257
|
-
role: z.string().optional().default("unknown"),
|
|
3258
|
-
model: z.string().min(1),
|
|
3259
|
-
scope: MemoryScopeSchema,
|
|
3260
|
-
ttlDays: z.number().min(1).optional(),
|
|
3261
|
-
supersedes: z.string().uuid().optional(),
|
|
3262
|
-
tags: z.array(z.string()).optional(),
|
|
3263
|
-
metadata: z.record(z.string(), z.any()).optional(),
|
|
3264
|
-
is_global: z.boolean().default(false),
|
|
3265
|
-
structured: z.boolean().default(false)
|
|
3266
|
-
});
|
|
3267
|
-
var MemoryUpdateSchema = z.object({
|
|
3268
|
-
id: z.string().uuid(),
|
|
3269
|
-
type: MemoryTypeSchema.optional(),
|
|
3270
|
-
title: z.string().min(3).max(255).optional(),
|
|
3271
|
-
content: z.string().min(10).optional(),
|
|
3272
|
-
importance: z.number().min(1).max(5).optional(),
|
|
3273
|
-
agent: z.string().optional(),
|
|
3274
|
-
role: z.string().optional(),
|
|
3275
|
-
status: z.enum(["active", "archived"]).optional(),
|
|
3276
|
-
supersedes: z.string().uuid().optional(),
|
|
3277
|
-
tags: z.array(z.string()).optional(),
|
|
3278
|
-
metadata: z.record(z.string(), z.any()).optional(),
|
|
3279
|
-
is_global: z.boolean().optional(),
|
|
3280
|
-
completed_at: z.string().optional(),
|
|
3281
|
-
structured: z.boolean().default(false)
|
|
3282
|
-
}).refine(
|
|
3283
|
-
(data) => data.type !== void 0 || data.content !== void 0 || data.title !== void 0 || data.importance !== void 0 || data.status !== void 0 || data.supersedes !== void 0 || data.tags !== void 0 || data.metadata !== void 0 || data.is_global !== void 0 || data.agent !== void 0 || data.role !== void 0 || data.completed_at !== void 0,
|
|
3284
|
-
{ message: "At least one field must be provided for update" }
|
|
3285
|
-
);
|
|
3286
|
-
var MemorySearchSchema = z.object({
|
|
3287
|
-
query: z.string().min(3),
|
|
3288
|
-
prompt: z.string().optional(),
|
|
3289
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3290
|
-
types: z.array(MemoryTypeSchema).optional(),
|
|
3291
|
-
minImportance: z.number().min(1).max(5).optional(),
|
|
3292
|
-
limit: z.number().min(1).max(100).default(5),
|
|
3293
|
-
offset: z.number().min(0).default(0),
|
|
3294
|
-
includeRecap: z.boolean().default(false),
|
|
3295
|
-
current_file_path: z.string().optional(),
|
|
3296
|
-
include_archived: z.boolean().default(false),
|
|
3297
|
-
current_tags: z.array(z.string()).optional(),
|
|
3298
|
-
scope: MemoryScopeSchema.partial().optional(),
|
|
3299
|
-
structured: z.boolean().default(false)
|
|
3300
|
-
});
|
|
3301
|
-
var MemoryAcknowledgeSchema = z.object({
|
|
3302
|
-
memory_id: z.string().uuid(),
|
|
3303
|
-
status: z.enum(["used", "irrelevant", "contradictory"]),
|
|
3304
|
-
application_context: z.string().min(10).optional(),
|
|
3305
|
-
structured: z.boolean().default(false)
|
|
3306
|
-
});
|
|
3307
|
-
var MemoryRecapSchema = z.object({
|
|
3308
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3309
|
-
limit: z.number().min(1).max(50).default(20),
|
|
3310
|
-
offset: z.number().min(0).default(0),
|
|
3311
|
-
structured: z.boolean().default(false)
|
|
3312
|
-
});
|
|
3313
|
-
var MemoryDeleteSchema = z.object({
|
|
3314
|
-
repo: z.string().min(1).transform(normalizeRepo).optional(),
|
|
3315
|
-
id: z.string().uuid().optional(),
|
|
3316
|
-
ids: z.array(z.string().uuid()).min(1).optional(),
|
|
3317
|
-
structured: z.boolean().default(false)
|
|
3318
|
-
}).refine((data) => data.id !== void 0 || data.ids !== void 0, {
|
|
3319
|
-
message: "Either 'id' or 'ids' must be provided for deletion"
|
|
3320
|
-
});
|
|
3321
|
-
var MemorySummarizeSchema = z.object({
|
|
3322
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3323
|
-
signals: z.array(z.string().max(200)).min(1),
|
|
3324
|
-
structured: z.boolean().default(false)
|
|
3325
|
-
});
|
|
3326
|
-
var MemorySynthesizeSchema = z.object({
|
|
3327
|
-
repo: z.string().min(1).transform(normalizeRepo).optional(),
|
|
3328
|
-
objective: z.string().min(5),
|
|
3329
|
-
current_file_path: z.string().optional(),
|
|
3330
|
-
include_summary: z.boolean().default(true),
|
|
3331
|
-
include_tasks: z.boolean().default(true),
|
|
3332
|
-
use_tools: z.boolean().default(true),
|
|
3333
|
-
max_iterations: z.number().int().min(1).max(5).default(3),
|
|
3334
|
-
max_tokens: z.number().int().min(128).max(4e3).default(1200),
|
|
3335
|
-
structured: z.boolean().default(false)
|
|
3336
|
-
});
|
|
3337
|
-
var TaskStatusSchema = z.enum(["backlog", "pending", "in_progress", "completed", "canceled", "blocked"]);
|
|
3338
|
-
var TaskPrioritySchema = z.number().min(1).max(5);
|
|
3339
|
-
var SingleTaskCreateSchema = z.object({
|
|
3340
|
-
task_code: z.string().min(1),
|
|
3341
|
-
phase: z.string().min(1),
|
|
3342
|
-
title: z.string().min(3).max(100),
|
|
3343
|
-
description: z.string().min(1),
|
|
3344
|
-
status: TaskStatusSchema.default("backlog"),
|
|
3345
|
-
priority: TaskPrioritySchema.default(3),
|
|
3346
|
-
agent: z.string().optional(),
|
|
3347
|
-
role: z.string().optional(),
|
|
3348
|
-
doc_path: z.string().optional(),
|
|
3349
|
-
tags: z.array(z.string()).optional(),
|
|
3350
|
-
metadata: z.record(z.string(), z.any()).optional(),
|
|
3351
|
-
parent_id: z.string().uuid().optional(),
|
|
3352
|
-
depends_on: z.string().uuid().optional(),
|
|
3353
|
-
est_tokens: z.number().int().min(0).optional()
|
|
3354
|
-
});
|
|
3355
|
-
var TaskCreateSchema = z.object({
|
|
3356
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3357
|
-
// Allow single task fields at top level (backward compatibility & single use)
|
|
3358
|
-
task_code: z.string().min(1).optional(),
|
|
3359
|
-
phase: z.string().min(1).optional(),
|
|
3360
|
-
title: z.string().min(3).max(100).optional(),
|
|
3361
|
-
description: z.string().min(1).optional(),
|
|
3362
|
-
status: TaskStatusSchema.optional(),
|
|
3363
|
-
priority: TaskPrioritySchema.optional(),
|
|
3364
|
-
agent: z.string().optional(),
|
|
3365
|
-
role: z.string().optional(),
|
|
3366
|
-
doc_path: z.string().optional(),
|
|
3367
|
-
tags: z.array(z.string()).optional(),
|
|
3368
|
-
metadata: z.record(z.string(), z.any()).optional(),
|
|
3369
|
-
parent_id: z.string().uuid().optional(),
|
|
3370
|
-
depends_on: z.string().uuid().optional(),
|
|
3371
|
-
est_tokens: z.number().int().min(0).optional(),
|
|
3372
|
-
// Allow bulk tasks
|
|
3373
|
-
tasks: z.array(SingleTaskCreateSchema).min(1).optional(),
|
|
3374
|
-
structured: z.boolean().default(false)
|
|
3375
|
-
}).refine(
|
|
3376
|
-
(data) => {
|
|
3377
|
-
if (data.tasks) return true;
|
|
3378
|
-
return !!(data.task_code && data.phase && data.title && data.description);
|
|
3379
3355
|
},
|
|
3380
|
-
{ message: "Either 'tasks' array or single task fields (task_code, phase, title, description) must be provided" }
|
|
3381
|
-
);
|
|
3382
|
-
var TaskCreateInteractiveSchema = SingleTaskCreateSchema.partial().extend({
|
|
3383
|
-
repo: z.string().min(1).transform(normalizeRepo).optional(),
|
|
3384
|
-
structured: z.boolean().default(false)
|
|
3385
|
-
});
|
|
3386
|
-
var TaskUpdateSchema = z.object({
|
|
3387
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3388
|
-
id: z.string().uuid().optional(),
|
|
3389
|
-
ids: z.array(z.string().uuid()).min(1).optional(),
|
|
3390
|
-
task_code: z.string().optional(),
|
|
3391
|
-
phase: z.string().optional(),
|
|
3392
|
-
title: z.string().min(3).max(100).optional(),
|
|
3393
|
-
description: z.string().optional(),
|
|
3394
|
-
status: TaskStatusSchema.optional(),
|
|
3395
|
-
priority: TaskPrioritySchema.optional(),
|
|
3396
|
-
agent: z.string().min(1, "agent name is required").optional(),
|
|
3397
|
-
role: z.string().min(1, "agent role is required").optional(),
|
|
3398
|
-
model: z.string().optional(),
|
|
3399
|
-
comment: z.string().min(1).optional(),
|
|
3400
|
-
doc_path: z.string().optional(),
|
|
3401
|
-
tags: z.array(z.string()).optional(),
|
|
3402
|
-
metadata: z.record(z.string(), z.any()).optional(),
|
|
3403
|
-
parent_id: z.string().uuid().optional(),
|
|
3404
|
-
depends_on: z.string().uuid().optional(),
|
|
3405
|
-
est_tokens: z.number().int().min(0).optional(),
|
|
3406
|
-
force: z.boolean().optional(),
|
|
3407
|
-
structured: z.boolean().default(false)
|
|
3408
|
-
}).refine((data) => data.id !== void 0 || data.ids !== void 0 || data.task_code !== void 0, {
|
|
3409
|
-
message: "Either 'id', 'ids', or 'task_code' must be provided for update"
|
|
3410
|
-
}).refine((data) => Object.keys(data).length > 2, {
|
|
3411
|
-
message: "At least one field besides repo and id/ids must be provided for update"
|
|
3412
|
-
});
|
|
3413
|
-
var TaskListSchema = z.object({
|
|
3414
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3415
|
-
status: z.string().optional(),
|
|
3416
|
-
phase: z.string().optional(),
|
|
3417
|
-
query: z.string().optional(),
|
|
3418
|
-
limit: z.number().min(1).max(100).default(15),
|
|
3419
|
-
offset: z.number().min(0).default(0),
|
|
3420
|
-
structured: z.boolean().default(false)
|
|
3421
|
-
});
|
|
3422
|
-
var TaskSearchSchema = z.object({
|
|
3423
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3424
|
-
query: z.string().min(1),
|
|
3425
|
-
status: z.string().optional(),
|
|
3426
|
-
limit: z.number().min(1).max(100).default(10),
|
|
3427
|
-
offset: z.number().min(0).default(0),
|
|
3428
|
-
structured: z.boolean().default(false)
|
|
3429
|
-
});
|
|
3430
|
-
var TaskDeleteSchema = z.object({
|
|
3431
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3432
|
-
id: z.string().uuid().optional(),
|
|
3433
|
-
ids: z.array(z.string().uuid()).min(1).optional(),
|
|
3434
|
-
structured: z.boolean().default(false)
|
|
3435
|
-
}).refine((data) => data.id !== void 0 || data.ids !== void 0, {
|
|
3436
|
-
message: "Either 'id' or 'ids' must be provided for deletion"
|
|
3437
|
-
});
|
|
3438
|
-
var MemoryDetailSchema = z.object({
|
|
3439
|
-
id: z.string().uuid().optional(),
|
|
3440
|
-
code: z.string().max(20).optional(),
|
|
3441
|
-
structured: z.boolean().default(false)
|
|
3442
|
-
}).refine((data) => data.id !== void 0 || data.code !== void 0, {
|
|
3443
|
-
message: "Either id or code must be provided"
|
|
3444
|
-
});
|
|
3445
|
-
var TaskGetSchema = z.object({
|
|
3446
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3447
|
-
id: z.string().uuid().optional(),
|
|
3448
|
-
task_code: z.string().optional(),
|
|
3449
|
-
structured: z.boolean().default(false)
|
|
3450
|
-
}).refine((data) => data.id !== void 0 || data.task_code !== void 0, {
|
|
3451
|
-
message: "Either id or task_code must be provided"
|
|
3452
|
-
});
|
|
3453
|
-
var HandoffStatusSchema = z.enum(["pending", "accepted", "rejected", "expired"]);
|
|
3454
|
-
var HandoffCreateSchema = z.object({
|
|
3455
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3456
|
-
from_agent: z.string().min(1),
|
|
3457
|
-
to_agent: z.string().min(1).optional(),
|
|
3458
|
-
task_id: z.string().uuid().optional(),
|
|
3459
|
-
task_code: z.string().optional(),
|
|
3460
|
-
summary: z.string().min(1),
|
|
3461
|
-
context: z.record(z.string(), z.any()).optional(),
|
|
3462
|
-
expires_at: z.string().optional(),
|
|
3463
|
-
structured: z.boolean().default(false)
|
|
3464
|
-
}).refine((data) => !(data.task_id && data.task_code), {
|
|
3465
|
-
message: "Provide either task_id or task_code, not both"
|
|
3466
|
-
});
|
|
3467
|
-
var HandoffListSchema = z.object({
|
|
3468
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3469
|
-
status: HandoffStatusSchema.optional(),
|
|
3470
|
-
from_agent: z.string().min(1).optional(),
|
|
3471
|
-
to_agent: z.string().min(1).optional(),
|
|
3472
|
-
limit: z.number().min(1).max(100).default(20),
|
|
3473
|
-
offset: z.number().min(0).default(0),
|
|
3474
|
-
structured: z.boolean().default(false)
|
|
3475
|
-
});
|
|
3476
|
-
var TaskClaimSchema = z.object({
|
|
3477
|
-
repo: z.string().min(1).transform(normalizeRepo),
|
|
3478
|
-
task_id: z.string().uuid().optional(),
|
|
3479
|
-
task_code: z.string().optional(),
|
|
3480
|
-
agent: z.string().min(1),
|
|
3481
|
-
role: z.string().optional(),
|
|
3482
|
-
metadata: z.record(z.string(), z.any()).optional(),
|
|
3483
|
-
structured: z.boolean().default(false)
|
|
3484
|
-
}).refine((data) => data.task_id !== void 0 || data.task_code !== void 0, {
|
|
3485
|
-
message: "Either task_id or task_code must be provided"
|
|
3486
|
-
}).refine((data) => !(data.task_id && data.task_code), {
|
|
3487
|
-
message: "Provide either task_id or task_code, not both"
|
|
3488
|
-
});
|
|
3489
|
-
var StandardStoreSchema = z.object({
|
|
3490
|
-
name: z.string().min(3).max(255),
|
|
3491
|
-
content: z.string().min(10),
|
|
3492
|
-
context: z.string().optional(),
|
|
3493
|
-
version: z.string().optional(),
|
|
3494
|
-
language: z.string().optional(),
|
|
3495
|
-
stack: z.array(z.string()).optional(),
|
|
3496
|
-
repo: z.string().optional(),
|
|
3497
|
-
is_global: z.boolean().optional(),
|
|
3498
|
-
tags: z.array(z.string()).optional(),
|
|
3499
|
-
metadata: z.record(z.string(), z.any()).optional(),
|
|
3500
|
-
agent: z.string().optional(),
|
|
3501
|
-
model: z.string().optional(),
|
|
3502
|
-
structured: z.boolean().default(false)
|
|
3503
|
-
});
|
|
3504
|
-
var StandardSearchSchema = z.object({
|
|
3505
|
-
query: z.string().optional(),
|
|
3506
|
-
stack: z.array(z.string()).optional(),
|
|
3507
|
-
language: z.string().optional(),
|
|
3508
|
-
version: z.string().optional(),
|
|
3509
|
-
repo: z.string().optional(),
|
|
3510
|
-
is_global: z.boolean().optional(),
|
|
3511
|
-
limit: z.number().min(1).max(100).default(20),
|
|
3512
|
-
offset: z.number().min(0).default(0),
|
|
3513
|
-
structured: z.boolean().default(false)
|
|
3514
|
-
});
|
|
3515
|
-
var TOOL_DEFINITIONS = [
|
|
3516
3356
|
{
|
|
3517
|
-
name: "memory-
|
|
3518
|
-
title: "Memory
|
|
3519
|
-
description: "
|
|
3357
|
+
name: "memory-summarize",
|
|
3358
|
+
title: "Memory Summarize",
|
|
3359
|
+
description: "Update the summary for a repository",
|
|
3520
3360
|
annotations: {
|
|
3521
|
-
readOnlyHint:
|
|
3522
|
-
idempotentHint:
|
|
3361
|
+
readOnlyHint: false,
|
|
3362
|
+
idempotentHint: false,
|
|
3523
3363
|
openWorldHint: false
|
|
3524
3364
|
},
|
|
3525
|
-
execution: {
|
|
3526
|
-
taskSupport: "optional"
|
|
3527
|
-
},
|
|
3528
3365
|
inputSchema: {
|
|
3529
3366
|
type: "object",
|
|
3530
3367
|
properties: {
|
|
3531
|
-
repo: { type: "string", description: "Repository name
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
type: "string",
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
include_summary: { type: "boolean", default: true },
|
|
3538
|
-
include_tasks: { type: "boolean", default: true },
|
|
3539
|
-
use_tools: {
|
|
3540
|
-
type: "boolean",
|
|
3541
|
-
default: true,
|
|
3542
|
-
description: "Allow the sampled model to call local memory/task tools during synthesis when the client supports sampling.tools."
|
|
3368
|
+
repo: { type: "string", description: "Repository name" },
|
|
3369
|
+
signals: {
|
|
3370
|
+
type: "array",
|
|
3371
|
+
items: { type: "string", maxLength: 200 },
|
|
3372
|
+
minItems: 1,
|
|
3373
|
+
description: "High-level signals to include in summary"
|
|
3543
3374
|
},
|
|
3544
|
-
|
|
3545
|
-
max_tokens: { type: "number", minimum: 128, maximum: 4e3, default: 1200 },
|
|
3546
|
-
structured: { type: "boolean", default: false, description: "If true, returns structured JSON results." }
|
|
3375
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON of the summary." }
|
|
3547
3376
|
},
|
|
3548
|
-
required: ["
|
|
3377
|
+
required: ["repo", "signals"]
|
|
3549
3378
|
},
|
|
3550
3379
|
outputSchema: {
|
|
3551
3380
|
type: "object",
|
|
3552
3381
|
properties: {
|
|
3382
|
+
success: { type: "boolean" },
|
|
3553
3383
|
repo: { type: "string" },
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
model: { type: "string" },
|
|
3557
|
-
stopReason: { type: "string" },
|
|
3558
|
-
iterations: { type: "number" },
|
|
3559
|
-
toolCalls: { type: "number" }
|
|
3384
|
+
summary: { type: "string" },
|
|
3385
|
+
signalCount: { type: "number" }
|
|
3560
3386
|
},
|
|
3561
|
-
required: ["
|
|
3387
|
+
required: ["success", "repo", "summary", "signalCount"]
|
|
3562
3388
|
}
|
|
3563
3389
|
},
|
|
3564
3390
|
{
|
|
3565
|
-
name: "
|
|
3566
|
-
title: "
|
|
3567
|
-
description: "
|
|
3391
|
+
name: "memory-delete",
|
|
3392
|
+
title: "Memory Delete",
|
|
3393
|
+
description: "Soft-delete one or more memory entries. Supports single 'id' or bulk 'ids'.",
|
|
3568
3394
|
annotations: {
|
|
3569
3395
|
readOnlyHint: false,
|
|
3570
3396
|
idempotentHint: false,
|
|
3571
|
-
destructiveHint:
|
|
3397
|
+
destructiveHint: true,
|
|
3572
3398
|
openWorldHint: false
|
|
3573
3399
|
},
|
|
3574
3400
|
inputSchema: {
|
|
3575
3401
|
type: "object",
|
|
3576
3402
|
properties: {
|
|
3577
|
-
repo: {
|
|
3578
|
-
|
|
3579
|
-
|
|
3403
|
+
repo: { type: "string", description: "Repository name (optional for single id)" },
|
|
3404
|
+
id: { type: "string", format: "uuid", description: "Memory entry ID to delete" },
|
|
3405
|
+
ids: {
|
|
3406
|
+
type: "array",
|
|
3407
|
+
items: { type: "string", format: "uuid" },
|
|
3408
|
+
minItems: 1,
|
|
3409
|
+
description: "Array of memory IDs to delete"
|
|
3580
3410
|
},
|
|
3581
|
-
task_code: { type: "string" },
|
|
3582
|
-
phase: { type: "string" },
|
|
3583
|
-
title: { type: "string", minLength: 3, maxLength: 100 },
|
|
3584
|
-
description: { type: "string", minLength: 1 },
|
|
3585
|
-
status: { type: "string", enum: ["backlog", "pending"], default: "backlog" },
|
|
3586
|
-
priority: { type: "number", minimum: 1, maximum: 5, default: 3 },
|
|
3587
|
-
agent: { type: "string" },
|
|
3588
|
-
role: { type: "string" },
|
|
3589
|
-
doc_path: { type: "string" },
|
|
3590
3411
|
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
3591
3412
|
}
|
|
3592
3413
|
},
|
|
3593
3414
|
outputSchema: {
|
|
3594
3415
|
type: "object",
|
|
3595
3416
|
properties: {
|
|
3417
|
+
success: { type: "boolean" },
|
|
3418
|
+
id: { type: "string" },
|
|
3419
|
+
ids: { type: "array", items: { type: "string" } },
|
|
3596
3420
|
repo: { type: "string" },
|
|
3597
|
-
|
|
3598
|
-
phase: { type: "string" },
|
|
3599
|
-
title: { type: "string" },
|
|
3600
|
-
status: { type: "string" },
|
|
3601
|
-
priority: { type: "number" }
|
|
3421
|
+
deletedCount: { type: "number" }
|
|
3602
3422
|
},
|
|
3603
|
-
required: ["
|
|
3604
|
-
}
|
|
3605
|
-
},
|
|
3606
|
-
{
|
|
3607
|
-
name: "memory-detail",
|
|
3608
|
-
title: "Memory Detail",
|
|
3609
|
-
description: "Fetch full details of a specific memory by ID or short code. Use after memory-recap or memory-search when a pointer row is relevant and full content is needed.",
|
|
3610
|
-
inputSchema: {
|
|
3611
|
-
type: "object",
|
|
3612
|
-
properties: {
|
|
3613
|
-
id: { type: "string", format: "uuid", description: "Memory entry ID. Optional if code is provided." },
|
|
3614
|
-
code: { type: "string", description: "Short memory code. Optional if id is provided." },
|
|
3615
|
-
structured: { type: "boolean", default: false, description: "If true, returns structured JSON details." }
|
|
3616
|
-
}
|
|
3423
|
+
required: ["success"]
|
|
3617
3424
|
}
|
|
3618
3425
|
},
|
|
3619
3426
|
{
|
|
3620
|
-
name: "
|
|
3621
|
-
title: "
|
|
3622
|
-
description: "
|
|
3427
|
+
name: "memory-recap",
|
|
3428
|
+
title: "Memory Recap",
|
|
3429
|
+
description: "AGGREGATED OVERVIEW LAYER: Returns stats (counts by type) and a pointer table of top memories [id, code, title, type, importance]. NO content. Use for orientation only \u2014 retrieve full memory via memory-detail.",
|
|
3430
|
+
annotations: {
|
|
3431
|
+
readOnlyHint: true,
|
|
3432
|
+
idempotentHint: true,
|
|
3433
|
+
openWorldHint: false
|
|
3434
|
+
},
|
|
3623
3435
|
inputSchema: {
|
|
3624
3436
|
type: "object",
|
|
3625
3437
|
properties: {
|
|
3626
|
-
repo: { type: "string", description: "Repository name" },
|
|
3627
|
-
|
|
3628
|
-
|
|
3438
|
+
repo: { type: "string", description: "Repository name (required)" },
|
|
3439
|
+
limit: {
|
|
3440
|
+
type: "number",
|
|
3441
|
+
minimum: 1,
|
|
3442
|
+
maximum: 50,
|
|
3443
|
+
default: 20,
|
|
3444
|
+
description: "Maximum number of top memories to return in the pointer table"
|
|
3445
|
+
},
|
|
3446
|
+
offset: {
|
|
3447
|
+
type: "number",
|
|
3448
|
+
minimum: 0,
|
|
3449
|
+
default: 0,
|
|
3450
|
+
description: "Number of memories to skip for pagination (optional, default 0)"
|
|
3451
|
+
},
|
|
3629
3452
|
structured: {
|
|
3630
3453
|
type: "boolean",
|
|
3631
3454
|
default: false,
|
|
3632
|
-
description: "If true, returns structured JSON without the text content
|
|
3455
|
+
description: "If true, returns structured JSON without the text content summary."
|
|
3633
3456
|
}
|
|
3634
3457
|
},
|
|
3635
3458
|
required: ["repo"]
|
|
3459
|
+
},
|
|
3460
|
+
outputSchema: {
|
|
3461
|
+
type: "object",
|
|
3462
|
+
properties: {
|
|
3463
|
+
schema: { type: "string", enum: ["memory-recap"] },
|
|
3464
|
+
repo: { type: "string" },
|
|
3465
|
+
count: { type: "number", description: "Number of rows in the top pointer table" },
|
|
3466
|
+
total: { type: "number", description: "Total active memories in repo" },
|
|
3467
|
+
offset: { type: "number" },
|
|
3468
|
+
limit: { type: "number" },
|
|
3469
|
+
stats: {
|
|
3470
|
+
type: "object",
|
|
3471
|
+
properties: {
|
|
3472
|
+
byType: {
|
|
3473
|
+
type: "object",
|
|
3474
|
+
description: "Count of active memories per type (e.g. { decision: 3, code_fact: 7 })"
|
|
3475
|
+
}
|
|
3476
|
+
},
|
|
3477
|
+
required: ["byType"]
|
|
3478
|
+
},
|
|
3479
|
+
top: {
|
|
3480
|
+
type: "object",
|
|
3481
|
+
properties: {
|
|
3482
|
+
columns: {
|
|
3483
|
+
type: "array",
|
|
3484
|
+
items: { type: "string" },
|
|
3485
|
+
description: "Column names: [id, code, title, type, importance]"
|
|
3486
|
+
},
|
|
3487
|
+
rows: {
|
|
3488
|
+
type: "array",
|
|
3489
|
+
items: { type: "array" },
|
|
3490
|
+
description: "Each row: [id, code, title, type, importance]. Fetch full content via memory-detail"
|
|
3491
|
+
}
|
|
3492
|
+
},
|
|
3493
|
+
required: ["columns", "rows"]
|
|
3494
|
+
}
|
|
3495
|
+
},
|
|
3496
|
+
required: ["schema", "repo", "count", "total", "offset", "limit", "stats", "top"]
|
|
3636
3497
|
}
|
|
3637
3498
|
},
|
|
3638
3499
|
{
|
|
3639
|
-
name: "
|
|
3640
|
-
title: "
|
|
3641
|
-
description: "
|
|
3500
|
+
name: "task-create",
|
|
3501
|
+
title: "Task Create",
|
|
3502
|
+
description: "Register one or more new tasks in a repository. task_code must be unique within the repository. Supports single task object or an array of tasks for bulk creation.",
|
|
3642
3503
|
annotations: {
|
|
3643
3504
|
readOnlyHint: false,
|
|
3644
3505
|
idempotentHint: false,
|
|
3645
|
-
destructiveHint: false,
|
|
3646
3506
|
openWorldHint: false
|
|
3647
3507
|
},
|
|
3648
3508
|
inputSchema: {
|
|
3649
3509
|
type: "object",
|
|
3650
3510
|
properties: {
|
|
3651
|
-
type:
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
"code_fact",
|
|
3655
|
-
"decision",
|
|
3656
|
-
"mistake",
|
|
3657
|
-
"pattern",
|
|
3658
|
-
"file_claim",
|
|
3659
|
-
"task_archive"
|
|
3660
|
-
],
|
|
3661
|
-
description: "Type of memory being stored"
|
|
3662
|
-
},
|
|
3511
|
+
repo: { type: "string", description: "Repository name" },
|
|
3512
|
+
task_code: { type: "string", description: "Unique task code (e.g. TASK-001) (Required for single task)" },
|
|
3513
|
+
phase: { type: "string", description: "Project phase (Required for single task)" },
|
|
3663
3514
|
title: {
|
|
3664
3515
|
type: "string",
|
|
3665
3516
|
minLength: 3,
|
|
3666
3517
|
maxLength: 100,
|
|
3667
|
-
description: "
|
|
3668
|
-
},
|
|
3669
|
-
content: {
|
|
3670
|
-
type: "string",
|
|
3671
|
-
minLength: 10,
|
|
3672
|
-
description: "The memory content"
|
|
3673
|
-
},
|
|
3674
|
-
importance: {
|
|
3675
|
-
type: "number",
|
|
3676
|
-
minimum: 1,
|
|
3677
|
-
maximum: 5,
|
|
3678
|
-
description: "Importance score (1-5)"
|
|
3679
|
-
},
|
|
3680
|
-
agent: {
|
|
3681
|
-
type: "string",
|
|
3682
|
-
description: "Name of the agent creating this memory"
|
|
3683
|
-
},
|
|
3684
|
-
role: {
|
|
3685
|
-
type: "string",
|
|
3686
|
-
description: "Role of the agent creating this memory"
|
|
3518
|
+
description: "Task objective (Required for single task)"
|
|
3687
3519
|
},
|
|
3688
|
-
|
|
3520
|
+
description: { type: "string", description: "Detailed description (Required for single task)" },
|
|
3521
|
+
status: {
|
|
3689
3522
|
type: "string",
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
type: "object",
|
|
3694
|
-
properties: {
|
|
3695
|
-
repo: { type: "string", description: "Repository name" },
|
|
3696
|
-
branch: { type: "string" },
|
|
3697
|
-
folder: { type: "string" },
|
|
3698
|
-
language: { type: "string" }
|
|
3699
|
-
},
|
|
3700
|
-
required: ["repo"]
|
|
3523
|
+
enum: ["backlog", "pending"],
|
|
3524
|
+
default: "backlog",
|
|
3525
|
+
description: "New tasks MUST start in 'backlog' if there are already 10 pending tasks. Otherwise can start in 'pending'."
|
|
3701
3526
|
},
|
|
3702
|
-
|
|
3527
|
+
priority: { type: "number", minimum: 1, maximum: 5, default: 3 },
|
|
3528
|
+
agent: { type: "string" },
|
|
3529
|
+
role: { type: "string" },
|
|
3530
|
+
doc_path: { type: "string" },
|
|
3531
|
+
tags: { type: "array", items: { type: "string" } },
|
|
3532
|
+
metadata: { type: "object" },
|
|
3533
|
+
parent_id: { type: "string", format: "uuid" },
|
|
3534
|
+
depends_on: { type: "string", format: "uuid" },
|
|
3535
|
+
est_tokens: { type: "number", minimum: 0, description: "Estimated tokens budget for this task" },
|
|
3536
|
+
tasks: {
|
|
3703
3537
|
type: "array",
|
|
3704
|
-
items: {
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3538
|
+
items: {
|
|
3539
|
+
type: "object",
|
|
3540
|
+
properties: {
|
|
3541
|
+
task_code: { type: "string" },
|
|
3542
|
+
phase: { type: "string" },
|
|
3543
|
+
title: { type: "string", minLength: 3, maxLength: 100 },
|
|
3544
|
+
description: { type: "string" },
|
|
3545
|
+
status: { type: "string", enum: ["backlog", "pending"], default: "backlog" },
|
|
3546
|
+
priority: { type: "number", minimum: 1, maximum: 5, default: 3 },
|
|
3547
|
+
agent: { type: "string" },
|
|
3548
|
+
role: { type: "string" },
|
|
3549
|
+
doc_path: { type: "string" },
|
|
3550
|
+
tags: { type: "array", items: { type: "string" } },
|
|
3551
|
+
metadata: { type: "object" },
|
|
3552
|
+
parent_id: { type: "string", format: "uuid" },
|
|
3553
|
+
depends_on: { type: "string", format: "uuid" },
|
|
3554
|
+
est_tokens: { type: "number", minimum: 0 }
|
|
3555
|
+
},
|
|
3556
|
+
required: ["task_code", "phase", "title", "description"]
|
|
3557
|
+
},
|
|
3558
|
+
description: "Array of tasks for bulk creation"
|
|
3714
3559
|
},
|
|
3715
|
-
|
|
3716
|
-
supersedes: { type: "string", format: "uuid" },
|
|
3717
|
-
structured: { type: "boolean", default: false, description: "If true, returns structured JSON of the stored memory." }
|
|
3560
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
3718
3561
|
},
|
|
3719
|
-
required: ["
|
|
3562
|
+
required: ["repo"]
|
|
3720
3563
|
},
|
|
3721
3564
|
outputSchema: {
|
|
3722
3565
|
type: "object",
|
|
3723
3566
|
properties: {
|
|
3724
3567
|
success: { type: "boolean" },
|
|
3725
3568
|
id: { type: "string" },
|
|
3726
|
-
|
|
3569
|
+
task_code: { type: "string" },
|
|
3727
3570
|
repo: { type: "string" },
|
|
3728
|
-
|
|
3571
|
+
phase: { type: "string" },
|
|
3729
3572
|
title: { type: "string" },
|
|
3730
|
-
|
|
3731
|
-
|
|
3573
|
+
status: { type: "string" },
|
|
3574
|
+
priority: { type: "number" },
|
|
3575
|
+
createdCount: { type: "number" },
|
|
3576
|
+
taskCodes: { type: "array", items: { type: "string" } }
|
|
3732
3577
|
},
|
|
3733
|
-
required: ["success"]
|
|
3578
|
+
required: ["success", "repo"]
|
|
3734
3579
|
}
|
|
3735
3580
|
},
|
|
3736
3581
|
{
|
|
3737
|
-
name: "
|
|
3738
|
-
title: "
|
|
3739
|
-
description: "
|
|
3582
|
+
name: "task-update",
|
|
3583
|
+
title: "Task Update",
|
|
3584
|
+
description: "Update one or more tasks. Supports single update via 'id' or bulk update via 'ids'. Provide only the fields that need to be changed. MANDATORY WORKFLOW: You cannot move a task from 'pending' or 'blocked' directly to 'completed'. You MUST move it to 'in_progress' first. When changing status to 'completed', include 'est_tokens' with the estimated total tokens actually used for the task.",
|
|
3740
3585
|
annotations: {
|
|
3741
3586
|
readOnlyHint: false,
|
|
3742
3587
|
idempotentHint: false,
|
|
@@ -3745,81 +3590,98 @@ var TOOL_DEFINITIONS = [
|
|
|
3745
3590
|
inputSchema: {
|
|
3746
3591
|
type: "object",
|
|
3747
3592
|
properties: {
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3593
|
+
repo: { type: "string", description: "Repository name" },
|
|
3594
|
+
id: { type: "string", format: "uuid", description: "Task ID (for single update)" },
|
|
3595
|
+
ids: { type: "array", items: { type: "string", format: "uuid" }, description: "Task IDs (for bulk update)" },
|
|
3596
|
+
task_code: { type: "string" },
|
|
3597
|
+
phase: { type: "string" },
|
|
3598
|
+
title: { type: "string", minLength: 3, maxLength: 100 },
|
|
3599
|
+
description: { type: "string" },
|
|
3600
|
+
status: {
|
|
3601
|
+
type: "string",
|
|
3602
|
+
enum: ["backlog", "pending", "in_progress", "completed", "canceled", "blocked"],
|
|
3603
|
+
description: "New status. Transitions from 'backlog', 'pending' or 'blocked' to 'completed' are NOT allowed."
|
|
3604
|
+
},
|
|
3605
|
+
priority: { type: "number", minimum: 1, maximum: 5 },
|
|
3606
|
+
agent: { type: "string" },
|
|
3607
|
+
role: { type: "string" },
|
|
3608
|
+
model: { type: "string" },
|
|
3609
|
+
comment: {
|
|
3610
|
+
type: "string",
|
|
3611
|
+
description: "REQUIRED when changing task status. Explain WHY the status is changing (e.g., 'Starting implementation', 'Blocked by missing API docs', 'Verified fix')."
|
|
3612
|
+
},
|
|
3613
|
+
doc_path: { type: "string" },
|
|
3614
|
+
tags: { type: "array", items: { type: "string" } },
|
|
3615
|
+
metadata: { type: "object" },
|
|
3616
|
+
parent_id: { type: "string", format: "uuid" },
|
|
3617
|
+
depends_on: { type: "string", format: "uuid" },
|
|
3618
|
+
est_tokens: {
|
|
3619
|
+
type: "number",
|
|
3620
|
+
minimum: 0,
|
|
3621
|
+
description: "Estimated total tokens actually used for this task. Required when status changes to 'completed'."
|
|
3622
|
+
},
|
|
3623
|
+
force: {
|
|
3624
|
+
type: "boolean",
|
|
3625
|
+
description: "If true, bypasses status transition validation (e.g. pending -> completed)."
|
|
3626
|
+
},
|
|
3751
3627
|
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
3752
3628
|
},
|
|
3753
|
-
required: ["
|
|
3629
|
+
required: ["repo"]
|
|
3754
3630
|
},
|
|
3755
3631
|
outputSchema: {
|
|
3756
3632
|
type: "object",
|
|
3757
3633
|
properties: {
|
|
3758
3634
|
success: { type: "boolean" },
|
|
3759
3635
|
id: { type: "string" },
|
|
3760
|
-
|
|
3636
|
+
ids: { type: "array", items: { type: "string" } },
|
|
3637
|
+
repo: { type: "string" },
|
|
3638
|
+
status: { type: "string" },
|
|
3639
|
+
archivedToMemory: { type: "boolean" },
|
|
3640
|
+
updatedFields: {
|
|
3641
|
+
type: "array",
|
|
3642
|
+
items: { type: "string" }
|
|
3643
|
+
},
|
|
3644
|
+
updatedCount: { type: "number" }
|
|
3761
3645
|
},
|
|
3762
|
-
required: ["success", "
|
|
3646
|
+
required: ["success", "repo"]
|
|
3763
3647
|
}
|
|
3764
3648
|
},
|
|
3765
3649
|
{
|
|
3766
|
-
name: "
|
|
3767
|
-
title: "
|
|
3768
|
-
description: "
|
|
3650
|
+
name: "task-delete",
|
|
3651
|
+
title: "Task Delete",
|
|
3652
|
+
description: "Delete one or more tasks from a repository. Supports single 'id' or bulk 'ids'.",
|
|
3769
3653
|
annotations: {
|
|
3770
3654
|
readOnlyHint: false,
|
|
3771
3655
|
idempotentHint: false,
|
|
3772
|
-
destructiveHint:
|
|
3656
|
+
destructiveHint: true,
|
|
3773
3657
|
openWorldHint: false
|
|
3774
3658
|
},
|
|
3775
3659
|
inputSchema: {
|
|
3776
3660
|
type: "object",
|
|
3777
3661
|
properties: {
|
|
3778
|
-
|
|
3779
|
-
type:
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
"code_fact",
|
|
3783
|
-
"decision",
|
|
3784
|
-
"mistake",
|
|
3785
|
-
"pattern",
|
|
3786
|
-
"file_claim",
|
|
3787
|
-
"task_archive"
|
|
3788
|
-
]
|
|
3789
|
-
},
|
|
3790
|
-
title: { type: "string", minLength: 3, maxLength: 100 },
|
|
3791
|
-
content: { type: "string", minLength: 10 },
|
|
3792
|
-
importance: { type: "number", minimum: 1, maximum: 5 },
|
|
3793
|
-
agent: { type: "string" },
|
|
3794
|
-
role: { type: "string" },
|
|
3795
|
-
status: { type: "string", enum: ["active", "archived"] },
|
|
3796
|
-
supersedes: { type: "string", format: "uuid" },
|
|
3797
|
-
tags: { type: "array", items: { type: "string" } },
|
|
3798
|
-
metadata: { type: "object" },
|
|
3799
|
-
is_global: { type: "boolean" },
|
|
3800
|
-
completed_at: { type: "string" },
|
|
3801
|
-
structured: { type: "boolean", default: false, description: "If true, returns structured JSON of the updated memory." }
|
|
3662
|
+
repo: { type: "string", description: "Repository name" },
|
|
3663
|
+
id: { type: "string", format: "uuid", description: "Task ID (for single deletion)" },
|
|
3664
|
+
ids: { type: "array", items: { type: "string", format: "uuid" }, description: "Task IDs (for bulk deletion)" },
|
|
3665
|
+
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
3802
3666
|
},
|
|
3803
|
-
required: ["
|
|
3667
|
+
required: ["repo"]
|
|
3804
3668
|
},
|
|
3805
3669
|
outputSchema: {
|
|
3806
3670
|
type: "object",
|
|
3807
3671
|
properties: {
|
|
3808
3672
|
success: { type: "boolean" },
|
|
3809
3673
|
id: { type: "string" },
|
|
3674
|
+
ids: { type: "array", items: { type: "string" } },
|
|
3810
3675
|
repo: { type: "string" },
|
|
3811
|
-
|
|
3812
|
-
type: "array",
|
|
3813
|
-
items: { type: "string" }
|
|
3814
|
-
}
|
|
3676
|
+
deletedCount: { type: "number" }
|
|
3815
3677
|
},
|
|
3816
|
-
required: ["success", "
|
|
3678
|
+
required: ["success", "repo"]
|
|
3817
3679
|
}
|
|
3818
3680
|
},
|
|
3819
3681
|
{
|
|
3820
|
-
name: "
|
|
3821
|
-
title: "
|
|
3822
|
-
description: "
|
|
3682
|
+
name: "task-list",
|
|
3683
|
+
title: "Task List",
|
|
3684
|
+
description: "PRIMARY navigation and search tool for tasks. Returns a compact tabular list of tasks (id, task_code, title, status, priority, updated_at, comments_count). Defaults to in_progress and pending tasks. Use 'query' to filter by code, title, or description. Use 'status' (comma-separated) for specific filters. AGENTS: call this once at start, pick ONE task, then call task-detail.",
|
|
3823
3685
|
annotations: {
|
|
3824
3686
|
readOnlyHint: true,
|
|
3825
3687
|
idempotentHint: true,
|
|
@@ -3828,42 +3690,35 @@ var TOOL_DEFINITIONS = [
|
|
|
3828
3690
|
inputSchema: {
|
|
3829
3691
|
type: "object",
|
|
3830
3692
|
properties: {
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
current_tags: {
|
|
3835
|
-
type: "array",
|
|
3836
|
-
items: { type: "string" },
|
|
3837
|
-
description: "Active tech stack tags (e.g., ['filament', 'react'])"
|
|
3693
|
+
repo: {
|
|
3694
|
+
type: "string",
|
|
3695
|
+
description: "Repository name"
|
|
3838
3696
|
},
|
|
3839
|
-
|
|
3840
|
-
type: "
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
enum: [
|
|
3844
|
-
"code_fact",
|
|
3845
|
-
"decision",
|
|
3846
|
-
"mistake",
|
|
3847
|
-
"pattern",
|
|
3848
|
-
"file_claim",
|
|
3849
|
-
"task_archive"
|
|
3850
|
-
]
|
|
3851
|
-
}
|
|
3697
|
+
status: {
|
|
3698
|
+
type: "string",
|
|
3699
|
+
default: "in_progress,pending",
|
|
3700
|
+
description: "Comma-separated status filter (backlog, pending, in_progress, completed, canceled, blocked). Defaults to 'in_progress,pending'."
|
|
3852
3701
|
},
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3702
|
+
phase: {
|
|
3703
|
+
type: "string",
|
|
3704
|
+
description: "Filter by phase (e.g., 'research', 'implementation')"
|
|
3705
|
+
},
|
|
3706
|
+
query: {
|
|
3707
|
+
type: "string",
|
|
3708
|
+
description: "Search keyword matching task code, title, or description"
|
|
3709
|
+
},
|
|
3710
|
+
limit: {
|
|
3711
|
+
type: "number",
|
|
3712
|
+
minimum: 1,
|
|
3713
|
+
maximum: 100,
|
|
3714
|
+
default: 5,
|
|
3715
|
+
description: "Maximum rows to return (default 5)"
|
|
3716
|
+
},
|
|
3717
|
+
offset: {
|
|
3718
|
+
type: "number",
|
|
3719
|
+
minimum: 0,
|
|
3720
|
+
default: 0,
|
|
3721
|
+
description: "Offset for pagination"
|
|
3867
3722
|
},
|
|
3868
3723
|
structured: {
|
|
3869
3724
|
type: "boolean",
|
|
@@ -3871,111 +3726,113 @@ var TOOL_DEFINITIONS = [
|
|
|
3871
3726
|
description: "If true, returns structured JSON without the text content summary."
|
|
3872
3727
|
}
|
|
3873
3728
|
},
|
|
3874
|
-
required: ["
|
|
3729
|
+
required: ["repo"]
|
|
3875
3730
|
},
|
|
3876
3731
|
outputSchema: {
|
|
3877
3732
|
type: "object",
|
|
3878
3733
|
properties: {
|
|
3879
|
-
schema: { type: "string", enum: ["
|
|
3880
|
-
|
|
3881
|
-
count: { type: "number", description: "Number of rows returned" },
|
|
3882
|
-
total: { type: "number", description: "Total matching memories" },
|
|
3883
|
-
offset: { type: "number" },
|
|
3884
|
-
limit: { type: "number" },
|
|
3885
|
-
results: {
|
|
3734
|
+
schema: { type: "string", enum: ["task-list"] },
|
|
3735
|
+
tasks: {
|
|
3886
3736
|
type: "object",
|
|
3887
3737
|
properties: {
|
|
3888
3738
|
columns: {
|
|
3889
3739
|
type: "array",
|
|
3890
3740
|
items: { type: "string" },
|
|
3891
|
-
description: "Column names:
|
|
3741
|
+
description: "Column names in order: id, task_code, title, status, priority, updated_at, comments_count"
|
|
3892
3742
|
},
|
|
3893
3743
|
rows: {
|
|
3894
3744
|
type: "array",
|
|
3895
3745
|
items: { type: "array" },
|
|
3896
|
-
description: "Each row: [id, title,
|
|
3746
|
+
description: "Each row: [id, task_code, title, status, priority, updated_at, comments_count]. Use task-detail to fetch full task."
|
|
3897
3747
|
}
|
|
3898
3748
|
},
|
|
3899
3749
|
required: ["columns", "rows"]
|
|
3900
|
-
}
|
|
3750
|
+
},
|
|
3751
|
+
count: { type: "number" },
|
|
3752
|
+
offset: { type: "number" }
|
|
3901
3753
|
},
|
|
3902
|
-
required: ["schema", "
|
|
3754
|
+
required: ["schema", "tasks", "count"]
|
|
3903
3755
|
}
|
|
3904
3756
|
},
|
|
3905
3757
|
{
|
|
3906
|
-
name: "
|
|
3907
|
-
title: "
|
|
3908
|
-
description: "
|
|
3758
|
+
name: "handoff-create",
|
|
3759
|
+
title: "Handoff Create",
|
|
3760
|
+
description: "Create a pending handoff only when unfinished work needs context transfer between agents. Do not use this for completed-work summaries, release notes, validation notes, or archives; put those on task-update/task comments or durable memory.",
|
|
3909
3761
|
annotations: {
|
|
3910
3762
|
readOnlyHint: false,
|
|
3911
3763
|
idempotentHint: false,
|
|
3764
|
+
destructiveHint: false,
|
|
3912
3765
|
openWorldHint: false
|
|
3913
3766
|
},
|
|
3914
3767
|
inputSchema: {
|
|
3915
3768
|
type: "object",
|
|
3916
3769
|
properties: {
|
|
3917
3770
|
repo: { type: "string", description: "Repository name" },
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3771
|
+
from_agent: { type: "string", description: "Agent creating the handoff" },
|
|
3772
|
+
to_agent: { type: "string", description: "Optional target agent" },
|
|
3773
|
+
task_id: { type: "string", format: "uuid", description: "Optional task id to associate" },
|
|
3774
|
+
task_code: { type: "string", description: "Optional task code to associate" },
|
|
3775
|
+
summary: { type: "string", minLength: 1, description: "Concise human-readable transfer summary" },
|
|
3776
|
+
context: {
|
|
3777
|
+
type: "object",
|
|
3778
|
+
description: "Structured handoff context. Include next_steps, blockers, or remaining_work unless a target agent or task is provided."
|
|
3923
3779
|
},
|
|
3924
|
-
|
|
3780
|
+
expires_at: { type: "string", description: "Optional expiration timestamp" },
|
|
3781
|
+
structured: { type: "boolean", default: false }
|
|
3925
3782
|
},
|
|
3926
|
-
required: ["repo", "
|
|
3783
|
+
required: ["repo", "from_agent", "summary"]
|
|
3927
3784
|
},
|
|
3928
3785
|
outputSchema: {
|
|
3929
3786
|
type: "object",
|
|
3930
3787
|
properties: {
|
|
3931
|
-
|
|
3788
|
+
id: { type: "string" },
|
|
3932
3789
|
repo: { type: "string" },
|
|
3790
|
+
from_agent: { type: "string" },
|
|
3791
|
+
to_agent: { type: "string", nullable: true },
|
|
3792
|
+
task_id: { type: "string", nullable: true },
|
|
3933
3793
|
summary: { type: "string" },
|
|
3934
|
-
|
|
3794
|
+
context: { type: "object" },
|
|
3795
|
+
status: { type: "string", enum: ["pending", "accepted", "rejected", "expired"] },
|
|
3796
|
+
created_at: { type: "string" },
|
|
3797
|
+
updated_at: { type: "string" },
|
|
3798
|
+
expires_at: { type: "string", nullable: true }
|
|
3935
3799
|
},
|
|
3936
|
-
required: ["
|
|
3800
|
+
required: ["id", "repo", "from_agent", "summary", "context", "status", "created_at", "updated_at"]
|
|
3937
3801
|
}
|
|
3938
3802
|
},
|
|
3939
3803
|
{
|
|
3940
|
-
name: "
|
|
3941
|
-
title: "
|
|
3942
|
-
description: "
|
|
3804
|
+
name: "handoff-update",
|
|
3805
|
+
title: "Handoff Update",
|
|
3806
|
+
description: "Close or reclassify a handoff after it has been consumed or found stale. Use accepted when transfer context was consumed, rejected when intentionally declined, and expired when the handoff is obsolete or only described completed work.",
|
|
3943
3807
|
annotations: {
|
|
3944
3808
|
readOnlyHint: false,
|
|
3945
3809
|
idempotentHint: false,
|
|
3946
|
-
destructiveHint:
|
|
3810
|
+
destructiveHint: false,
|
|
3947
3811
|
openWorldHint: false
|
|
3948
3812
|
},
|
|
3949
3813
|
inputSchema: {
|
|
3950
3814
|
type: "object",
|
|
3951
3815
|
properties: {
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
minItems: 1,
|
|
3958
|
-
description: "Array of memory IDs to delete"
|
|
3959
|
-
},
|
|
3960
|
-
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
3961
|
-
}
|
|
3816
|
+
id: { type: "string", format: "uuid", description: "Handoff ID" },
|
|
3817
|
+
status: { type: "string", enum: ["pending", "accepted", "rejected", "expired"] },
|
|
3818
|
+
structured: { type: "boolean", default: false }
|
|
3819
|
+
},
|
|
3820
|
+
required: ["id", "status"]
|
|
3962
3821
|
},
|
|
3963
3822
|
outputSchema: {
|
|
3964
3823
|
type: "object",
|
|
3965
3824
|
properties: {
|
|
3966
3825
|
success: { type: "boolean" },
|
|
3967
3826
|
id: { type: "string" },
|
|
3968
|
-
|
|
3969
|
-
repo: { type: "string" },
|
|
3970
|
-
deletedCount: { type: "number" }
|
|
3827
|
+
status: { type: "string", enum: ["pending", "accepted", "rejected", "expired"] }
|
|
3971
3828
|
},
|
|
3972
|
-
required: ["success"]
|
|
3829
|
+
required: ["success", "id", "status"]
|
|
3973
3830
|
}
|
|
3974
3831
|
},
|
|
3975
3832
|
{
|
|
3976
|
-
name: "
|
|
3977
|
-
title: "
|
|
3978
|
-
description: "
|
|
3833
|
+
name: "handoff-list",
|
|
3834
|
+
title: "Handoff List",
|
|
3835
|
+
description: "Navigation layer for handoff queues. List repository handoffs with optional status and agent filters, then inspect selected rows before acting.",
|
|
3979
3836
|
annotations: {
|
|
3980
3837
|
readOnlyHint: true,
|
|
3981
3838
|
idempotentHint: true,
|
|
@@ -3984,253 +3841,169 @@ var TOOL_DEFINITIONS = [
|
|
|
3984
3841
|
inputSchema: {
|
|
3985
3842
|
type: "object",
|
|
3986
3843
|
properties: {
|
|
3987
|
-
repo: { type: "string", description: "Repository name
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
},
|
|
3995
|
-
offset: {
|
|
3996
|
-
type: "number",
|
|
3997
|
-
minimum: 0,
|
|
3998
|
-
default: 0,
|
|
3999
|
-
description: "Number of memories to skip for pagination (optional, default 0)"
|
|
4000
|
-
},
|
|
4001
|
-
structured: {
|
|
4002
|
-
type: "boolean",
|
|
4003
|
-
default: false,
|
|
4004
|
-
description: "If true, returns structured JSON without the text content summary."
|
|
4005
|
-
}
|
|
3844
|
+
repo: { type: "string", description: "Repository name" },
|
|
3845
|
+
status: { type: "string", enum: ["pending", "accepted", "rejected", "expired"] },
|
|
3846
|
+
from_agent: { type: "string" },
|
|
3847
|
+
to_agent: { type: "string" },
|
|
3848
|
+
limit: { type: "number", minimum: 1, maximum: 100, default: 20 },
|
|
3849
|
+
offset: { type: "number", minimum: 0, default: 0 },
|
|
3850
|
+
structured: { type: "boolean", default: false }
|
|
4006
3851
|
},
|
|
4007
3852
|
required: ["repo"]
|
|
4008
3853
|
},
|
|
4009
3854
|
outputSchema: {
|
|
4010
3855
|
type: "object",
|
|
4011
3856
|
properties: {
|
|
4012
|
-
schema: { type: "string", enum: ["
|
|
4013
|
-
|
|
4014
|
-
count: { type: "number", description: "Number of rows in the top pointer table" },
|
|
4015
|
-
total: { type: "number", description: "Total active memories in repo" },
|
|
4016
|
-
offset: { type: "number" },
|
|
4017
|
-
limit: { type: "number" },
|
|
4018
|
-
stats: {
|
|
4019
|
-
type: "object",
|
|
4020
|
-
properties: {
|
|
4021
|
-
byType: {
|
|
4022
|
-
type: "object",
|
|
4023
|
-
description: "Count of active memories per type (e.g. { decision: 3, code_fact: 7 })"
|
|
4024
|
-
}
|
|
4025
|
-
},
|
|
4026
|
-
required: ["byType"]
|
|
4027
|
-
},
|
|
4028
|
-
top: {
|
|
3857
|
+
schema: { type: "string", enum: ["handoff-list"] },
|
|
3858
|
+
handoffs: {
|
|
4029
3859
|
type: "object",
|
|
4030
3860
|
properties: {
|
|
4031
3861
|
columns: {
|
|
4032
3862
|
type: "array",
|
|
4033
3863
|
items: { type: "string" },
|
|
4034
|
-
description: "Column names: [id,
|
|
3864
|
+
description: "Column names: [id, from_agent, to_agent, task_id, status, created_at, summary]"
|
|
4035
3865
|
},
|
|
4036
3866
|
rows: {
|
|
4037
3867
|
type: "array",
|
|
4038
3868
|
items: { type: "array" },
|
|
4039
|
-
description: "Each row: [id,
|
|
3869
|
+
description: "Each row: [id, from_agent, to_agent, task_id, status, created_at, summary]"
|
|
4040
3870
|
}
|
|
4041
3871
|
},
|
|
4042
3872
|
required: ["columns", "rows"]
|
|
4043
|
-
}
|
|
3873
|
+
},
|
|
3874
|
+
count: { type: "number" },
|
|
3875
|
+
offset: { type: "number" }
|
|
4044
3876
|
},
|
|
4045
|
-
required: ["schema", "
|
|
3877
|
+
required: ["schema", "handoffs", "count", "offset"]
|
|
4046
3878
|
}
|
|
4047
3879
|
},
|
|
4048
3880
|
{
|
|
4049
|
-
name: "task-
|
|
4050
|
-
title: "Task
|
|
4051
|
-
description: "
|
|
3881
|
+
name: "task-claim",
|
|
3882
|
+
title: "Task Claim",
|
|
3883
|
+
description: "Claim task ownership for an agent using the dedicated claims table. Use this before taking work from task-list; provide either task_id or task_code.",
|
|
4052
3884
|
annotations: {
|
|
4053
3885
|
readOnlyHint: false,
|
|
4054
3886
|
idempotentHint: false,
|
|
3887
|
+
destructiveHint: false,
|
|
4055
3888
|
openWorldHint: false
|
|
4056
3889
|
},
|
|
4057
3890
|
inputSchema: {
|
|
4058
3891
|
type: "object",
|
|
4059
3892
|
properties: {
|
|
4060
3893
|
repo: { type: "string", description: "Repository name" },
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
description: "Task objective (Required for single task)"
|
|
4068
|
-
},
|
|
4069
|
-
description: { type: "string", description: "Detailed description (Required for single task)" },
|
|
4070
|
-
status: {
|
|
4071
|
-
type: "string",
|
|
4072
|
-
enum: ["backlog", "pending"],
|
|
4073
|
-
default: "backlog",
|
|
4074
|
-
description: "New tasks MUST start in 'backlog' if there are already 10 pending tasks. Otherwise can start in 'pending'."
|
|
4075
|
-
},
|
|
4076
|
-
priority: { type: "number", minimum: 1, maximum: 5, default: 3 },
|
|
4077
|
-
agent: { type: "string" },
|
|
4078
|
-
role: { type: "string" },
|
|
4079
|
-
doc_path: { type: "string" },
|
|
4080
|
-
tags: { type: "array", items: { type: "string" } },
|
|
4081
|
-
metadata: { type: "object" },
|
|
4082
|
-
parent_id: { type: "string", format: "uuid" },
|
|
4083
|
-
depends_on: { type: "string", format: "uuid" },
|
|
4084
|
-
est_tokens: { type: "number", minimum: 0, description: "Estimated tokens budget for this task" },
|
|
4085
|
-
tasks: {
|
|
4086
|
-
type: "array",
|
|
4087
|
-
items: {
|
|
4088
|
-
type: "object",
|
|
4089
|
-
properties: {
|
|
4090
|
-
task_code: { type: "string" },
|
|
4091
|
-
phase: { type: "string" },
|
|
4092
|
-
title: { type: "string", minLength: 3, maxLength: 100 },
|
|
4093
|
-
description: { type: "string" },
|
|
4094
|
-
status: { type: "string", enum: ["backlog", "pending"], default: "backlog" },
|
|
4095
|
-
priority: { type: "number", minimum: 1, maximum: 5, default: 3 },
|
|
4096
|
-
agent: { type: "string" },
|
|
4097
|
-
role: { type: "string" },
|
|
4098
|
-
doc_path: { type: "string" },
|
|
4099
|
-
tags: { type: "array", items: { type: "string" } },
|
|
4100
|
-
metadata: { type: "object" },
|
|
4101
|
-
parent_id: { type: "string", format: "uuid" },
|
|
4102
|
-
depends_on: { type: "string", format: "uuid" },
|
|
4103
|
-
est_tokens: { type: "number", minimum: 0 }
|
|
4104
|
-
},
|
|
4105
|
-
required: ["task_code", "phase", "title", "description"]
|
|
4106
|
-
},
|
|
4107
|
-
description: "Array of tasks for bulk creation"
|
|
4108
|
-
},
|
|
4109
|
-
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
3894
|
+
task_id: { type: "string", format: "uuid", description: "Task id to claim. Optional if task_code is provided." },
|
|
3895
|
+
task_code: { type: "string", description: "Task code to claim. Optional if task_id is provided." },
|
|
3896
|
+
agent: { type: "string", description: "Claiming agent name" },
|
|
3897
|
+
role: { type: "string", description: "Claiming agent role" },
|
|
3898
|
+
metadata: { type: "object", description: "Optional claim metadata" },
|
|
3899
|
+
structured: { type: "boolean", default: false }
|
|
4110
3900
|
},
|
|
4111
|
-
required: ["repo"]
|
|
3901
|
+
required: ["repo", "agent"]
|
|
4112
3902
|
},
|
|
4113
3903
|
outputSchema: {
|
|
4114
3904
|
type: "object",
|
|
4115
3905
|
properties: {
|
|
4116
|
-
success: { type: "boolean" },
|
|
4117
3906
|
id: { type: "string" },
|
|
4118
|
-
task_code: { type: "string" },
|
|
4119
3907
|
repo: { type: "string" },
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
3908
|
+
task_id: { type: "string" },
|
|
3909
|
+
task_code: { type: "string", nullable: true },
|
|
3910
|
+
agent: { type: "string" },
|
|
3911
|
+
role: { type: "string" },
|
|
3912
|
+
claimed_at: { type: "string" },
|
|
3913
|
+
released_at: { type: "string", nullable: true },
|
|
3914
|
+
metadata: { type: "object" }
|
|
4126
3915
|
},
|
|
4127
|
-
required: ["
|
|
3916
|
+
required: ["id", "repo", "task_id", "agent", "role", "claimed_at", "metadata"]
|
|
4128
3917
|
}
|
|
4129
3918
|
},
|
|
4130
3919
|
{
|
|
4131
|
-
name: "
|
|
4132
|
-
title: "
|
|
4133
|
-
description: "
|
|
3920
|
+
name: "standard-store",
|
|
3921
|
+
title: "Standard Store",
|
|
3922
|
+
description: "Store one atomic coding standard. Use for durable implementation rules with explicit context, stack/language filters, and repo/global scope.",
|
|
4134
3923
|
annotations: {
|
|
4135
3924
|
readOnlyHint: false,
|
|
4136
3925
|
idempotentHint: false,
|
|
3926
|
+
destructiveHint: false,
|
|
4137
3927
|
openWorldHint: false
|
|
4138
3928
|
},
|
|
4139
3929
|
inputSchema: {
|
|
4140
3930
|
type: "object",
|
|
4141
3931
|
properties: {
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
enum: ["backlog", "pending", "in_progress", "completed", "canceled", "blocked"],
|
|
4152
|
-
description: "New status. Transitions from 'backlog', 'pending' or 'blocked' to 'completed' are NOT allowed."
|
|
4153
|
-
},
|
|
4154
|
-
priority: { type: "number", minimum: 1, maximum: 5 },
|
|
4155
|
-
agent: { type: "string" },
|
|
4156
|
-
role: { type: "string" },
|
|
4157
|
-
model: { type: "string" },
|
|
4158
|
-
comment: {
|
|
4159
|
-
type: "string",
|
|
4160
|
-
description: "REQUIRED when changing task status. Explain WHY the status is changing (e.g., 'Starting implementation', 'Blocked by missing API docs', 'Verified fix')."
|
|
4161
|
-
},
|
|
4162
|
-
doc_path: { type: "string" },
|
|
4163
|
-
tags: { type: "array", items: { type: "string" } },
|
|
4164
|
-
metadata: { type: "object" },
|
|
4165
|
-
parent_id: { type: "string", format: "uuid" },
|
|
4166
|
-
depends_on: { type: "string", format: "uuid" },
|
|
4167
|
-
est_tokens: {
|
|
4168
|
-
type: "number",
|
|
4169
|
-
minimum: 0,
|
|
4170
|
-
description: "Estimated total tokens actually used for this task. Required when status changes to 'completed'."
|
|
4171
|
-
},
|
|
4172
|
-
force: {
|
|
4173
|
-
type: "boolean",
|
|
4174
|
-
description: "If true, bypasses status transition validation (e.g. pending -> completed)."
|
|
3932
|
+
name: { type: "string", minLength: 3, maxLength: 255, description: "Human-readable standard name" },
|
|
3933
|
+
content: { type: "string", minLength: 10, description: "One atomic, actionable standard written as concise Markdown" },
|
|
3934
|
+
context: { type: "string", description: "Context or category (e.g., 'error-handling', 'security')" },
|
|
3935
|
+
version: { type: "string", description: "Version of the standard (e.g., '1.0.0')" },
|
|
3936
|
+
language: { type: "string", description: "Programming language (e.g., 'typescript', 'python')" },
|
|
3937
|
+
stack: {
|
|
3938
|
+
type: "array",
|
|
3939
|
+
items: { type: "string" },
|
|
3940
|
+
description: "Technology stack (e.g., ['react', 'nextjs'])"
|
|
4175
3941
|
},
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
},
|
|
4180
|
-
outputSchema: {
|
|
4181
|
-
type: "object",
|
|
4182
|
-
properties: {
|
|
4183
|
-
success: { type: "boolean" },
|
|
4184
|
-
id: { type: "string" },
|
|
4185
|
-
ids: { type: "array", items: { type: "string" } },
|
|
4186
|
-
repo: { type: "string" },
|
|
4187
|
-
status: { type: "string" },
|
|
4188
|
-
archivedToMemory: { type: "boolean" },
|
|
4189
|
-
updatedFields: {
|
|
3942
|
+
repo: { type: "string", description: "Repository name for repo-specific standards. Omit only for global standards." },
|
|
3943
|
+
is_global: { type: "boolean", description: "Whether standard applies globally or repo-specific" },
|
|
3944
|
+
tags: {
|
|
4190
3945
|
type: "array",
|
|
4191
|
-
items: { type: "string" }
|
|
3946
|
+
items: { type: "string" },
|
|
3947
|
+
description: "Tags for categorization"
|
|
4192
3948
|
},
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
title: "Task Delete",
|
|
4201
|
-
description: "Delete one or more tasks from a repository. Supports single 'id' or bulk 'ids'.",
|
|
4202
|
-
annotations: {
|
|
4203
|
-
readOnlyHint: false,
|
|
4204
|
-
idempotentHint: false,
|
|
4205
|
-
destructiveHint: true,
|
|
4206
|
-
openWorldHint: false
|
|
4207
|
-
},
|
|
4208
|
-
inputSchema: {
|
|
4209
|
-
type: "object",
|
|
4210
|
-
properties: {
|
|
4211
|
-
repo: { type: "string", description: "Repository name" },
|
|
4212
|
-
id: { type: "string", format: "uuid", description: "Task ID (for single deletion)" },
|
|
4213
|
-
ids: { type: "array", items: { type: "string", format: "uuid" }, description: "Task IDs (for bulk deletion)" },
|
|
4214
|
-
structured: { type: "boolean", default: false, description: "If true, returns structured JSON result." }
|
|
3949
|
+
metadata: {
|
|
3950
|
+
type: "object",
|
|
3951
|
+
description: "Additional metadata"
|
|
3952
|
+
},
|
|
3953
|
+
agent: { type: "string", description: "Agent creating the standard" },
|
|
3954
|
+
model: { type: "string", description: "AI model used" },
|
|
3955
|
+
structured: { type: "boolean", default: false }
|
|
4215
3956
|
},
|
|
4216
|
-
required: ["
|
|
3957
|
+
required: ["name", "content"]
|
|
4217
3958
|
},
|
|
4218
3959
|
outputSchema: {
|
|
4219
3960
|
type: "object",
|
|
4220
3961
|
properties: {
|
|
4221
3962
|
success: { type: "boolean" },
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
3963
|
+
standard: {
|
|
3964
|
+
type: "object",
|
|
3965
|
+
properties: {
|
|
3966
|
+
id: { type: "string" },
|
|
3967
|
+
title: { type: "string" },
|
|
3968
|
+
content: { type: "string" },
|
|
3969
|
+
context: { type: "string" },
|
|
3970
|
+
version: { type: "string" },
|
|
3971
|
+
language: { type: "string", nullable: true },
|
|
3972
|
+
stack: { type: "array", items: { type: "string" } },
|
|
3973
|
+
is_global: { type: "boolean" },
|
|
3974
|
+
repo: { type: "string", nullable: true },
|
|
3975
|
+
tags: { type: "array", items: { type: "string" } },
|
|
3976
|
+
metadata: { type: "object" },
|
|
3977
|
+
created_at: { type: "string" },
|
|
3978
|
+
updated_at: { type: "string" },
|
|
3979
|
+
agent: { type: "string" },
|
|
3980
|
+
model: { type: "string" }
|
|
3981
|
+
},
|
|
3982
|
+
required: [
|
|
3983
|
+
"id",
|
|
3984
|
+
"title",
|
|
3985
|
+
"content",
|
|
3986
|
+
"context",
|
|
3987
|
+
"version",
|
|
3988
|
+
"stack",
|
|
3989
|
+
"is_global",
|
|
3990
|
+
"tags",
|
|
3991
|
+
"metadata",
|
|
3992
|
+
"created_at",
|
|
3993
|
+
"updated_at",
|
|
3994
|
+
"agent",
|
|
3995
|
+
"model"
|
|
3996
|
+
]
|
|
3997
|
+
},
|
|
3998
|
+
message: { type: "string" }
|
|
4226
3999
|
},
|
|
4227
|
-
required: ["success", "
|
|
4000
|
+
required: ["success", "standard", "message"]
|
|
4228
4001
|
}
|
|
4229
4002
|
},
|
|
4230
4003
|
{
|
|
4231
|
-
name: "
|
|
4232
|
-
title: "
|
|
4233
|
-
description: "
|
|
4004
|
+
name: "standard-search",
|
|
4005
|
+
title: "Standard Search",
|
|
4006
|
+
description: "Navigation and lookup layer for coding standards. Query by text, stack, language, version, repo, and global scope before applying or creating standards.",
|
|
4234
4007
|
annotations: {
|
|
4235
4008
|
readOnlyHint: true,
|
|
4236
4009
|
idempotentHint: true,
|
|
@@ -4239,377 +4012,635 @@ var TOOL_DEFINITIONS = [
|
|
|
4239
4012
|
inputSchema: {
|
|
4240
4013
|
type: "object",
|
|
4241
4014
|
properties: {
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
type: "string",
|
|
4248
|
-
default: "in_progress,pending",
|
|
4249
|
-
description: "Comma-separated status filter (backlog, pending, in_progress, completed, canceled, blocked). Defaults to 'in_progress,pending'."
|
|
4250
|
-
},
|
|
4251
|
-
phase: {
|
|
4252
|
-
type: "string",
|
|
4253
|
-
description: "Filter by phase (e.g., 'research', 'implementation')"
|
|
4254
|
-
},
|
|
4255
|
-
query: {
|
|
4256
|
-
type: "string",
|
|
4257
|
-
description: "Search keyword matching task code, title, or description"
|
|
4258
|
-
},
|
|
4259
|
-
limit: {
|
|
4260
|
-
type: "number",
|
|
4261
|
-
minimum: 1,
|
|
4262
|
-
maximum: 100,
|
|
4263
|
-
default: 5,
|
|
4264
|
-
description: "Maximum rows to return (default 5)"
|
|
4015
|
+
query: { type: "string", description: "Search query (optional, searches title/content)" },
|
|
4016
|
+
stack: {
|
|
4017
|
+
type: "array",
|
|
4018
|
+
items: { type: "string" },
|
|
4019
|
+
description: "Technology stack to filter by (e.g., ['react', 'nextjs'])"
|
|
4265
4020
|
},
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4021
|
+
language: { type: "string", description: "Programming language filter" },
|
|
4022
|
+
version: { type: "string", description: "Version filter" },
|
|
4023
|
+
repo: { type: "string", description: "Repository filter (optional)" },
|
|
4024
|
+
is_global: { type: "boolean", description: "Filter by global/repo-specific" },
|
|
4025
|
+
limit: { type: "number", minimum: 1, maximum: 100, default: 20 },
|
|
4026
|
+
offset: { type: "number", minimum: 0, default: 0 },
|
|
4027
|
+
structured: { type: "boolean", default: false }
|
|
4028
|
+
},
|
|
4029
|
+
required: []
|
|
4030
|
+
},
|
|
4031
|
+
outputSchema: {
|
|
4032
|
+
type: "object",
|
|
4033
|
+
properties: {
|
|
4034
|
+
success: { type: "boolean" },
|
|
4035
|
+
standards: {
|
|
4036
|
+
type: "array",
|
|
4037
|
+
items: {
|
|
4038
|
+
type: "object",
|
|
4039
|
+
properties: {
|
|
4040
|
+
id: { type: "string" },
|
|
4041
|
+
title: { type: "string" },
|
|
4042
|
+
content: { type: "string" },
|
|
4043
|
+
context: { type: "string" },
|
|
4044
|
+
version: { type: "string" },
|
|
4045
|
+
language: { type: "string", nullable: true },
|
|
4046
|
+
stack: { type: "array", items: { type: "string" } },
|
|
4047
|
+
is_global: { type: "boolean" },
|
|
4048
|
+
repo: { type: "string", nullable: true },
|
|
4049
|
+
tags: { type: "array", items: { type: "string" } },
|
|
4050
|
+
metadata: { type: "object" },
|
|
4051
|
+
created_at: { type: "string" },
|
|
4052
|
+
updated_at: { type: "string" },
|
|
4053
|
+
agent: { type: "string" },
|
|
4054
|
+
model: { type: "string" }
|
|
4055
|
+
}
|
|
4056
|
+
},
|
|
4057
|
+
description: "Matching coding standards"
|
|
4271
4058
|
},
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
default: false,
|
|
4275
|
-
description: "If true, returns structured JSON without the text content summary."
|
|
4276
|
-
}
|
|
4059
|
+
count: { type: "number", description: "Number of results returned" },
|
|
4060
|
+
message: { type: "string" }
|
|
4277
4061
|
},
|
|
4278
|
-
required: ["
|
|
4062
|
+
required: ["success", "standards", "count", "message"]
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
];
|
|
4066
|
+
|
|
4067
|
+
// src/mcp/utils/pagination.ts
|
|
4068
|
+
function encodeCursor(offset) {
|
|
4069
|
+
return Buffer.from(String(offset), "utf8").toString("base64");
|
|
4070
|
+
}
|
|
4071
|
+
function decodeCursor(cursor) {
|
|
4072
|
+
if (cursor === void 0 || cursor === null || cursor === "") {
|
|
4073
|
+
return 0;
|
|
4074
|
+
}
|
|
4075
|
+
if (typeof cursor !== "string" || cursor.trim() === "") {
|
|
4076
|
+
throw invalidPaginationParams("Invalid cursor");
|
|
4077
|
+
}
|
|
4078
|
+
let decoded;
|
|
4079
|
+
try {
|
|
4080
|
+
decoded = Buffer.from(cursor, "base64").toString("utf8");
|
|
4081
|
+
} catch {
|
|
4082
|
+
throw invalidPaginationParams("Invalid cursor");
|
|
4083
|
+
}
|
|
4084
|
+
if (!/^\d+$/.test(decoded)) {
|
|
4085
|
+
throw invalidPaginationParams("Invalid cursor");
|
|
4086
|
+
}
|
|
4087
|
+
const offset = Number.parseInt(decoded, 10);
|
|
4088
|
+
if (!Number.isFinite(offset) || offset < 0) {
|
|
4089
|
+
throw invalidPaginationParams("Invalid cursor");
|
|
4090
|
+
}
|
|
4091
|
+
return offset;
|
|
4092
|
+
}
|
|
4093
|
+
function invalidPaginationParams(message) {
|
|
4094
|
+
const error = new Error(message);
|
|
4095
|
+
error.code = -32602;
|
|
4096
|
+
return error;
|
|
4097
|
+
}
|
|
4098
|
+
|
|
4099
|
+
// src/mcp/utils/completion.ts
|
|
4100
|
+
var MAX_COMPLETION_VALUES = 100;
|
|
4101
|
+
function rankCompletionValues(candidates, input) {
|
|
4102
|
+
const unique = [...new Set(candidates.filter(Boolean))];
|
|
4103
|
+
const needle = input.trim().toLowerCase();
|
|
4104
|
+
if (!needle) {
|
|
4105
|
+
return unique.slice(0, MAX_COMPLETION_VALUES);
|
|
4106
|
+
}
|
|
4107
|
+
return unique.map((value) => ({ value, score: scoreCompletionValue(value, needle) })).filter((entry) => entry.score > 0).sort((a, b) => b.score - a.score || a.value.localeCompare(b.value)).map((entry) => entry.value);
|
|
4108
|
+
}
|
|
4109
|
+
function scoreCompletionValue(value, needle) {
|
|
4110
|
+
const haystack = value.toLowerCase();
|
|
4111
|
+
if (haystack === needle) return 100;
|
|
4112
|
+
if (haystack.startsWith(needle)) return 75;
|
|
4113
|
+
if (haystack.includes(needle)) return 50;
|
|
4114
|
+
const compactNeedle = needle.replace(/[\s_-]+/g, "");
|
|
4115
|
+
const compactHaystack = haystack.replace(/[\s_-]+/g, "");
|
|
4116
|
+
if (compactNeedle && compactHaystack.includes(compactNeedle)) return 25;
|
|
4117
|
+
return 0;
|
|
4118
|
+
}
|
|
4119
|
+
|
|
4120
|
+
// src/mcp/resources/index.ts
|
|
4121
|
+
var DEFAULT_PAGE_SIZE = 25;
|
|
4122
|
+
var MAX_PAGE_SIZE = 100;
|
|
4123
|
+
function listResources(session, params) {
|
|
4124
|
+
const resources = [
|
|
4125
|
+
{
|
|
4126
|
+
uri: "repository://index",
|
|
4127
|
+
name: "Repository Index",
|
|
4128
|
+
title: "Repository Index",
|
|
4129
|
+
description: "List of all known repositories with memory/task counts and last activity",
|
|
4130
|
+
mimeType: "application/json",
|
|
4131
|
+
annotations: {
|
|
4132
|
+
audience: ["assistant"],
|
|
4133
|
+
priority: 1,
|
|
4134
|
+
lastModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
4135
|
+
}
|
|
4136
|
+
},
|
|
4137
|
+
{
|
|
4138
|
+
uri: "session://roots",
|
|
4139
|
+
name: "Session Roots",
|
|
4140
|
+
title: "Session Roots",
|
|
4141
|
+
description: session?.roots.length ? "Active workspace roots provided by the MCP client" : "No active workspace roots were provided by the MCP client",
|
|
4142
|
+
mimeType: "application/json",
|
|
4143
|
+
size: Buffer.byteLength(JSON.stringify({ roots: session?.roots ?? [] }), "utf8"),
|
|
4144
|
+
annotations: {
|
|
4145
|
+
audience: ["assistant"],
|
|
4146
|
+
priority: 0.95,
|
|
4147
|
+
lastModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
4148
|
+
}
|
|
4149
|
+
}
|
|
4150
|
+
];
|
|
4151
|
+
return paginateEntries("resources", resources, params);
|
|
4152
|
+
}
|
|
4153
|
+
function listResourceTemplates(params) {
|
|
4154
|
+
const templates = [
|
|
4155
|
+
// ── Memory ──────────────────────────────────────────────────────────────
|
|
4156
|
+
{
|
|
4157
|
+
uriTemplate: "repository://{name}/memories",
|
|
4158
|
+
name: "Repository Memories",
|
|
4159
|
+
title: "Repository Memories",
|
|
4160
|
+
description: "All active memory entries for a specific repository",
|
|
4161
|
+
mimeType: "application/json",
|
|
4162
|
+
annotations: { audience: ["assistant"], priority: 0.85 }
|
|
4163
|
+
},
|
|
4164
|
+
{
|
|
4165
|
+
uriTemplate: "repository://{name}/memories?search={search}&type={type}&tag={tag}",
|
|
4166
|
+
name: "Filtered Repository Memories",
|
|
4167
|
+
title: "Filtered Repository Memories",
|
|
4168
|
+
description: "Filter or search memories within a repository by keyword, type, or tag",
|
|
4169
|
+
mimeType: "application/json",
|
|
4170
|
+
annotations: { audience: ["assistant"], priority: 0.8 }
|
|
4171
|
+
},
|
|
4172
|
+
{
|
|
4173
|
+
uriTemplate: "memory://{id}",
|
|
4174
|
+
name: "Memory Detail",
|
|
4175
|
+
title: "Memory Detail",
|
|
4176
|
+
description: "Full content and statistics for a specific memory UUID",
|
|
4177
|
+
mimeType: "application/json",
|
|
4178
|
+
annotations: { audience: ["assistant"], priority: 0.75 }
|
|
4179
|
+
},
|
|
4180
|
+
// ── Tasks ────────────────────────────────────────────────────────────────
|
|
4181
|
+
{
|
|
4182
|
+
uriTemplate: "repository://{name}/tasks",
|
|
4183
|
+
name: "Repository Tasks",
|
|
4184
|
+
title: "Repository Tasks",
|
|
4185
|
+
description: "All active tasks for a specific repository",
|
|
4186
|
+
mimeType: "application/json",
|
|
4187
|
+
annotations: { audience: ["assistant"], priority: 0.9 }
|
|
4279
4188
|
},
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
columns: {
|
|
4288
|
-
type: "array",
|
|
4289
|
-
items: { type: "string" },
|
|
4290
|
-
description: "Column names in order: id, task_code, title, status, priority, updated_at, comments_count"
|
|
4291
|
-
},
|
|
4292
|
-
rows: {
|
|
4293
|
-
type: "array",
|
|
4294
|
-
items: { type: "array" },
|
|
4295
|
-
description: "Each row: [id, task_code, title, status, priority, updated_at, comments_count]. Use task-detail to fetch full task."
|
|
4296
|
-
}
|
|
4297
|
-
},
|
|
4298
|
-
required: ["columns", "rows"]
|
|
4299
|
-
},
|
|
4300
|
-
count: { type: "number" },
|
|
4301
|
-
offset: { type: "number" }
|
|
4302
|
-
},
|
|
4303
|
-
required: ["schema", "tasks", "count"]
|
|
4304
|
-
}
|
|
4305
|
-
},
|
|
4306
|
-
{
|
|
4307
|
-
name: "handoff-create",
|
|
4308
|
-
title: "Handoff Create",
|
|
4309
|
-
description: "Create a handoff record when work needs context transfer between agents. Optionally link it to a task by task_id or task_code, and put machine-readable details in context.",
|
|
4310
|
-
annotations: {
|
|
4311
|
-
readOnlyHint: false,
|
|
4312
|
-
idempotentHint: false,
|
|
4313
|
-
destructiveHint: false,
|
|
4314
|
-
openWorldHint: false
|
|
4189
|
+
{
|
|
4190
|
+
uriTemplate: "repository://{name}/tasks?status={status}&priority={priority}",
|
|
4191
|
+
name: "Filtered Repository Tasks",
|
|
4192
|
+
title: "Filtered Repository Tasks",
|
|
4193
|
+
description: "Filter tasks within a repository by status or priority level",
|
|
4194
|
+
mimeType: "application/json",
|
|
4195
|
+
annotations: { audience: ["assistant"], priority: 0.85 }
|
|
4315
4196
|
},
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
task_code: { type: "string", description: "Optional task code to associate" },
|
|
4324
|
-
summary: { type: "string", minLength: 1, description: "Concise human-readable transfer summary" },
|
|
4325
|
-
context: {
|
|
4326
|
-
type: "object",
|
|
4327
|
-
description: "Structured handoff context, such as changed files, blockers, verification status, and next steps"
|
|
4328
|
-
},
|
|
4329
|
-
expires_at: { type: "string", description: "Optional expiration timestamp" },
|
|
4330
|
-
structured: { type: "boolean", default: false }
|
|
4331
|
-
},
|
|
4332
|
-
required: ["repo", "from_agent", "summary"]
|
|
4197
|
+
{
|
|
4198
|
+
uriTemplate: "task://{id}",
|
|
4199
|
+
name: "Task Detail",
|
|
4200
|
+
title: "Task Detail",
|
|
4201
|
+
description: "Full content and comments for a specific task UUID",
|
|
4202
|
+
mimeType: "application/json",
|
|
4203
|
+
annotations: { audience: ["assistant"], priority: 0.8 }
|
|
4333
4204
|
},
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
summary: { type: "string" },
|
|
4343
|
-
context: { type: "object" },
|
|
4344
|
-
status: { type: "string", enum: ["pending", "accepted", "rejected", "expired"] },
|
|
4345
|
-
created_at: { type: "string" },
|
|
4346
|
-
updated_at: { type: "string" },
|
|
4347
|
-
expires_at: { type: "string", nullable: true }
|
|
4348
|
-
},
|
|
4349
|
-
required: ["id", "repo", "from_agent", "summary", "context", "status", "created_at", "updated_at"]
|
|
4350
|
-
}
|
|
4351
|
-
},
|
|
4352
|
-
{
|
|
4353
|
-
name: "handoff-list",
|
|
4354
|
-
title: "Handoff List",
|
|
4355
|
-
description: "Navigation layer for handoff queues. List repository handoffs with optional status and agent filters, then inspect selected rows before acting.",
|
|
4356
|
-
annotations: {
|
|
4357
|
-
readOnlyHint: true,
|
|
4358
|
-
idempotentHint: true,
|
|
4359
|
-
openWorldHint: false
|
|
4205
|
+
// ── Repository extras ────────────────────────────────────────────────────
|
|
4206
|
+
{
|
|
4207
|
+
uriTemplate: "repository://{name}/summary",
|
|
4208
|
+
name: "Repository Summary",
|
|
4209
|
+
title: "Repository Summary",
|
|
4210
|
+
description: "High-level architectural summary for a repository",
|
|
4211
|
+
mimeType: "text/plain",
|
|
4212
|
+
annotations: { audience: ["assistant"], priority: 0.95 }
|
|
4360
4213
|
},
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
limit: { type: "number", minimum: 1, maximum: 100, default: 20 },
|
|
4369
|
-
offset: { type: "number", minimum: 0, default: 0 },
|
|
4370
|
-
structured: { type: "boolean", default: false }
|
|
4371
|
-
},
|
|
4372
|
-
required: ["repo"]
|
|
4214
|
+
{
|
|
4215
|
+
uriTemplate: "repository://{name}/actions",
|
|
4216
|
+
name: "Repository Actions",
|
|
4217
|
+
title: "Repository Actions",
|
|
4218
|
+
description: "Audit log of agent tool actions scoped to a repository",
|
|
4219
|
+
mimeType: "application/json",
|
|
4220
|
+
annotations: { audience: ["assistant"], priority: 0.6 }
|
|
4373
4221
|
},
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4222
|
+
// ── Action detail ────────────────────────────────────────────────────────
|
|
4223
|
+
{
|
|
4224
|
+
uriTemplate: "action://{id}",
|
|
4225
|
+
name: "Action Detail",
|
|
4226
|
+
title: "Action Detail",
|
|
4227
|
+
description: "Full details of a specific audit log entry by integer ID",
|
|
4228
|
+
mimeType: "application/json",
|
|
4229
|
+
annotations: { audience: ["assistant"], priority: 0.55 }
|
|
4230
|
+
}
|
|
4231
|
+
];
|
|
4232
|
+
return paginateEntries("resourceTemplates", templates, params);
|
|
4233
|
+
}
|
|
4234
|
+
function completeResourceArgument(resourceUri, argumentName, argumentValue, _contextArguments, dataSources) {
|
|
4235
|
+
if (resourceUri === "repository://{name}/memories" || resourceUri === "repository://{name}/memories?search={search}&type={type}&tag={tag}" || resourceUri === "repository://{name}/tasks" || resourceUri === "repository://{name}/tasks?status={status}&priority={priority}" || resourceUri === "repository://{name}/summary" || resourceUri === "repository://{name}/actions") {
|
|
4236
|
+
if (argumentName === "name") {
|
|
4237
|
+
return rankCompletionValues(dataSources.repos, argumentValue);
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
if (resourceUri === "repository://{name}/memories?search={search}&type={type}&tag={tag}") {
|
|
4241
|
+
if (argumentName === "tag") {
|
|
4242
|
+
return rankCompletionValues(dataSources.tags, argumentValue);
|
|
4243
|
+
}
|
|
4244
|
+
}
|
|
4245
|
+
throw invalidCompletionParams(`Unknown resource template or argument: ${resourceUri} (${argumentName})`);
|
|
4246
|
+
}
|
|
4247
|
+
function readResource(uri, db, session) {
|
|
4248
|
+
logger.info("[Tool] resource.read", { uri });
|
|
4249
|
+
if (uri === "repository://index") {
|
|
4250
|
+
const repos = db.system.listRepoNavigation();
|
|
4251
|
+
const payload = JSON.stringify(repos, null, 2);
|
|
4252
|
+
return {
|
|
4253
|
+
contents: [
|
|
4254
|
+
{
|
|
4255
|
+
uri,
|
|
4256
|
+
mimeType: "application/json",
|
|
4257
|
+
text: payload,
|
|
4258
|
+
size: Buffer.byteLength(payload, "utf8"),
|
|
4259
|
+
annotations: {
|
|
4260
|
+
audience: ["assistant"],
|
|
4261
|
+
priority: 1,
|
|
4262
|
+
lastModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
]
|
|
4266
|
+
};
|
|
4267
|
+
}
|
|
4268
|
+
if (uri === "session://roots") {
|
|
4269
|
+
const payload = JSON.stringify({ roots: session?.roots ?? [] }, null, 2);
|
|
4270
|
+
return {
|
|
4271
|
+
contents: [
|
|
4272
|
+
{
|
|
4273
|
+
uri,
|
|
4274
|
+
mimeType: "application/json",
|
|
4275
|
+
text: payload,
|
|
4276
|
+
size: Buffer.byteLength(payload, "utf8"),
|
|
4277
|
+
annotations: {
|
|
4278
|
+
audience: ["assistant"],
|
|
4279
|
+
priority: 0.95,
|
|
4280
|
+
lastModified: (/* @__PURE__ */ new Date()).toISOString()
|
|
4281
|
+
}
|
|
4282
|
+
}
|
|
4283
|
+
]
|
|
4284
|
+
};
|
|
4285
|
+
}
|
|
4286
|
+
const memoryIdMatch = uri.match(/^memory:\/\/([0-9a-f-]{36})$/i);
|
|
4287
|
+
if (memoryIdMatch) {
|
|
4288
|
+
const id = memoryIdMatch[1];
|
|
4289
|
+
const entry = db.memories.getByIdWithStats(id);
|
|
4290
|
+
if (!entry) throw resourceNotFound(`Memory with ID ${id} not found.`, uri);
|
|
4291
|
+
const payload = JSON.stringify(entry, null, 2);
|
|
4292
|
+
return {
|
|
4293
|
+
contents: [
|
|
4294
|
+
{
|
|
4295
|
+
uri,
|
|
4296
|
+
mimeType: "application/json",
|
|
4297
|
+
text: payload,
|
|
4298
|
+
size: Buffer.byteLength(payload, "utf8"),
|
|
4299
|
+
annotations: {
|
|
4300
|
+
audience: ["assistant"],
|
|
4301
|
+
priority: 0.75,
|
|
4302
|
+
lastModified: entry.updated_at || entry.created_at
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
]
|
|
4306
|
+
};
|
|
4307
|
+
}
|
|
4308
|
+
const taskIdMatch = uri.match(/^task:\/\/([0-9a-f-]{36})$/i);
|
|
4309
|
+
if (taskIdMatch) {
|
|
4310
|
+
const id = taskIdMatch[1];
|
|
4311
|
+
const task = db.tasks.getTaskById(id);
|
|
4312
|
+
if (!task) throw resourceNotFound(`Task with ID ${id} not found.`, uri);
|
|
4313
|
+
const payload = JSON.stringify(task, null, 2);
|
|
4314
|
+
return {
|
|
4315
|
+
contents: [
|
|
4316
|
+
{
|
|
4317
|
+
uri,
|
|
4318
|
+
mimeType: "application/json",
|
|
4319
|
+
text: payload,
|
|
4320
|
+
size: Buffer.byteLength(payload, "utf8"),
|
|
4321
|
+
annotations: {
|
|
4322
|
+
audience: ["assistant"],
|
|
4323
|
+
priority: 0.8,
|
|
4324
|
+
lastModified: task.updated_at || task.created_at
|
|
4325
|
+
}
|
|
4326
|
+
}
|
|
4327
|
+
]
|
|
4328
|
+
};
|
|
4329
|
+
}
|
|
4330
|
+
const repoBase = parseRepoUri(uri);
|
|
4331
|
+
if (repoBase) {
|
|
4332
|
+
const { name, path: repoPath, query } = repoBase;
|
|
4333
|
+
if (repoPath === "summary") {
|
|
4334
|
+
const summary = db.summaries.getSummary(name);
|
|
4335
|
+
const text = summary?.summary || `No summary available for repository: ${name}`;
|
|
4336
|
+
return {
|
|
4337
|
+
contents: [
|
|
4338
|
+
{
|
|
4339
|
+
uri,
|
|
4340
|
+
mimeType: "text/plain",
|
|
4341
|
+
text,
|
|
4342
|
+
size: Buffer.byteLength(text, "utf8"),
|
|
4343
|
+
annotations: {
|
|
4344
|
+
audience: ["assistant"],
|
|
4345
|
+
priority: 0.95,
|
|
4346
|
+
lastModified: summary?.updated_at || (/* @__PURE__ */ new Date()).toISOString()
|
|
4390
4347
|
}
|
|
4391
|
-
}
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
count: { type: "number" },
|
|
4395
|
-
offset: { type: "number" }
|
|
4396
|
-
},
|
|
4397
|
-
required: ["schema", "handoffs", "count", "offset"]
|
|
4348
|
+
}
|
|
4349
|
+
]
|
|
4350
|
+
};
|
|
4398
4351
|
}
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
task_code: { type: "string", nullable: true },
|
|
4430
|
-
agent: { type: "string" },
|
|
4431
|
-
role: { type: "string" },
|
|
4432
|
-
claimed_at: { type: "string" },
|
|
4433
|
-
released_at: { type: "string", nullable: true },
|
|
4434
|
-
metadata: { type: "object" }
|
|
4435
|
-
},
|
|
4436
|
-
required: ["id", "repo", "task_id", "agent", "role", "claimed_at", "metadata"]
|
|
4352
|
+
if (repoPath === "memories") {
|
|
4353
|
+
const search = query.get("search") || "";
|
|
4354
|
+
const type = query.get("type");
|
|
4355
|
+
const tag = query.get("tag");
|
|
4356
|
+
const result = db.memories.listMemoriesForDashboard({
|
|
4357
|
+
repo: name,
|
|
4358
|
+
type: type || void 0,
|
|
4359
|
+
tag: tag || void 0,
|
|
4360
|
+
search: search || void 0,
|
|
4361
|
+
limit: 50
|
|
4362
|
+
});
|
|
4363
|
+
const entries = result.items;
|
|
4364
|
+
const payload = JSON.stringify(entries, null, 2);
|
|
4365
|
+
return {
|
|
4366
|
+
contents: [
|
|
4367
|
+
{
|
|
4368
|
+
uri,
|
|
4369
|
+
mimeType: "application/json",
|
|
4370
|
+
text: payload,
|
|
4371
|
+
size: Buffer.byteLength(payload, "utf8"),
|
|
4372
|
+
annotations: {
|
|
4373
|
+
audience: ["assistant"],
|
|
4374
|
+
priority: 0.85,
|
|
4375
|
+
lastModified: deriveLastModifiedFromCollection(
|
|
4376
|
+
entries.map((e) => e.updated_at || e.created_at)
|
|
4377
|
+
)
|
|
4378
|
+
}
|
|
4379
|
+
}
|
|
4380
|
+
]
|
|
4381
|
+
};
|
|
4437
4382
|
}
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
type: "object",
|
|
4471
|
-
description: "Additional metadata"
|
|
4472
|
-
},
|
|
4473
|
-
agent: { type: "string", description: "Agent creating the standard" },
|
|
4474
|
-
model: { type: "string", description: "AI model used" },
|
|
4475
|
-
structured: { type: "boolean", default: false }
|
|
4476
|
-
},
|
|
4477
|
-
required: ["name", "content"]
|
|
4478
|
-
},
|
|
4479
|
-
outputSchema: {
|
|
4480
|
-
type: "object",
|
|
4481
|
-
properties: {
|
|
4482
|
-
success: { type: "boolean" },
|
|
4483
|
-
standard: {
|
|
4484
|
-
type: "object",
|
|
4485
|
-
properties: {
|
|
4486
|
-
id: { type: "string" },
|
|
4487
|
-
title: { type: "string" },
|
|
4488
|
-
content: { type: "string" },
|
|
4489
|
-
context: { type: "string" },
|
|
4490
|
-
version: { type: "string" },
|
|
4491
|
-
language: { type: "string", nullable: true },
|
|
4492
|
-
stack: { type: "array", items: { type: "string" } },
|
|
4493
|
-
is_global: { type: "boolean" },
|
|
4494
|
-
repo: { type: "string", nullable: true },
|
|
4495
|
-
tags: { type: "array", items: { type: "string" } },
|
|
4496
|
-
metadata: { type: "object" },
|
|
4497
|
-
created_at: { type: "string" },
|
|
4498
|
-
updated_at: { type: "string" },
|
|
4499
|
-
agent: { type: "string" },
|
|
4500
|
-
model: { type: "string" }
|
|
4501
|
-
},
|
|
4502
|
-
required: [
|
|
4503
|
-
"id",
|
|
4504
|
-
"title",
|
|
4505
|
-
"content",
|
|
4506
|
-
"context",
|
|
4507
|
-
"version",
|
|
4508
|
-
"stack",
|
|
4509
|
-
"is_global",
|
|
4510
|
-
"tags",
|
|
4511
|
-
"metadata",
|
|
4512
|
-
"created_at",
|
|
4513
|
-
"updated_at",
|
|
4514
|
-
"agent",
|
|
4515
|
-
"model"
|
|
4516
|
-
]
|
|
4517
|
-
},
|
|
4518
|
-
message: { type: "string" }
|
|
4519
|
-
},
|
|
4520
|
-
required: ["success", "standard", "message"]
|
|
4383
|
+
if (repoPath === "tasks") {
|
|
4384
|
+
const status = query.get("status");
|
|
4385
|
+
const priority = query.get("priority");
|
|
4386
|
+
let tasks;
|
|
4387
|
+
if (status && status !== "all") {
|
|
4388
|
+
const statuses = status.split(",").map((s) => s.trim());
|
|
4389
|
+
tasks = db.tasks.getTasksByMultipleStatuses(name, statuses);
|
|
4390
|
+
} else {
|
|
4391
|
+
tasks = db.tasks.getTasksByMultipleStatuses(name, ["backlog", "pending", "in_progress", "blocked"]);
|
|
4392
|
+
}
|
|
4393
|
+
if (priority) {
|
|
4394
|
+
const p = Number(priority);
|
|
4395
|
+
if (!isNaN(p)) {
|
|
4396
|
+
tasks = tasks.filter((t) => t.priority === p);
|
|
4397
|
+
}
|
|
4398
|
+
}
|
|
4399
|
+
const payload = JSON.stringify(tasks, null, 2);
|
|
4400
|
+
return {
|
|
4401
|
+
contents: [
|
|
4402
|
+
{
|
|
4403
|
+
uri,
|
|
4404
|
+
mimeType: "application/json",
|
|
4405
|
+
text: payload,
|
|
4406
|
+
size: Buffer.byteLength(payload, "utf8"),
|
|
4407
|
+
annotations: {
|
|
4408
|
+
audience: ["assistant"],
|
|
4409
|
+
priority: 0.9,
|
|
4410
|
+
lastModified: deriveLastModifiedFromCollection(tasks.map((t) => t.updated_at))
|
|
4411
|
+
}
|
|
4412
|
+
}
|
|
4413
|
+
]
|
|
4414
|
+
};
|
|
4521
4415
|
}
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
stack: {
|
|
4537
|
-
type: "array",
|
|
4538
|
-
items: { type: "string" },
|
|
4539
|
-
description: "Technology stack to filter by (e.g., ['react', 'nextjs'])"
|
|
4540
|
-
},
|
|
4541
|
-
language: { type: "string", description: "Programming language filter" },
|
|
4542
|
-
version: { type: "string", description: "Version filter" },
|
|
4543
|
-
repo: { type: "string", description: "Repository filter (optional)" },
|
|
4544
|
-
is_global: { type: "boolean", description: "Filter by global/repo-specific" },
|
|
4545
|
-
limit: { type: "number", minimum: 1, maximum: 100, default: 20 },
|
|
4546
|
-
offset: { type: "number", minimum: 0, default: 0 },
|
|
4547
|
-
structured: { type: "boolean", default: false }
|
|
4548
|
-
},
|
|
4549
|
-
required: []
|
|
4550
|
-
},
|
|
4551
|
-
outputSchema: {
|
|
4552
|
-
type: "object",
|
|
4553
|
-
properties: {
|
|
4554
|
-
success: { type: "boolean" },
|
|
4555
|
-
standards: {
|
|
4556
|
-
type: "array",
|
|
4557
|
-
items: {
|
|
4558
|
-
type: "object",
|
|
4559
|
-
properties: {
|
|
4560
|
-
id: { type: "string" },
|
|
4561
|
-
title: { type: "string" },
|
|
4562
|
-
content: { type: "string" },
|
|
4563
|
-
context: { type: "string" },
|
|
4564
|
-
version: { type: "string" },
|
|
4565
|
-
language: { type: "string", nullable: true },
|
|
4566
|
-
stack: { type: "array", items: { type: "string" } },
|
|
4567
|
-
is_global: { type: "boolean" },
|
|
4568
|
-
repo: { type: "string", nullable: true },
|
|
4569
|
-
tags: { type: "array", items: { type: "string" } },
|
|
4570
|
-
metadata: { type: "object" },
|
|
4571
|
-
created_at: { type: "string" },
|
|
4572
|
-
updated_at: { type: "string" },
|
|
4573
|
-
agent: { type: "string" },
|
|
4574
|
-
model: { type: "string" }
|
|
4416
|
+
if (repoPath === "actions") {
|
|
4417
|
+
const actions = db.actions.getRecentActions(name, 100);
|
|
4418
|
+
const payload = JSON.stringify(actions, null, 2);
|
|
4419
|
+
return {
|
|
4420
|
+
contents: [
|
|
4421
|
+
{
|
|
4422
|
+
uri,
|
|
4423
|
+
mimeType: "application/json",
|
|
4424
|
+
text: payload,
|
|
4425
|
+
size: Buffer.byteLength(payload, "utf8"),
|
|
4426
|
+
annotations: {
|
|
4427
|
+
audience: ["assistant"],
|
|
4428
|
+
priority: 0.6,
|
|
4429
|
+
lastModified: deriveLastModifiedFromCollection(actions.map((a) => a.created_at))
|
|
4575
4430
|
}
|
|
4576
|
-
}
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
count: { type: "number", description: "Number of results returned" },
|
|
4580
|
-
message: { type: "string" }
|
|
4581
|
-
},
|
|
4582
|
-
required: ["success", "standards", "count", "message"]
|
|
4431
|
+
}
|
|
4432
|
+
]
|
|
4433
|
+
};
|
|
4583
4434
|
}
|
|
4584
4435
|
}
|
|
4585
|
-
|
|
4436
|
+
const actionIdMatch = uri.match(/^action:\/\/(\d+)$/);
|
|
4437
|
+
if (actionIdMatch) {
|
|
4438
|
+
const id = Number(actionIdMatch[1]);
|
|
4439
|
+
const action = db.actions.getActionById(id);
|
|
4440
|
+
if (!action) throw resourceNotFound(`Action with ID ${id} not found.`, uri);
|
|
4441
|
+
const payload = JSON.stringify(action, null, 2);
|
|
4442
|
+
return {
|
|
4443
|
+
contents: [
|
|
4444
|
+
{
|
|
4445
|
+
uri,
|
|
4446
|
+
mimeType: "application/json",
|
|
4447
|
+
text: payload,
|
|
4448
|
+
size: Buffer.byteLength(payload, "utf8"),
|
|
4449
|
+
annotations: {
|
|
4450
|
+
audience: ["assistant"],
|
|
4451
|
+
priority: 0.55,
|
|
4452
|
+
lastModified: action.created_at
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4455
|
+
]
|
|
4456
|
+
};
|
|
4457
|
+
}
|
|
4458
|
+
throw resourceNotFound(`Unknown resource URI: ${uri}`, uri);
|
|
4459
|
+
}
|
|
4460
|
+
function parseRepoUri(uri) {
|
|
4461
|
+
const prefix = "repository://";
|
|
4462
|
+
if (!uri.startsWith(prefix)) return null;
|
|
4463
|
+
const rest = uri.slice(prefix.length);
|
|
4464
|
+
const queryStart = rest.indexOf("?");
|
|
4465
|
+
const withoutQuery = queryStart === -1 ? rest : rest.slice(0, queryStart);
|
|
4466
|
+
const queryString = queryStart === -1 ? "" : rest.slice(queryStart + 1);
|
|
4467
|
+
const slashIdx = withoutQuery.indexOf("/");
|
|
4468
|
+
if (slashIdx === -1) return null;
|
|
4469
|
+
const name = withoutQuery.slice(0, slashIdx);
|
|
4470
|
+
const path6 = withoutQuery.slice(slashIdx + 1);
|
|
4471
|
+
if (!name || !path6) return null;
|
|
4472
|
+
return { name, path: path6, query: new URLSearchParams(queryString) };
|
|
4473
|
+
}
|
|
4474
|
+
function paginateEntries(key, entries, params) {
|
|
4475
|
+
const limit = normalizeLimit(params?.limit);
|
|
4476
|
+
const offset = decodeCursor(params?.cursor);
|
|
4477
|
+
const sliced = entries.slice(offset, offset + limit);
|
|
4478
|
+
const nextOffset = offset + sliced.length;
|
|
4479
|
+
return {
|
|
4480
|
+
[key]: sliced,
|
|
4481
|
+
nextCursor: nextOffset < entries.length ? encodeCursor(nextOffset) : void 0
|
|
4482
|
+
};
|
|
4483
|
+
}
|
|
4484
|
+
function normalizeLimit(limit) {
|
|
4485
|
+
if (typeof limit !== "number" || !Number.isFinite(limit)) {
|
|
4486
|
+
return DEFAULT_PAGE_SIZE;
|
|
4487
|
+
}
|
|
4488
|
+
return Math.min(MAX_PAGE_SIZE, Math.max(1, Math.trunc(limit)));
|
|
4489
|
+
}
|
|
4490
|
+
function deriveLastModifiedFromCollection(values) {
|
|
4491
|
+
const normalized = values.filter((value) => typeof value === "string" && value.length > 0);
|
|
4492
|
+
return normalized.sort().at(-1) ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
4493
|
+
}
|
|
4494
|
+
function resourceNotFound(message, uri) {
|
|
4495
|
+
const error = new Error(message);
|
|
4496
|
+
error.code = -32002;
|
|
4497
|
+
error.data = { uri };
|
|
4498
|
+
return error;
|
|
4499
|
+
}
|
|
4500
|
+
function invalidCompletionParams(message) {
|
|
4501
|
+
const error = new Error(message);
|
|
4502
|
+
error.code = -32602;
|
|
4503
|
+
return error;
|
|
4504
|
+
}
|
|
4505
|
+
|
|
4506
|
+
// src/mcp/prompts/loader.ts
|
|
4507
|
+
import fs4 from "fs";
|
|
4508
|
+
import path5 from "path";
|
|
4509
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4510
|
+
import matter from "gray-matter";
|
|
4511
|
+
var __filename = fileURLToPath3(import.meta.url);
|
|
4512
|
+
var __dirname2 = path5.dirname(__filename);
|
|
4513
|
+
function findPromptDir() {
|
|
4514
|
+
const candidates = [
|
|
4515
|
+
// Production if chunked into dist/
|
|
4516
|
+
"./prompts",
|
|
4517
|
+
// Production if inlined into dist/mcp/
|
|
4518
|
+
"../prompts",
|
|
4519
|
+
// Dev: /src/mcp/prompts/definitions (next to loader.ts)
|
|
4520
|
+
"./definitions"
|
|
4521
|
+
].map((relPath) => path5.resolve(__dirname2, relPath));
|
|
4522
|
+
for (const dir of candidates) {
|
|
4523
|
+
if (fs4.existsSync(dir)) {
|
|
4524
|
+
const files = fs4.readdirSync(dir);
|
|
4525
|
+
if (files.some((f) => f.endsWith(".md"))) {
|
|
4526
|
+
return dir;
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
}
|
|
4530
|
+
return path5.resolve(__dirname2, "./definitions");
|
|
4531
|
+
}
|
|
4532
|
+
var PROMPT_DIR = findPromptDir();
|
|
4533
|
+
function listPromptFiles() {
|
|
4534
|
+
if (!fs4.existsSync(PROMPT_DIR)) return [];
|
|
4535
|
+
return fs4.readdirSync(PROMPT_DIR).filter((file) => file.endsWith(".md")).map((file) => file.replace(/\.md$/, "")).sort();
|
|
4536
|
+
}
|
|
4537
|
+
function loadPromptFromMarkdown(name) {
|
|
4538
|
+
const filePath = path5.join(PROMPT_DIR, `${name}.md`);
|
|
4539
|
+
if (!fs4.existsSync(filePath)) {
|
|
4540
|
+
throw new Error(`Prompt file not found: ${filePath}`);
|
|
4541
|
+
}
|
|
4542
|
+
const fileContent = fs4.readFileSync(filePath, "utf-8");
|
|
4543
|
+
const { data, content } = matter(fileContent);
|
|
4544
|
+
return {
|
|
4545
|
+
name: data.name || name,
|
|
4546
|
+
description: data.description || "",
|
|
4547
|
+
arguments: data.arguments || [],
|
|
4548
|
+
agent: data.agent,
|
|
4549
|
+
content: content.trim()
|
|
4550
|
+
};
|
|
4551
|
+
}
|
|
4552
|
+
|
|
4553
|
+
// src/mcp/prompts/registry.ts
|
|
4554
|
+
function createPromptDefinition(loaded) {
|
|
4555
|
+
return {
|
|
4556
|
+
name: loaded.name,
|
|
4557
|
+
description: loaded.description,
|
|
4558
|
+
arguments: loaded.arguments,
|
|
4559
|
+
agent: loaded.agent,
|
|
4560
|
+
messages: [
|
|
4561
|
+
{
|
|
4562
|
+
role: "user",
|
|
4563
|
+
content: {
|
|
4564
|
+
type: "text",
|
|
4565
|
+
text: loaded.content
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
]
|
|
4569
|
+
};
|
|
4570
|
+
}
|
|
4571
|
+
var PROMPTS = {};
|
|
4572
|
+
var promptFiles = listPromptFiles();
|
|
4573
|
+
for (const name of promptFiles) {
|
|
4574
|
+
try {
|
|
4575
|
+
PROMPTS[name] = createPromptDefinition(loadPromptFromMarkdown(name));
|
|
4576
|
+
} catch (e) {
|
|
4577
|
+
logger.warn(`Failed to load prompt ${name}: ${e}`);
|
|
4578
|
+
}
|
|
4579
|
+
}
|
|
4580
|
+
async function listPrompts(db, session, params) {
|
|
4581
|
+
const allPrompts = Object.values(PROMPTS).map((p) => ({
|
|
4582
|
+
name: p.name,
|
|
4583
|
+
description: p.description,
|
|
4584
|
+
arguments: p.arguments,
|
|
4585
|
+
metadata: p.agent ? { agent: p.agent } : void 0
|
|
4586
|
+
}));
|
|
4587
|
+
const rawLimit = typeof params?.limit === "number" && Number.isInteger(params?.limit) ? params.limit : 25;
|
|
4588
|
+
const limit = Math.max(1, Math.min(100, Math.trunc(rawLimit)));
|
|
4589
|
+
const offset = decodeCursor(params?.cursor);
|
|
4590
|
+
const sliced = allPrompts.slice(offset, offset + limit);
|
|
4591
|
+
const nextOffset = offset + sliced.length;
|
|
4592
|
+
return {
|
|
4593
|
+
prompts: sliced,
|
|
4594
|
+
nextCursor: nextOffset < allPrompts.length ? encodeCursor(nextOffset) : void 0
|
|
4595
|
+
};
|
|
4596
|
+
}
|
|
4597
|
+
async function getPrompt(name, args = {}, db, session) {
|
|
4598
|
+
const prompt = PROMPTS[name];
|
|
4599
|
+
if (!prompt) {
|
|
4600
|
+
throw new Error(`Prompt not found: ${name}`);
|
|
4601
|
+
}
|
|
4602
|
+
const inferredRepo = inferRepoFromSession(session);
|
|
4603
|
+
const messages = prompt.messages.map((m) => {
|
|
4604
|
+
let text = m.content.text;
|
|
4605
|
+
for (const [key, value] of Object.entries(args)) {
|
|
4606
|
+
text = text.replace(new RegExp(`\\{{${key}\\}}`, "g"), value);
|
|
4607
|
+
}
|
|
4608
|
+
text = text.replace(/{{current_repo}}/g, inferredRepo || "unknown-repo");
|
|
4609
|
+
return {
|
|
4610
|
+
...m,
|
|
4611
|
+
content: {
|
|
4612
|
+
...m.content,
|
|
4613
|
+
text
|
|
4614
|
+
}
|
|
4615
|
+
};
|
|
4616
|
+
});
|
|
4617
|
+
return {
|
|
4618
|
+
description: prompt.description,
|
|
4619
|
+
messages,
|
|
4620
|
+
metadata: prompt.agent ? { agent: prompt.agent } : void 0
|
|
4621
|
+
};
|
|
4622
|
+
}
|
|
4623
|
+
async function completePromptArgument(name, argName, value, contextArguments, dataSources) {
|
|
4624
|
+
void name;
|
|
4625
|
+
void contextArguments;
|
|
4626
|
+
if (argName === "task_id") {
|
|
4627
|
+
const values = dataSources.tasks.map((t) => t.id);
|
|
4628
|
+
return rankCompletionValues(values, value);
|
|
4629
|
+
}
|
|
4630
|
+
return [];
|
|
4631
|
+
}
|
|
4586
4632
|
|
|
4587
4633
|
export {
|
|
4634
|
+
MCP_PROTOCOL_VERSION,
|
|
4635
|
+
CAPABILITIES,
|
|
4588
4636
|
logger,
|
|
4589
4637
|
setLogLevel,
|
|
4590
4638
|
getLogLevel,
|
|
4591
4639
|
addLogSink,
|
|
4592
4640
|
LOG_LEVEL_VALUES,
|
|
4593
4641
|
createFileSink,
|
|
4594
|
-
encodeCursor,
|
|
4595
|
-
decodeCursor,
|
|
4596
|
-
listResources,
|
|
4597
|
-
listResourceTemplates,
|
|
4598
|
-
completeResourceArgument,
|
|
4599
|
-
readResource,
|
|
4600
|
-
createSessionContext,
|
|
4601
|
-
updateSessionFromInitialize,
|
|
4602
|
-
updateSessionRoots,
|
|
4603
|
-
extractRootsFromResult,
|
|
4604
|
-
getFilesystemRoots,
|
|
4605
|
-
isPathWithinRoots,
|
|
4606
|
-
findContainingRoot,
|
|
4607
|
-
inferRepoFromSession,
|
|
4608
|
-
PROMPTS,
|
|
4609
|
-
listPrompts,
|
|
4610
|
-
getPrompt,
|
|
4611
|
-
completePromptArgument,
|
|
4612
4642
|
normalizeRepo,
|
|
4643
|
+
SQLiteStore,
|
|
4613
4644
|
MemoryStoreSchema,
|
|
4614
4645
|
MemoryUpdateSchema,
|
|
4615
4646
|
MemorySearchSchema,
|
|
@@ -4626,12 +4657,28 @@ export {
|
|
|
4626
4657
|
MemoryDetailSchema,
|
|
4627
4658
|
TaskGetSchema,
|
|
4628
4659
|
HandoffCreateSchema,
|
|
4660
|
+
HandoffUpdateSchema,
|
|
4629
4661
|
HandoffListSchema,
|
|
4630
4662
|
TaskClaimSchema,
|
|
4631
4663
|
StandardStoreSchema,
|
|
4632
4664
|
StandardSearchSchema,
|
|
4633
4665
|
TOOL_DEFINITIONS,
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4666
|
+
encodeCursor,
|
|
4667
|
+
decodeCursor,
|
|
4668
|
+
listResources,
|
|
4669
|
+
listResourceTemplates,
|
|
4670
|
+
completeResourceArgument,
|
|
4671
|
+
readResource,
|
|
4672
|
+
createSessionContext,
|
|
4673
|
+
updateSessionFromInitialize,
|
|
4674
|
+
updateSessionRoots,
|
|
4675
|
+
extractRootsFromResult,
|
|
4676
|
+
getFilesystemRoots,
|
|
4677
|
+
isPathWithinRoots,
|
|
4678
|
+
findContainingRoot,
|
|
4679
|
+
inferRepoFromSession,
|
|
4680
|
+
PROMPTS,
|
|
4681
|
+
listPrompts,
|
|
4682
|
+
getPrompt,
|
|
4683
|
+
completePromptArgument
|
|
4637
4684
|
};
|