@vheins/local-memory-mcp 0.19.18 → 0.19.19

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.
@@ -3462,10 +3462,94 @@ var RealVectorStore = class {
3462
3462
  }
3463
3463
  };
3464
3464
 
3465
- // src/mcp/session.ts
3465
+ // src/mcp/prompts/loader.ts
3466
3466
  import fs4 from "fs";
3467
3467
  import path3 from "path";
3468
3468
  import { fileURLToPath } from "url";
3469
+ import matter from "gray-matter";
3470
+ var __filename = fileURLToPath(import.meta.url);
3471
+ var __dirname = path3.dirname(__filename);
3472
+ function findPromptDir() {
3473
+ const candidates = [
3474
+ // Production if chunked into dist/
3475
+ "./prompts",
3476
+ // Production if inlined into dist/mcp/
3477
+ "../prompts",
3478
+ // Dev: /src/mcp/prompts/definitions (next to loader.ts)
3479
+ "./definitions"
3480
+ ].map((relPath) => path3.resolve(__dirname, relPath));
3481
+ for (const dir of candidates) {
3482
+ if (fs4.existsSync(dir)) {
3483
+ const files = fs4.readdirSync(dir);
3484
+ if (files.some((f) => f.endsWith(".md"))) {
3485
+ return dir;
3486
+ }
3487
+ }
3488
+ }
3489
+ return path3.resolve(__dirname, "./definitions");
3490
+ }
3491
+ var PROMPT_DIR = findPromptDir();
3492
+ var promptCache = /* @__PURE__ */ new Map();
3493
+ function listPromptFiles() {
3494
+ if (!fs4.existsSync(PROMPT_DIR)) return [];
3495
+ return fs4.readdirSync(PROMPT_DIR).filter((file) => file.endsWith(".md")).map((file) => file.replace(/\.md$/, "")).sort();
3496
+ }
3497
+ function loadPromptFromMarkdown(name) {
3498
+ const cached = promptCache.get(name);
3499
+ if (cached) return cached;
3500
+ const filePath = path3.join(PROMPT_DIR, `${name}.md`);
3501
+ if (!fs4.existsSync(filePath)) {
3502
+ throw new Error(`Prompt file not found: ${filePath}`);
3503
+ }
3504
+ const fileContent = fs4.readFileSync(filePath, "utf-8");
3505
+ const { data, content } = matter(fileContent);
3506
+ const result = {
3507
+ name: data.name || name,
3508
+ description: data.description || "",
3509
+ arguments: data.arguments || [],
3510
+ agent: data.agent,
3511
+ content: content.trim()
3512
+ };
3513
+ promptCache.set(name, result);
3514
+ return result;
3515
+ }
3516
+ function findServerInstructionsDir() {
3517
+ const candidates = [
3518
+ // Production if chunked into dist/
3519
+ "./prompts/server",
3520
+ // Production if inlined into dist/mcp/
3521
+ "../prompts/server",
3522
+ // Dev: /src/mcp/prompts/server (next to loader.ts)
3523
+ "./server"
3524
+ ].map((relPath) => path3.resolve(__dirname, relPath));
3525
+ for (const dir of candidates) {
3526
+ if (fs4.existsSync(dir)) {
3527
+ const filePath = path3.join(dir, "instructions.md");
3528
+ if (fs4.existsSync(filePath)) {
3529
+ return dir;
3530
+ }
3531
+ }
3532
+ }
3533
+ return path3.resolve(__dirname, "./server");
3534
+ }
3535
+ var SERVER_DIR = findServerInstructionsDir();
3536
+ var serverInstructionsCache = null;
3537
+ function loadServerInstructions() {
3538
+ if (serverInstructionsCache !== null) return serverInstructionsCache;
3539
+ const filePath = path3.join(SERVER_DIR, "instructions.md");
3540
+ if (!fs4.existsSync(filePath)) {
3541
+ throw new Error(`Server instructions file not found: ${filePath}`);
3542
+ }
3543
+ const fileContent = fs4.readFileSync(filePath, "utf-8");
3544
+ const { content } = matter(fileContent);
3545
+ serverInstructionsCache = content.trim();
3546
+ return serverInstructionsCache;
3547
+ }
3548
+
3549
+ // src/mcp/session.ts
3550
+ import fs5 from "fs";
3551
+ import path4 from "path";
3552
+ import { fileURLToPath as fileURLToPath2 } from "url";
3469
3553
  function createSessionContext() {
3470
3554
  return {
3471
3555
  roots: [],
@@ -3483,7 +3567,7 @@ function getFilesystemRoots(session) {
3483
3567
  for (const root of session.roots) {
3484
3568
  if (!root.uri.startsWith("file://")) continue;
3485
3569
  try {
3486
- resolved.push(path3.resolve(fileURLToPath(root.uri)));
3570
+ resolved.push(path4.resolve(fileURLToPath2(root.uri)));
3487
3571
  } catch {
3488
3572
  }
3489
3573
  }
@@ -3492,19 +3576,19 @@ function getFilesystemRoots(session) {
3492
3576
  function isPathWithinRoots(targetPath, session) {
3493
3577
  const roots = getFilesystemRoots(session);
3494
3578
  if (roots.length === 0) return true;
3495
- const normalizedTarget = path3.resolve(targetPath);
3579
+ const normalizedTarget = path4.resolve(targetPath);
3496
3580
  return roots.some((rootPath) => {
3497
- const relative = path3.relative(rootPath, normalizedTarget);
3498
- return relative === "" || !relative.startsWith("..") && !path3.isAbsolute(relative);
3581
+ const relative = path4.relative(rootPath, normalizedTarget);
3582
+ return relative === "" || !relative.startsWith("..") && !path4.isAbsolute(relative);
3499
3583
  });
3500
3584
  }
3501
3585
  function findContainingRoot(targetPath, session) {
3502
3586
  const roots = getFilesystemRoots(session);
3503
3587
  if (roots.length === 0) return null;
3504
- const normalizedTarget = path3.resolve(targetPath);
3588
+ const normalizedTarget = path4.resolve(targetPath);
3505
3589
  for (const rootPath of roots) {
3506
- const relative = path3.relative(rootPath, normalizedTarget);
3507
- if (relative === "" || !relative.startsWith("..") && !path3.isAbsolute(relative)) {
3590
+ const relative = path4.relative(rootPath, normalizedTarget);
3591
+ if (relative === "" || !relative.startsWith("..") && !path4.isAbsolute(relative)) {
3508
3592
  return rootPath;
3509
3593
  }
3510
3594
  }
@@ -3513,20 +3597,20 @@ function findContainingRoot(targetPath, session) {
3513
3597
  function inferRepoFromSession(session) {
3514
3598
  const roots = getFilesystemRoots(session);
3515
3599
  if (roots.length === 1) {
3516
- return path3.basename(roots[0]);
3600
+ return path4.basename(roots[0]);
3517
3601
  }
3518
3602
  if (roots.length === 0) {
3519
3603
  if (!session) return void 0;
3520
3604
  const cwd = process.cwd();
3521
- return path3.basename(cwd);
3605
+ return path4.basename(cwd);
3522
3606
  }
3523
3607
  return void 0;
3524
3608
  }
3525
3609
  function inferOwnerFromGit(cwd) {
3526
3610
  try {
3527
- const gitConfigPath = path3.join(cwd, ".git", "config");
3528
- if (!fs4.existsSync(gitConfigPath)) return void 0;
3529
- const content = fs4.readFileSync(gitConfigPath, "utf-8");
3611
+ const gitConfigPath = path4.join(cwd, ".git", "config");
3612
+ if (!fs5.existsSync(gitConfigPath)) return void 0;
3613
+ const content = fs5.readFileSync(gitConfigPath, "utf-8");
3530
3614
  const match = content.match(
3531
3615
  /url\s*=\s*(?:git@github\.com:|https?:\/\/github\.com\/|git:\/\/github\.com\/)([^\/\s]+)/
3532
3616
  );
@@ -3548,7 +3632,7 @@ function inferOwnerFromSession(session) {
3548
3632
  if (gitOwner) return gitOwner;
3549
3633
  }
3550
3634
  if (roots.length === 1) {
3551
- const parts = roots[0].split(path3.sep).filter(Boolean);
3635
+ const parts = roots[0].split(path4.sep).filter(Boolean);
3552
3636
  if (parts.length >= 2) {
3553
3637
  return parts[parts.length - 2];
3554
3638
  }
@@ -3556,7 +3640,7 @@ function inferOwnerFromSession(session) {
3556
3640
  if (roots.length === 0) {
3557
3641
  if (!session) return void 0;
3558
3642
  const workdir = process.cwd();
3559
- const parts = workdir.split(path3.sep).filter(Boolean);
3643
+ const parts = workdir.split(path4.sep).filter(Boolean);
3560
3644
  if (parts.length >= 2) {
3561
3645
  return parts[parts.length - 2];
3562
3646
  }
@@ -3564,90 +3648,6 @@ function inferOwnerFromSession(session) {
3564
3648
  return void 0;
3565
3649
  }
3566
3650
 
3567
- // src/mcp/prompts/loader.ts
3568
- import fs5 from "fs";
3569
- import path4 from "path";
3570
- import { fileURLToPath as fileURLToPath2 } from "url";
3571
- import matter from "gray-matter";
3572
- var __filename = fileURLToPath2(import.meta.url);
3573
- var __dirname = path4.dirname(__filename);
3574
- function findPromptDir() {
3575
- const candidates = [
3576
- // Production if chunked into dist/
3577
- "./prompts",
3578
- // Production if inlined into dist/mcp/
3579
- "../prompts",
3580
- // Dev: /src/mcp/prompts/definitions (next to loader.ts)
3581
- "./definitions"
3582
- ].map((relPath) => path4.resolve(__dirname, relPath));
3583
- for (const dir of candidates) {
3584
- if (fs5.existsSync(dir)) {
3585
- const files = fs5.readdirSync(dir);
3586
- if (files.some((f) => f.endsWith(".md"))) {
3587
- return dir;
3588
- }
3589
- }
3590
- }
3591
- return path4.resolve(__dirname, "./definitions");
3592
- }
3593
- var PROMPT_DIR = findPromptDir();
3594
- var promptCache = /* @__PURE__ */ new Map();
3595
- function listPromptFiles() {
3596
- if (!fs5.existsSync(PROMPT_DIR)) return [];
3597
- return fs5.readdirSync(PROMPT_DIR).filter((file) => file.endsWith(".md")).map((file) => file.replace(/\.md$/, "")).sort();
3598
- }
3599
- function loadPromptFromMarkdown(name) {
3600
- const cached = promptCache.get(name);
3601
- if (cached) return cached;
3602
- const filePath = path4.join(PROMPT_DIR, `${name}.md`);
3603
- if (!fs5.existsSync(filePath)) {
3604
- throw new Error(`Prompt file not found: ${filePath}`);
3605
- }
3606
- const fileContent = fs5.readFileSync(filePath, "utf-8");
3607
- const { data, content } = matter(fileContent);
3608
- const result = {
3609
- name: data.name || name,
3610
- description: data.description || "",
3611
- arguments: data.arguments || [],
3612
- agent: data.agent,
3613
- content: content.trim()
3614
- };
3615
- promptCache.set(name, result);
3616
- return result;
3617
- }
3618
- function findServerInstructionsDir() {
3619
- const candidates = [
3620
- // Production if chunked into dist/
3621
- "./prompts/server",
3622
- // Production if inlined into dist/mcp/
3623
- "../prompts/server",
3624
- // Dev: /src/mcp/prompts/server (next to loader.ts)
3625
- "./server"
3626
- ].map((relPath) => path4.resolve(__dirname, relPath));
3627
- for (const dir of candidates) {
3628
- if (fs5.existsSync(dir)) {
3629
- const filePath = path4.join(dir, "instructions.md");
3630
- if (fs5.existsSync(filePath)) {
3631
- return dir;
3632
- }
3633
- }
3634
- }
3635
- return path4.resolve(__dirname, "./server");
3636
- }
3637
- var SERVER_DIR = findServerInstructionsDir();
3638
- var serverInstructionsCache = null;
3639
- function loadServerInstructions() {
3640
- if (serverInstructionsCache !== null) return serverInstructionsCache;
3641
- const filePath = path4.join(SERVER_DIR, "instructions.md");
3642
- if (!fs5.existsSync(filePath)) {
3643
- throw new Error(`Server instructions file not found: ${filePath}`);
3644
- }
3645
- const fileContent = fs5.readFileSync(filePath, "utf-8");
3646
- const { content } = matter(fileContent);
3647
- serverInstructionsCache = content.trim();
3648
- return serverInstructionsCache;
3649
- }
3650
-
3651
3651
  // src/mcp/tools/definitions/memory.ts
3652
3652
  var MEMORY_TOOL_DEFINITIONS = [
3653
3653
  {
@@ -6336,164 +6336,6 @@ var TOOL_DEFINITIONS = [
6336
6336
  ...KG_TOOL_DEFINITIONS
6337
6337
  ];
6338
6338
 
6339
- // src/mcp/utils/completion.ts
6340
- var MAX_COMPLETION_VALUES = 100;
6341
- function rankCompletionValues(candidates, input) {
6342
- const unique = [...new Set(candidates.filter(Boolean))];
6343
- const needle = input.trim().toLowerCase();
6344
- if (!needle) {
6345
- return unique.slice(0, MAX_COMPLETION_VALUES);
6346
- }
6347
- 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);
6348
- }
6349
- function scoreCompletionValue(value, needle) {
6350
- const haystack = value.toLowerCase();
6351
- if (haystack === needle) return 100;
6352
- if (haystack.startsWith(needle)) return 75;
6353
- if (haystack.includes(needle)) return 50;
6354
- const compactNeedle = needle.replace(/[\s_-]+/g, "");
6355
- const compactHaystack = haystack.replace(/[\s_-]+/g, "");
6356
- if (compactNeedle && compactHaystack.includes(compactNeedle)) return 25;
6357
- return 0;
6358
- }
6359
-
6360
- // src/mcp/utils/pagination.ts
6361
- function encodeCursor(offset) {
6362
- return Buffer.from(String(offset), "utf8").toString("base64");
6363
- }
6364
- function decodeCursor(cursor) {
6365
- if (cursor === void 0 || cursor === null || cursor === "") {
6366
- return 0;
6367
- }
6368
- if (typeof cursor !== "string" || cursor.trim() === "") {
6369
- throw invalidPaginationParams("Invalid cursor");
6370
- }
6371
- let decoded;
6372
- try {
6373
- decoded = Buffer.from(cursor, "base64").toString("utf8");
6374
- } catch {
6375
- throw invalidPaginationParams("Invalid cursor");
6376
- }
6377
- if (!/^\d+$/.test(decoded)) {
6378
- throw invalidPaginationParams("Invalid cursor");
6379
- }
6380
- const offset = Number.parseInt(decoded, 10);
6381
- if (!Number.isFinite(offset) || offset < 0) {
6382
- throw invalidPaginationParams("Invalid cursor");
6383
- }
6384
- return offset;
6385
- }
6386
- function invalidPaginationParams(message) {
6387
- const error = new Error(message);
6388
- error.code = -32602;
6389
- return error;
6390
- }
6391
-
6392
- // src/mcp/resources/index.ts
6393
- var DEFAULT_PAGE_SIZE = 25;
6394
- var MAX_PAGE_SIZE = 100;
6395
- function listResources(session, params) {
6396
- const resources = [
6397
- {
6398
- uri: "repository://index",
6399
- name: "Repository Index",
6400
- title: "Repository Index",
6401
- description: "List of all known repositories with memory/task counts and last activity",
6402
- mimeType: "application/json",
6403
- annotations: {
6404
- audience: ["assistant"],
6405
- priority: 1,
6406
- lastModified: (/* @__PURE__ */ new Date()).toISOString()
6407
- }
6408
- },
6409
- {
6410
- uri: "session://roots",
6411
- name: "Session Roots",
6412
- title: "Session Roots",
6413
- description: session?.roots.length ? "Active workspace roots provided by the MCP client" : "No active workspace roots were provided by the MCP client",
6414
- mimeType: "application/json",
6415
- size: Buffer.byteLength(JSON.stringify({ roots: session?.roots ?? [] }), "utf8"),
6416
- annotations: {
6417
- audience: ["assistant"],
6418
- priority: 0.95,
6419
- lastModified: (/* @__PURE__ */ new Date()).toISOString()
6420
- }
6421
- }
6422
- ];
6423
- return paginateEntries("resources", resources, params);
6424
- }
6425
- function completeResourceArgument(resourceUri, argumentName, argumentValue, _contextArguments, dataSources) {
6426
- 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") {
6427
- if (argumentName === "name") {
6428
- return rankCompletionValues(dataSources.repos, argumentValue);
6429
- }
6430
- }
6431
- if (resourceUri === "repository://{name}/memories?search={search}&type={type}&tag={tag}") {
6432
- if (argumentName === "tag") {
6433
- return rankCompletionValues(dataSources.tags, argumentValue);
6434
- }
6435
- }
6436
- throw invalidCompletionParams(`Unknown resource template or argument: ${resourceUri} (${argumentName})`);
6437
- }
6438
- function paginateEntries(key, entries, params) {
6439
- const limit = normalizeLimit(params?.limit);
6440
- const offset = decodeCursor(params?.cursor);
6441
- const sliced = entries.slice(offset, offset + limit);
6442
- const nextOffset = offset + sliced.length;
6443
- return {
6444
- [key]: sliced,
6445
- nextCursor: nextOffset < entries.length ? encodeCursor(nextOffset) : void 0
6446
- };
6447
- }
6448
- function normalizeLimit(limit) {
6449
- if (typeof limit !== "number" || !Number.isFinite(limit)) {
6450
- return DEFAULT_PAGE_SIZE;
6451
- }
6452
- return Math.min(MAX_PAGE_SIZE, Math.max(1, Math.trunc(limit)));
6453
- }
6454
- function invalidCompletionParams(message) {
6455
- const error = new Error(message);
6456
- error.code = -32602;
6457
- return error;
6458
- }
6459
-
6460
- // src/mcp/prompts/registry.ts
6461
- function createPromptDefinition(loaded) {
6462
- return {
6463
- name: loaded.name,
6464
- description: loaded.description,
6465
- arguments: loaded.arguments,
6466
- agent: loaded.agent,
6467
- messages: [
6468
- {
6469
- role: "user",
6470
- content: {
6471
- type: "text",
6472
- text: loaded.content
6473
- }
6474
- }
6475
- ]
6476
- };
6477
- }
6478
- var PROMPTS = {};
6479
- var promptFiles = listPromptFiles();
6480
- for (const name of promptFiles) {
6481
- try {
6482
- PROMPTS[name] = createPromptDefinition(loadPromptFromMarkdown(name));
6483
- } catch (e) {
6484
- logger.warn(`Failed to load prompt ${name}: ${e}`);
6485
- }
6486
- }
6487
- async function completePromptArgument(name, argName, value, contextArguments, dataSources) {
6488
- void name;
6489
- void contextArguments;
6490
- if (argName === "task_id") {
6491
- const values = dataSources.tasks.map((t) => t.id);
6492
- return rankCompletionValues(values, value);
6493
- }
6494
- return [];
6495
- }
6496
-
6497
6339
  // src/mcp/tools/handoff.manage.ts
6498
6340
  import { randomUUID as randomUUID2 } from "crypto";
6499
6341
 
@@ -7532,6 +7374,164 @@ async function handleClaimRelease(args, storage) {
7532
7374
  });
7533
7375
  }
7534
7376
 
7377
+ // src/mcp/utils/completion.ts
7378
+ var MAX_COMPLETION_VALUES = 100;
7379
+ function rankCompletionValues(candidates, input) {
7380
+ const unique = [...new Set(candidates.filter(Boolean))];
7381
+ const needle = input.trim().toLowerCase();
7382
+ if (!needle) {
7383
+ return unique.slice(0, MAX_COMPLETION_VALUES);
7384
+ }
7385
+ 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);
7386
+ }
7387
+ function scoreCompletionValue(value, needle) {
7388
+ const haystack = value.toLowerCase();
7389
+ if (haystack === needle) return 100;
7390
+ if (haystack.startsWith(needle)) return 75;
7391
+ if (haystack.includes(needle)) return 50;
7392
+ const compactNeedle = needle.replace(/[\s_-]+/g, "");
7393
+ const compactHaystack = haystack.replace(/[\s_-]+/g, "");
7394
+ if (compactNeedle && compactHaystack.includes(compactNeedle)) return 25;
7395
+ return 0;
7396
+ }
7397
+
7398
+ // src/mcp/utils/pagination.ts
7399
+ function encodeCursor(offset) {
7400
+ return Buffer.from(String(offset), "utf8").toString("base64");
7401
+ }
7402
+ function decodeCursor(cursor) {
7403
+ if (cursor === void 0 || cursor === null || cursor === "") {
7404
+ return 0;
7405
+ }
7406
+ if (typeof cursor !== "string" || cursor.trim() === "") {
7407
+ throw invalidPaginationParams("Invalid cursor");
7408
+ }
7409
+ let decoded;
7410
+ try {
7411
+ decoded = Buffer.from(cursor, "base64").toString("utf8");
7412
+ } catch {
7413
+ throw invalidPaginationParams("Invalid cursor");
7414
+ }
7415
+ if (!/^\d+$/.test(decoded)) {
7416
+ throw invalidPaginationParams("Invalid cursor");
7417
+ }
7418
+ const offset = Number.parseInt(decoded, 10);
7419
+ if (!Number.isFinite(offset) || offset < 0) {
7420
+ throw invalidPaginationParams("Invalid cursor");
7421
+ }
7422
+ return offset;
7423
+ }
7424
+ function invalidPaginationParams(message) {
7425
+ const error = new Error(message);
7426
+ error.code = -32602;
7427
+ return error;
7428
+ }
7429
+
7430
+ // src/mcp/prompts/registry.ts
7431
+ function createPromptDefinition(loaded) {
7432
+ return {
7433
+ name: loaded.name,
7434
+ description: loaded.description,
7435
+ arguments: loaded.arguments,
7436
+ agent: loaded.agent,
7437
+ messages: [
7438
+ {
7439
+ role: "user",
7440
+ content: {
7441
+ type: "text",
7442
+ text: loaded.content
7443
+ }
7444
+ }
7445
+ ]
7446
+ };
7447
+ }
7448
+ var PROMPTS = {};
7449
+ var promptFiles = listPromptFiles();
7450
+ for (const name of promptFiles) {
7451
+ try {
7452
+ PROMPTS[name] = createPromptDefinition(loadPromptFromMarkdown(name));
7453
+ } catch (e) {
7454
+ logger.warn(`Failed to load prompt ${name}: ${e}`);
7455
+ }
7456
+ }
7457
+ async function completePromptArgument(name, argName, value, contextArguments, dataSources) {
7458
+ void name;
7459
+ void contextArguments;
7460
+ if (argName === "task_id") {
7461
+ const values = dataSources.tasks.map((t) => t.id);
7462
+ return rankCompletionValues(values, value);
7463
+ }
7464
+ return [];
7465
+ }
7466
+
7467
+ // src/mcp/resources/index.ts
7468
+ var DEFAULT_PAGE_SIZE = 25;
7469
+ var MAX_PAGE_SIZE = 100;
7470
+ function listResources(session, params) {
7471
+ const resources = [
7472
+ {
7473
+ uri: "repository://index",
7474
+ name: "Repository Index",
7475
+ title: "Repository Index",
7476
+ description: "List of all known repositories with memory/task counts and last activity",
7477
+ mimeType: "application/json",
7478
+ annotations: {
7479
+ audience: ["assistant"],
7480
+ priority: 1,
7481
+ lastModified: (/* @__PURE__ */ new Date()).toISOString()
7482
+ }
7483
+ },
7484
+ {
7485
+ uri: "session://roots",
7486
+ name: "Session Roots",
7487
+ title: "Session Roots",
7488
+ description: session?.roots.length ? "Active workspace roots provided by the MCP client" : "No active workspace roots were provided by the MCP client",
7489
+ mimeType: "application/json",
7490
+ size: Buffer.byteLength(JSON.stringify({ roots: session?.roots ?? [] }), "utf8"),
7491
+ annotations: {
7492
+ audience: ["assistant"],
7493
+ priority: 0.95,
7494
+ lastModified: (/* @__PURE__ */ new Date()).toISOString()
7495
+ }
7496
+ }
7497
+ ];
7498
+ return paginateEntries("resources", resources, params);
7499
+ }
7500
+ function completeResourceArgument(resourceUri, argumentName, argumentValue, _contextArguments, dataSources) {
7501
+ 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") {
7502
+ if (argumentName === "name") {
7503
+ return rankCompletionValues(dataSources.repos, argumentValue);
7504
+ }
7505
+ }
7506
+ if (resourceUri === "repository://{name}/memories?search={search}&type={type}&tag={tag}") {
7507
+ if (argumentName === "tag") {
7508
+ return rankCompletionValues(dataSources.tags, argumentValue);
7509
+ }
7510
+ }
7511
+ throw invalidCompletionParams(`Unknown resource template or argument: ${resourceUri} (${argumentName})`);
7512
+ }
7513
+ function paginateEntries(key, entries, params) {
7514
+ const limit = normalizeLimit(params?.limit);
7515
+ const offset = decodeCursor(params?.cursor);
7516
+ const sliced = entries.slice(offset, offset + limit);
7517
+ const nextOffset = offset + sliced.length;
7518
+ return {
7519
+ [key]: sliced,
7520
+ nextCursor: nextOffset < entries.length ? encodeCursor(nextOffset) : void 0
7521
+ };
7522
+ }
7523
+ function normalizeLimit(limit) {
7524
+ if (typeof limit !== "number" || !Number.isFinite(limit)) {
7525
+ return DEFAULT_PAGE_SIZE;
7526
+ }
7527
+ return Math.min(MAX_PAGE_SIZE, Math.max(1, Math.trunc(limit)));
7528
+ }
7529
+ function invalidCompletionParams(message) {
7530
+ const error = new Error(message);
7531
+ error.code = -32602;
7532
+ return error;
7533
+ }
7534
+
7535
7535
  // src/mcp/tools/standard.shared.ts
7536
7536
  function toContextSlug(value) {
7537
7537
  return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -7550,30 +7550,20 @@ function buildStandardVectorText(standard) {
7550
7550
  }
7551
7551
 
7552
7552
  export {
7553
- logger,
7554
- addLogSink,
7555
- createFileSink,
7556
- parseRepoInput,
7557
- normalizeRepo,
7558
- SQLiteStore,
7559
- RealVectorStore,
7560
- TOOL_DEFINITIONS,
7561
- rankCompletionValues,
7562
- listResources,
7563
- completeResourceArgument,
7553
+ listPromptFiles,
7554
+ loadPromptFromMarkdown,
7555
+ loadServerInstructions,
7564
7556
  createSessionContext,
7565
7557
  getFilesystemRoots,
7566
7558
  isPathWithinRoots,
7567
7559
  findContainingRoot,
7568
7560
  inferRepoFromSession,
7569
7561
  inferOwnerFromSession,
7570
- listPromptFiles,
7571
- loadPromptFromMarkdown,
7572
- loadServerInstructions,
7573
- PROMPTS,
7574
- completePromptArgument,
7575
- createMcpResponse,
7576
- getPrimaryTextContent,
7562
+ logger,
7563
+ addLogSink,
7564
+ createFileSink,
7565
+ parseRepoInput,
7566
+ normalizeRepo,
7577
7567
  TaskStatusSchema,
7578
7568
  MemoryStoreSchema,
7579
7569
  MemoryUpdateSchema,
@@ -7605,6 +7595,9 @@ export {
7605
7595
  DeleteRelationSchema,
7606
7596
  DeleteObservationSchema,
7607
7597
  KGBackfillSchema,
7598
+ TOOL_DEFINITIONS,
7599
+ createMcpResponse,
7600
+ getPrimaryTextContent,
7608
7601
  UUID_REGEX,
7609
7602
  handleHandoffCreate,
7610
7603
  handleHandoffList,
@@ -7613,5 +7606,12 @@ export {
7613
7606
  handleClaimList,
7614
7607
  handleClaimRelease,
7615
7608
  toContextSlug,
7616
- buildStandardVectorText
7609
+ buildStandardVectorText,
7610
+ rankCompletionValues,
7611
+ PROMPTS,
7612
+ completePromptArgument,
7613
+ listResources,
7614
+ completeResourceArgument,
7615
+ SQLiteStore,
7616
+ RealVectorStore
7617
7617
  };