@vheins/local-memory-mcp 0.19.16 → 0.19.18

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.
@@ -3896,7 +3896,7 @@ var MEMORY_TOOL_DEFINITIONS = [
3896
3896
  {
3897
3897
  name: "memory-acknowledge",
3898
3898
  title: "Memory Acknowledge",
3899
- description: "Acknowledge the use of a memory or report its irrelevance/contradiction. Mandatory after using memory to generate code.",
3899
+ description: 'Acknowledge the use of a memory or report its irrelevance/contradiction. Mandatory after using memory to generate code. Example: { code: "MEM-123", status: "used" } or { code: "MEM-123", status: "irrelevant" }.',
3900
3900
  annotations: {
3901
3901
  readOnlyHint: false,
3902
3902
  idempotentHint: false,
@@ -6737,7 +6737,9 @@ var MemoryAcknowledgeSchema = z3.object({
6737
6737
  code: z3.string().max(20).optional(),
6738
6738
  owner: z3.string().min(1),
6739
6739
  repo: z3.string().min(1).transform(normalizeRepo),
6740
- status: z3.enum(["used", "irrelevant", "contradictory"]),
6740
+ status: z3.enum(["used", "irrelevant", "contradictory"]).describe(
6741
+ `Usage status. Use "used" after generating code from a memory, "irrelevant" if the memory didn't help, or "contradictory" if it conflicts with current understanding.`
6742
+ ),
6741
6743
  application_context: z3.string().min(10).optional(),
6742
6744
  structured: z3.boolean().default(false)
6743
6745
  }).refine((data) => data.memory_id !== void 0 || data.code !== void 0, {
@@ -15,7 +15,7 @@ import {
15
15
  handleTaskClaim,
16
16
  listResources,
17
17
  logger
18
- } from "../chunk-ZG2WJU7H.js";
18
+ } from "../chunk-7O3T3GQF.js";
19
19
 
20
20
  // src/dashboard/server.ts
21
21
  import express from "express";
@@ -62,7 +62,7 @@ import {
62
62
  parseRepoInput,
63
63
  rankCompletionValues,
64
64
  toContextSlug
65
- } from "../chunk-ZG2WJU7H.js";
65
+ } from "../chunk-7O3T3GQF.js";
66
66
 
67
67
  // src/mcp/server.ts
68
68
  import { serveStdio } from "@modelcontextprotocol/server/stdio";
@@ -75,8 +75,8 @@ import path from "path";
75
75
  import { fileURLToPath } from "url";
76
76
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
77
77
  var pkgVersion = "0.1.0";
78
- if ("0.19.16") {
79
- pkgVersion = "0.19.16";
78
+ if ("0.19.18") {
79
+ pkgVersion = "0.19.18";
80
80
  } else {
81
81
  let searchDir = __dirname;
82
82
  for (let i = 0; i < 5; i++) {
@@ -123,6 +123,7 @@ import { z } from "zod";
123
123
  import { randomUUID as randomUUID2 } from "crypto";
124
124
 
125
125
  // src/mcp/utils/code-generator.ts
126
+ import { randomBytes } from "crypto";
126
127
  var ENTITY_CONFIG = {
127
128
  task: { prefix: "TASK", table: "tasks", column: "task_code" },
128
129
  memory: { prefix: "MEM", table: "memories", column: "code" },
@@ -152,6 +153,38 @@ function generateNextCode(owner, repo, entityType, storage, batchCodes) {
152
153
  }
153
154
  return `${config.prefix}-${String(nextSeq).padStart(3, "0")}`;
154
155
  }
156
+ function resolveEntityCode(preferredCode, owner, repo, entityType, storage, options) {
157
+ const { batchCodes } = options ?? {};
158
+ if (!preferredCode) {
159
+ const code = generateNextCode(owner, repo, entityType, storage, batchCodes);
160
+ if (batchCodes) batchCodes.add(code);
161
+ return code;
162
+ }
163
+ const isTaken = (code) => {
164
+ if (batchCodes?.has(code)) return true;
165
+ switch (entityType) {
166
+ case "task":
167
+ return storage.tasks.isTaskCodeDuplicate(owner, repo, code);
168
+ case "memory":
169
+ return storage.memories.getByCode(code, owner, repo) !== null;
170
+ case "standard":
171
+ return storage.standards.getByCode(code, owner, repo) !== null;
172
+ }
173
+ };
174
+ if (!isTaken(preferredCode)) {
175
+ if (batchCodes) batchCodes.add(preferredCode);
176
+ return preferredCode;
177
+ }
178
+ for (let attempt = 0; attempt < 20; attempt++) {
179
+ const suffix = randomBytes(2).toString("hex");
180
+ const candidate = `${preferredCode}-${suffix}`;
181
+ if (!isTaken(candidate)) {
182
+ if (batchCodes) batchCodes.add(candidate);
183
+ return candidate;
184
+ }
185
+ }
186
+ return generateNextCode(owner, repo, entityType, storage, batchCodes);
187
+ }
155
188
 
156
189
  // src/mcp/tools/kg-archivist.ts
157
190
  import { randomUUID } from "crypto";
@@ -478,7 +511,7 @@ async function storeSingleMemory(params, db2, vectors2) {
478
511
  }
479
512
  const entry = {
480
513
  id: randomUUID2(),
481
- code: params.code || generateNextCode(params.scope.owner ?? "", params.scope.repo, "memory", db2),
514
+ code: resolveEntityCode(params.code, params.scope.owner ?? "", params.scope.repo, "memory", db2),
482
515
  type: params.type,
483
516
  title: params.title,
484
517
  content: params.content,
@@ -578,8 +611,9 @@ async function handleMemoryStore(params, db2, vectors2) {
578
611
  if (mem.scope.language && !tags.includes(mem.scope.language.toLowerCase())) {
579
612
  tags.push(mem.scope.language.toLowerCase());
580
613
  }
581
- const code = mem.code || generateNextCode(mem.scope.owner ?? "", mem.scope.repo, "memory", db2, batchCodes);
582
- batchCodes.add(code);
614
+ const code = resolveEntityCode(mem.code || null, mem.scope.owner ?? "", mem.scope.repo, "memory", db2, {
615
+ batchCodes
616
+ });
583
617
  entries.push({
584
618
  id: randomUUID2(),
585
619
  code,
@@ -2371,14 +2405,6 @@ async function handleTaskCreate(args, storage) {
2371
2405
  const now2 = (/* @__PURE__ */ new Date()).toISOString();
2372
2406
  const codesInRequest = /* @__PURE__ */ new Set();
2373
2407
  const batchCodes = /* @__PURE__ */ new Set();
2374
- for (const taskData of bulkTasks) {
2375
- if (!taskData.task_code) {
2376
- taskData.task_code = generateNextCode(owner ?? "", repo, "task", storage, batchCodes);
2377
- }
2378
- batchCodes.add(taskData.task_code);
2379
- }
2380
- const allCodes = bulkTasks.map((t) => t.task_code);
2381
- const existingCodes = storage.tasks.getExistingTaskCodes(owner, repo, allCodes);
2382
2408
  const initialStats = storage.taskStats.getTaskStats(owner, repo);
2383
2409
  let pendingInRequestCount = 0;
2384
2410
  const localCodeMap = /* @__PURE__ */ new Map();
@@ -2386,15 +2412,10 @@ async function handleTaskCreate(args, storage) {
2386
2412
  localCodeMap.set(taskData.task_code, randomUUID4());
2387
2413
  }
2388
2414
  for (const taskData of bulkTasks) {
2389
- const code = taskData.task_code;
2415
+ const code = resolveEntityCode(taskData.task_code ?? null, owner ?? "", repo, "task", storage, { batchCodes });
2390
2416
  if (codesInRequest.has(code)) {
2391
2417
  throw new Error(`Duplicate task_code in request: '${code}'`);
2392
2418
  }
2393
- if (existingCodes.has(code)) {
2394
- throw new Error(
2395
- `Duplicate task_code: '${code}' already exists in repository '${repo}'. Omit task_code to auto-generate, or use task-list/task-search to find available codes.`
2396
- );
2397
- }
2398
2419
  codesInRequest.add(code);
2399
2420
  let normalizedStatus = taskData.status || "backlog";
2400
2421
  if (normalizedStatus !== "backlog" && normalizedStatus !== "pending") {
@@ -2472,12 +2493,7 @@ async function handleTaskCreate(args, storage) {
2472
2493
  throw new Error("Missing required fields for single task creation (phase, title, description)");
2473
2494
  }
2474
2495
  let effectiveStatus = requestedStatus || "backlog";
2475
- const resolvedCode = task_code || generateNextCode(owner ?? "", repo, "task", storage);
2476
- if (storage.tasks.isTaskCodeDuplicate(owner, repo, resolvedCode)) {
2477
- throw new Error(
2478
- `Duplicate task_code: '${resolvedCode}' already exists in repository '${repo}'. Omit task_code to auto-generate, or use task-list/task-search to find available codes.`
2479
- );
2480
- }
2496
+ const resolvedCode = resolveEntityCode(task_code, owner ?? "", repo, "task", storage);
2481
2497
  if (requestedStatus !== "backlog" && requestedStatus !== "pending" && requestedStatus !== void 0) {
2482
2498
  throw new Error("New tasks must be created with status 'backlog' or 'pending'.");
2483
2499
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vheins/local-memory-mcp",
3
- "version": "0.19.16",
3
+ "version": "0.19.18",
4
4
  "description": "MCP Local Memory Service for coding copilot agents",
5
5
  "mcpName": "io.github.vheins/local-memory-mcp",
6
6
  "type": "module",