@vheins/local-memory-mcp 0.19.13 → 0.19.14

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.
@@ -6690,7 +6690,7 @@ var MemoryStoreSchema = z3.object({
6690
6690
  memories: z3.array(SingleMemorySchema).min(1).optional()
6691
6691
  });
6692
6692
  var MemoryUpdateSchema = z3.object({
6693
- id: z3.string().uuid().optional(),
6693
+ id: z3.string().optional(),
6694
6694
  code: z3.string().max(20).optional(),
6695
6695
  owner: z3.string().min(1),
6696
6696
  repo: z3.string().min(1).transform(normalizeRepo),
@@ -6730,7 +6730,7 @@ var MemorySearchSchema = z3.object({
6730
6730
  structured: z3.boolean().default(false)
6731
6731
  });
6732
6732
  var MemoryAcknowledgeSchema = z3.object({
6733
- memory_id: z3.string().uuid().optional(),
6733
+ memory_id: z3.string().optional(),
6734
6734
  code: z3.string().max(20).optional(),
6735
6735
  owner: z3.string().min(1),
6736
6736
  repo: z3.string().min(1).transform(normalizeRepo),
@@ -6750,8 +6750,8 @@ var MemoryRecapSchema = z3.object({
6750
6750
  var MemoryDeleteSchema = z3.object({
6751
6751
  owner: z3.string().min(1),
6752
6752
  repo: z3.string().min(1).transform(normalizeRepo),
6753
- id: z3.string().uuid().optional(),
6754
- ids: z3.array(z3.string().uuid()).min(1).optional(),
6753
+ id: z3.string().optional(),
6754
+ ids: z3.array(z3.string()).min(1).optional(),
6755
6755
  code: z3.string().max(20).optional(),
6756
6756
  codes: z3.array(z3.string().max(20)).min(1).optional(),
6757
6757
  structured: z3.boolean().default(false)
@@ -6762,7 +6762,7 @@ var MemoryDeleteSchema = z3.object({
6762
6762
  }
6763
6763
  );
6764
6764
  var MemoryDetailSchema = z3.object({
6765
- id: z3.string().uuid().optional(),
6765
+ id: z3.string().optional(),
6766
6766
  code: z3.string().max(20).optional(),
6767
6767
  owner: z3.string().min(1),
6768
6768
  repo: z3.string().min(1).transform(normalizeRepo),
@@ -6899,8 +6899,8 @@ var TaskCreateInteractiveSchema = SingleTaskCreateSchema.partial().extend({
6899
6899
  var TaskUpdateSchema = z4.object({
6900
6900
  owner: z4.string().min(1),
6901
6901
  repo: z4.string().min(1).transform(normalizeRepo),
6902
- id: z4.string().uuid().optional(),
6903
- ids: z4.array(z4.string().uuid()).min(1).optional(),
6902
+ id: z4.string().optional(),
6903
+ ids: z4.array(z4.string()).min(1).optional(),
6904
6904
  task_code: z4.string().optional(),
6905
6905
  task_codes: z4.array(z4.string().min(1)).min(1).optional(),
6906
6906
  phase: z4.string().optional(),
@@ -6926,7 +6926,7 @@ var TaskUpdateSchema = z4.object({
6926
6926
  }).refine(
6927
6927
  (data) => data.id !== void 0 || data.ids !== void 0 || data.task_code !== void 0 || data.task_codes !== void 0,
6928
6928
  {
6929
- message: "Either 'id' (UUID), 'ids' (array of UUIDs), 'task_code' (string code like PERF-1), or 'task_codes' (array of string codes) must be provided. Note: 'ids' expects UUID format, not task codes \u2014 use 'task_code'/'task_codes' for string identifiers."
6929
+ message: "Either 'id' (UUID), 'ids' (array of UUIDs or codes), 'task_code' (string code like PERF-1), or 'task_codes' (array of string codes) must be provided."
6930
6930
  }
6931
6931
  ).refine((data) => Object.keys(data).length > 2, {
6932
6932
  message: "At least one field besides repo and id/ids must be provided for update"
@@ -6955,21 +6955,21 @@ var TaskSearchSchema = z4.object({
6955
6955
  var TaskDeleteSchema = z4.object({
6956
6956
  owner: z4.string().min(1),
6957
6957
  repo: z4.string().min(1).transform(normalizeRepo),
6958
- id: z4.string().uuid().optional(),
6959
- ids: z4.array(z4.string().uuid()).min(1).optional(),
6958
+ id: z4.string().optional(),
6959
+ ids: z4.array(z4.string()).min(1).optional(),
6960
6960
  task_code: z4.string().optional(),
6961
6961
  task_codes: z4.array(z4.string().min(1)).min(1).optional(),
6962
6962
  structured: z4.boolean().default(false)
6963
6963
  }).refine(
6964
6964
  (data) => data.id !== void 0 || data.ids !== void 0 || data.task_code !== void 0 || data.task_codes !== void 0,
6965
6965
  {
6966
- message: "Either 'id' (UUID), 'ids' (array of UUIDs), 'task_code' (string code like PERF-1), or 'task_codes' (array of string codes) must be provided. Note: 'ids' expects UUID format, not task codes \u2014 use 'task_code'/'task_codes' for string identifiers."
6966
+ message: "Either 'id' (UUID), 'ids' (array of UUIDs or codes), 'task_code' (string code like PERF-1), or 'task_codes' (array of string codes) must be provided."
6967
6967
  }
6968
6968
  );
6969
6969
  var TaskGetSchema = z4.object({
6970
6970
  owner: z4.string().min(1),
6971
6971
  repo: z4.string().min(1).transform(normalizeRepo),
6972
- id: z4.string().uuid().optional(),
6972
+ id: z4.string().optional(),
6973
6973
  task_code: z4.string().optional(),
6974
6974
  task_codes: z4.array(z4.string().min(1)).min(1).optional(),
6975
6975
  structured: z4.boolean().default(false)
@@ -6984,7 +6984,7 @@ var HandoffCreateSchema = z5.object({
6984
6984
  repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
6985
6985
  from_agent: z5.string().min(1),
6986
6986
  to_agent: z5.string().min(1).optional(),
6987
- task_id: z5.string().uuid().optional(),
6987
+ task_id: z5.string().optional(),
6988
6988
  task_code: z5.string().optional(),
6989
6989
  summary: z5.string().min(1),
6990
6990
  context: z5.record(z5.string(), z5.unknown()).optional(),
@@ -7016,7 +7016,7 @@ var HandoffListSchema = z5.object({
7016
7016
  var TaskClaimSchema = z5.object({
7017
7017
  owner: z5.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
7018
7018
  repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
7019
- task_id: z5.string().uuid().optional(),
7019
+ task_id: z5.string().optional(),
7020
7020
  task_code: z5.string().optional(),
7021
7021
  agent: z5.string().min(1),
7022
7022
  role: z5.string().optional(),
@@ -7039,7 +7039,7 @@ var ClaimListSchema = z5.object({
7039
7039
  var ClaimReleaseSchema = z5.object({
7040
7040
  owner: z5.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
7041
7041
  repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
7042
- task_id: z5.string().uuid().optional(),
7042
+ task_id: z5.string().optional(),
7043
7043
  task_code: z5.string().optional(),
7044
7044
  agent: z5.string().min(1).optional(),
7045
7045
  structured: z5.boolean().default(false)
@@ -7078,7 +7078,7 @@ var StandardStoreSchema = z6.object({
7078
7078
  message: "repo is required for repo-specific standards"
7079
7079
  });
7080
7080
  var StandardUpdateSchema = z6.object({
7081
- id: z6.string().uuid().optional(),
7081
+ id: z6.string().optional(),
7082
7082
  code: z6.string().max(20).optional(),
7083
7083
  name: z6.string().min(3).max(255).optional(),
7084
7084
  content: z6.string().min(10).optional(),
@@ -7120,8 +7120,8 @@ var StandardSearchSchema = z6.object({
7120
7120
  var StandardDeleteSchema = z6.object({
7121
7121
  owner: z6.string().min(1),
7122
7122
  repo: z6.string().min(1).transform(normalizeRepo),
7123
- id: z6.string().uuid().optional(),
7124
- ids: z6.array(z6.string().uuid()).min(1).optional(),
7123
+ id: z6.string().optional(),
7124
+ ids: z6.array(z6.string()).min(1).optional(),
7125
7125
  code: z6.string().max(20).optional(),
7126
7126
  codes: z6.array(z6.string().max(20)).min(1).optional(),
7127
7127
  structured: z6.boolean().default(false)
@@ -7132,7 +7132,7 @@ var StandardDeleteSchema = z6.object({
7132
7132
  }
7133
7133
  );
7134
7134
  var StandardDetailSchema = z6.object({
7135
- id: z6.string().uuid().optional(),
7135
+ id: z6.string().optional(),
7136
7136
  code: z6.string().max(20).optional(),
7137
7137
  owner: z6.string().min(1),
7138
7138
  repo: z6.string().min(1).transform(normalizeRepo),
@@ -7215,6 +7215,9 @@ var KGBackfillSchema = z8.object({
7215
7215
  source: z8.enum(["memories", "standards", "both"]).optional().default("both")
7216
7216
  });
7217
7217
 
7218
+ // src/mcp/utils/uuid.ts
7219
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
7220
+
7218
7221
  // src/mcp/tools/handoff.manage.ts
7219
7222
  function buildHandoffListSummary(repo, count, status, fromAgent, toAgent) {
7220
7223
  const parts = [`Found ${count} handoff${count === 1 ? "" : "s"} in repo "${repo}".`];
@@ -7243,6 +7246,13 @@ async function handleHandoffCreate(args, storage) {
7243
7246
  const validated = HandoffCreateSchema.parse(args);
7244
7247
  const { owner, repo, from_agent, to_agent, task_id, task_code, summary, context, expires_at, structured } = validated;
7245
7248
  let resolvedTaskId = task_id ?? null;
7249
+ if (resolvedTaskId && !UUID_REGEX.test(resolvedTaskId)) {
7250
+ const task = storage.tasks.getTaskByCode(owner, repo, resolvedTaskId);
7251
+ if (!task) {
7252
+ throw new Error(`Task not found: ${resolvedTaskId} in repo ${repo}`);
7253
+ }
7254
+ resolvedTaskId = task.id;
7255
+ }
7246
7256
  if (!resolvedTaskId && task_code) {
7247
7257
  const task = storage.tasks.getTaskByCode(owner, repo, task_code);
7248
7258
  if (!task) {
@@ -7361,6 +7371,13 @@ async function handleTaskClaim(args, storage) {
7361
7371
  const validated = TaskClaimSchema.parse(args);
7362
7372
  const { owner, repo, task_id, task_code, agent, role, metadata, structured } = validated;
7363
7373
  let taskId = task_id;
7374
+ if (taskId && !UUID_REGEX.test(taskId)) {
7375
+ const task2 = storage.tasks.getTaskByCode(owner, repo, taskId);
7376
+ if (!task2) {
7377
+ throw new Error(`Task not found: ${taskId} in repo ${repo}`);
7378
+ }
7379
+ taskId = task2.id;
7380
+ }
7364
7381
  let resolvedTaskCode;
7365
7382
  let task;
7366
7383
  if (taskId) {
@@ -7466,6 +7483,13 @@ async function handleClaimRelease(args, storage) {
7466
7483
  const validated = ClaimReleaseSchema.parse(args);
7467
7484
  const { owner, repo, task_id, task_code, agent, structured } = validated;
7468
7485
  let resolvedTaskId = task_id;
7486
+ if (resolvedTaskId && !UUID_REGEX.test(resolvedTaskId)) {
7487
+ const task = storage.tasks.getTaskByCode(owner, repo, resolvedTaskId);
7488
+ if (!task) {
7489
+ throw new Error(`Task not found: ${resolvedTaskId} in repo ${repo}`);
7490
+ }
7491
+ resolvedTaskId = task.id;
7492
+ }
7469
7493
  let resolvedTaskCode = task_code ?? null;
7470
7494
  if (resolvedTaskId) {
7471
7495
  const task = storage.tasks.getTaskById(resolvedTaskId);
@@ -7576,6 +7600,7 @@ export {
7576
7600
  DeleteRelationSchema,
7577
7601
  DeleteObservationSchema,
7578
7602
  KGBackfillSchema,
7603
+ UUID_REGEX,
7579
7604
  handleHandoffCreate,
7580
7605
  handleHandoffList,
7581
7606
  handleHandoffUpdate,
@@ -15,7 +15,7 @@ import {
15
15
  handleTaskClaim,
16
16
  listResources,
17
17
  logger
18
- } from "../chunk-H7BLOZB6.js";
18
+ } from "../chunk-3ZCTWRSA.js";
19
19
 
20
20
  // src/dashboard/server.ts
21
21
  import express from "express";
@@ -34,6 +34,7 @@ import {
34
34
  TaskSearchSchema,
35
35
  TaskStatusSchema,
36
36
  TaskUpdateSchema,
37
+ UUID_REGEX,
37
38
  addLogSink,
38
39
  buildStandardVectorText,
39
40
  completePromptArgument,
@@ -61,7 +62,7 @@ import {
61
62
  parseRepoInput,
62
63
  rankCompletionValues,
63
64
  toContextSlug
64
- } from "../chunk-H7BLOZB6.js";
65
+ } from "../chunk-3ZCTWRSA.js";
65
66
 
66
67
  // src/mcp/server.ts
67
68
  import { serveStdio } from "@modelcontextprotocol/server/stdio";
@@ -74,8 +75,8 @@ import path from "path";
74
75
  import { fileURLToPath } from "url";
75
76
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
76
77
  var pkgVersion = "0.1.0";
77
- if ("0.19.13") {
78
- pkgVersion = "0.19.13";
78
+ if ("0.19.14") {
79
+ pkgVersion = "0.19.14";
79
80
  } else {
80
81
  let searchDir = __dirname;
81
82
  for (let i = 0; i < 5; i++) {
@@ -422,7 +423,6 @@ async function saveExtractions(content, title, owner, repo, db2) {
422
423
  }
423
424
 
424
425
  // src/mcp/tools/memory.store.ts
425
- var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
426
426
  function hasMetadataLikeTitle(title) {
427
427
  const normalized = title.trim();
428
428
  return /^\[[^\]]{0,200}(agent:|role:|model:|\d{4}-\d{2}-\d{2}|source_)[^\]]*\]/i.test(normalized);
@@ -657,14 +657,13 @@ async function handleMemoryStore(params, db2, vectors2) {
657
657
  }
658
658
 
659
659
  // src/mcp/tools/memory.update.ts
660
- var UUID_REGEX2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
661
660
  function hasMetadataLikeTitle2(title) {
662
661
  const normalized = title.trim();
663
662
  return /^\[[^\]]{0,200}(agent:|role:|model:|\d{4}-\d{2}-\d{2}|source_)[^\]]*\]/i.test(normalized);
664
663
  }
665
664
  function resolveMemorySupersedes2(value, db2, owner, repo) {
666
665
  if (!value) return null;
667
- if (UUID_REGEX2.test(value)) return value;
666
+ if (UUID_REGEX.test(value)) return value;
668
667
  const memory = db2.memories.getByCode(value, owner, repo);
669
668
  if (!memory) throw new Error(`supersedes: memory with code '${value}' not found`);
670
669
  return memory.id;
@@ -672,6 +671,11 @@ function resolveMemorySupersedes2(value, db2, owner, repo) {
672
671
  async function handleMemoryUpdate(params, db2, vectors2) {
673
672
  const validated = MemoryUpdateSchema.parse(params);
674
673
  let resolvedId = validated.id;
674
+ if (resolvedId && !UUID_REGEX.test(resolvedId)) {
675
+ const byCode = db2.memories.getByCode(resolvedId, validated.owner, validated.repo);
676
+ if (!byCode) throw new Error(`Memory not found: ${resolvedId}`);
677
+ resolvedId = byCode.id;
678
+ }
675
679
  if (!resolvedId && validated.code) {
676
680
  const byCode = db2.memories.getByCode(validated.code, validated.owner, validated.repo);
677
681
  if (!byCode) throw new Error(`Memory not found: ${validated.code}`);
@@ -1037,6 +1041,11 @@ function applyTimeFilter(memories, tunnel) {
1037
1041
  async function handleMemoryAcknowledge(params, db2) {
1038
1042
  const validated = MemoryAcknowledgeSchema.parse(params);
1039
1043
  let memoryId = validated.memory_id;
1044
+ if (memoryId && !UUID_REGEX.test(memoryId)) {
1045
+ const byCode = db2.memories.getByCode(memoryId, validated.owner, validated.repo);
1046
+ if (!byCode) throw new Error(`Memory not found: ${memoryId}`);
1047
+ memoryId = byCode.id;
1048
+ }
1040
1049
  if (!memoryId && validated.code) {
1041
1050
  const byCode = db2.memories.getByCode(validated.code, validated.owner, validated.repo);
1042
1051
  if (!byCode) throw new Error(`Memory not found: ${validated.code}`);
@@ -1541,8 +1550,26 @@ async function handleMemoryDelete(params, db2, vectors2, onProgress) {
1541
1550
  const validated = MemoryDeleteSchema.parse(params);
1542
1551
  const { id, ids, code, codes, owner, repo, structured } = validated;
1543
1552
  const resolvedIds = [];
1544
- if (ids) resolvedIds.push(...ids);
1545
- if (id) resolvedIds.push(id);
1553
+ if (ids) {
1554
+ for (const item of ids) {
1555
+ if (UUID_REGEX.test(item)) {
1556
+ resolvedIds.push(item);
1557
+ } else {
1558
+ const entry = db2.memories.getByCode(item, owner, repo);
1559
+ if (!entry) throw new Error(`Memory not found: ${item}`);
1560
+ resolvedIds.push(entry.id);
1561
+ }
1562
+ }
1563
+ }
1564
+ if (id) {
1565
+ if (!UUID_REGEX.test(id)) {
1566
+ const entry = db2.memories.getByCode(id, owner, repo);
1567
+ if (!entry) throw new Error(`Memory not found: ${id}`);
1568
+ resolvedIds.push(entry.id);
1569
+ } else {
1570
+ resolvedIds.push(id);
1571
+ }
1572
+ }
1546
1573
  if (code) {
1547
1574
  const entry = db2.memories.getByCode(code, owner, repo);
1548
1575
  if (!entry) throw new Error(`Memory not found: ${code}`);
@@ -1573,7 +1600,7 @@ async function handleMemoryDelete(params, db2, vectors2, onProgress) {
1573
1600
  lastRepo = existing.scope.repo;
1574
1601
  deletedCodes.push(existing.code || existing.id);
1575
1602
  validIdsToDelete.push(targetId);
1576
- } else if (id) {
1603
+ } else {
1577
1604
  throw new Error(`Memory not found: ${targetId}`);
1578
1605
  }
1579
1606
  }
@@ -1615,7 +1642,7 @@ async function handleMemoryDetail(args, storage) {
1615
1642
  const { id, code, owner, repo } = validated;
1616
1643
  let memory;
1617
1644
  if (id) {
1618
- memory = storage.memories.getById(id);
1645
+ memory = UUID_REGEX.test(id) ? storage.memories.getById(id) : storage.memories.getByCode(id, owner, repo);
1619
1646
  } else if (code) {
1620
1647
  memory = storage.memories.getByCode(code, owner, repo);
1621
1648
  }
@@ -1645,10 +1672,9 @@ async function handleMemoryDetail(args, storage) {
1645
1672
 
1646
1673
  // src/mcp/tools/standard.store.ts
1647
1674
  import { randomUUID as randomUUID3 } from "crypto";
1648
- var UUID_REGEX3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1649
1675
  function resolveStandardParentId(value, db2, owner, repo) {
1650
1676
  if (!value) return null;
1651
- if (UUID_REGEX3.test(value)) return value;
1677
+ if (UUID_REGEX.test(value)) return value;
1652
1678
  const standard = db2.standards.getByCode(value, owner, repo);
1653
1679
  if (!standard) throw new Error(`parent_id: standard with code '${value}' not found`);
1654
1680
  return standard.id;
@@ -2055,10 +2081,9 @@ async function handleStandardSearch(params, db2, vectors2) {
2055
2081
  }
2056
2082
 
2057
2083
  // src/mcp/tools/standard.update.ts
2058
- var UUID_REGEX4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2059
2084
  function resolveStandardParentId2(value, db2, owner, repo) {
2060
2085
  if (!value) return null;
2061
- if (UUID_REGEX4.test(value)) return value;
2086
+ if (UUID_REGEX.test(value)) return value;
2062
2087
  const standard = db2.standards.getByCode(value, owner, repo);
2063
2088
  if (!standard) throw new Error(`parent_id: standard with code '${value}' not found`);
2064
2089
  return standard.id;
@@ -2066,6 +2091,11 @@ function resolveStandardParentId2(value, db2, owner, repo) {
2066
2091
  async function handleStandardUpdate(params, db2, vectors2) {
2067
2092
  const validated = StandardUpdateSchema.parse(params);
2068
2093
  let resolvedId = validated.id;
2094
+ if (resolvedId && !UUID_REGEX.test(resolvedId)) {
2095
+ const byCode = db2.standards.getByCode(resolvedId, validated.owner, validated.repo);
2096
+ if (!byCode) throw new Error(`Coding standard not found: ${resolvedId}`);
2097
+ resolvedId = byCode.id;
2098
+ }
2069
2099
  if (!resolvedId && validated.code) {
2070
2100
  const byCode = db2.standards.getByCode(validated.code, validated.owner, validated.repo);
2071
2101
  if (!byCode) throw new Error(`Coding standard not found: ${validated.code}`);
@@ -2123,9 +2153,15 @@ async function handleStandardUpdate(params, db2, vectors2) {
2123
2153
  // src/mcp/tools/standard.detail.ts
2124
2154
  async function handleStandardDetail(args, storage) {
2125
2155
  const validated = StandardDetailSchema.parse(args);
2126
- const standard = validated.id ? storage.standards.getById(validated.id) : storage.standards.getByCode(validated.code, validated.owner, validated.repo);
2156
+ const { id, code, owner, repo } = validated;
2157
+ let standard;
2158
+ if (id) {
2159
+ standard = UUID_REGEX.test(id) ? storage.standards.getById(id) : storage.standards.getByCode(id, owner, repo);
2160
+ } else if (code) {
2161
+ standard = storage.standards.getByCode(code, owner, repo);
2162
+ }
2127
2163
  if (!standard) {
2128
- const identifier = validated.id ?? validated.code;
2164
+ const identifier = id ?? code;
2129
2165
  throw new Error(`Coding standard not found: ${identifier}`);
2130
2166
  }
2131
2167
  storage.standards.incrementHitCounts([standard.id]);
@@ -2159,8 +2195,26 @@ async function handleStandardDelete(params, db2, vectors2) {
2159
2195
  const validated = StandardDeleteSchema.parse(params);
2160
2196
  const { id, ids, code, codes, owner, repo, structured } = validated;
2161
2197
  const resolvedIds = [];
2162
- if (ids) resolvedIds.push(...ids);
2163
- if (id) resolvedIds.push(id);
2198
+ if (ids) {
2199
+ for (const item of ids) {
2200
+ if (UUID_REGEX.test(item)) {
2201
+ resolvedIds.push(item);
2202
+ } else {
2203
+ const entry = db2.standards.getByCode(item, owner, repo);
2204
+ if (!entry) throw new Error(`Coding standard not found: ${item}`);
2205
+ resolvedIds.push(entry.id);
2206
+ }
2207
+ }
2208
+ }
2209
+ if (id) {
2210
+ if (!UUID_REGEX.test(id)) {
2211
+ const entry = db2.standards.getByCode(id, owner, repo);
2212
+ if (!entry) throw new Error(`Coding standard not found: ${id}`);
2213
+ resolvedIds.push(entry.id);
2214
+ } else {
2215
+ resolvedIds.push(id);
2216
+ }
2217
+ }
2164
2218
  if (code) {
2165
2219
  const entry = db2.standards.getByCode(code, owner, repo);
2166
2220
  if (!entry) throw new Error(`Coding standard not found: ${code}`);
@@ -2188,7 +2242,7 @@ async function handleStandardDelete(params, db2, vectors2) {
2188
2242
  db2.standards.delete(targetId);
2189
2243
  await vectors2.remove(targetId, "standard");
2190
2244
  deletedCount++;
2191
- } else if (id) {
2245
+ } else {
2192
2246
  throw new Error(`Coding standard not found: ${targetId}`);
2193
2247
  }
2194
2248
  }
@@ -2214,10 +2268,9 @@ async function handleStandardDelete(params, db2, vectors2) {
2214
2268
  import { randomUUID as randomUUID4 } from "crypto";
2215
2269
 
2216
2270
  // src/mcp/tools/task.helpers.ts
2217
- var UUID_REGEX5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2218
2271
  function resolveParentId(value, owner, repo, storage, localCodeMap) {
2219
2272
  if (!value) return null;
2220
- if (UUID_REGEX5.test(value)) return value;
2273
+ if (UUID_REGEX.test(value)) return value;
2221
2274
  if (localCodeMap?.has(value)) return localCodeMap.get(value);
2222
2275
  const parent = storage.tasks.getTaskByCode(owner, repo, value);
2223
2276
  if (!parent) throw new Error(`parent_id: task with code '${value}' not found in repo '${repo}'`);
@@ -2225,7 +2278,7 @@ function resolveParentId(value, owner, repo, storage, localCodeMap) {
2225
2278
  }
2226
2279
  function resolveDependsOn(value, owner, repo, storage, localCodeMap) {
2227
2280
  if (!value) return null;
2228
- if (UUID_REGEX5.test(value)) return value;
2281
+ if (UUID_REGEX.test(value)) return value;
2229
2282
  if (localCodeMap?.has(value)) return localCodeMap.get(value);
2230
2283
  const task = storage.tasks.getTaskByCode(owner, repo, value);
2231
2284
  if (!task) throw new Error(`depends_on: task with code '${value}' not found in repo '${repo}'`);
@@ -2583,12 +2636,29 @@ async function handleTaskUpdate(args, storage, vectors2) {
2583
2636
  const updateData = TaskUpdateSchema.parse(args);
2584
2637
  const { owner, repo, id, ids, comment, force, ...updates } = updateData;
2585
2638
  let resolvedId = id;
2639
+ if (resolvedId && !UUID_REGEX.test(resolvedId)) {
2640
+ const found = storage.tasks.getTaskByCode(owner, repo, resolvedId);
2641
+ if (!found) throw new Error(`Task not found: ${resolvedId}`);
2642
+ resolvedId = found.id;
2643
+ }
2586
2644
  if (!resolvedId && !ids && updates.task_code) {
2587
2645
  const found = storage.tasks.getTaskByCode(owner, repo, updates.task_code);
2588
2646
  if (!found) throw new Error(`Task not found: ${updates.task_code}`);
2589
2647
  resolvedId = found.id;
2590
2648
  }
2591
- const targetIds = ids || (resolvedId ? [resolvedId] : []);
2649
+ const resolvedIdsArray = [];
2650
+ if (ids) {
2651
+ for (const item of ids) {
2652
+ if (UUID_REGEX.test(item)) {
2653
+ resolvedIdsArray.push(item);
2654
+ } else {
2655
+ const task = storage.tasks.getTaskByCode(owner, repo, item);
2656
+ if (!task) throw new Error(`Task not found: ${item}`);
2657
+ resolvedIdsArray.push(task.id);
2658
+ }
2659
+ }
2660
+ }
2661
+ const targetIds = resolvedIdsArray.length > 0 ? resolvedIdsArray : resolvedId ? [resolvedId] : [];
2592
2662
  if (targetIds.length === 0) {
2593
2663
  throw new Error("Either 'id' or 'ids' must be provided for update");
2594
2664
  }
@@ -2731,8 +2801,26 @@ async function handleTaskDelete(args, storage) {
2731
2801
  const validated = TaskDeleteSchema.parse(args);
2732
2802
  const { owner, repo, id, ids, task_code } = validated;
2733
2803
  const resolvedIds = [];
2734
- if (ids) resolvedIds.push(...ids);
2735
- if (id) resolvedIds.push(id);
2804
+ if (ids) {
2805
+ for (const item of ids) {
2806
+ if (UUID_REGEX.test(item)) {
2807
+ resolvedIds.push(item);
2808
+ } else {
2809
+ const task = storage.tasks.getTaskByCode(owner, repo, item);
2810
+ if (!task) throw new Error(`Task not found: ${item}`);
2811
+ resolvedIds.push(task.id);
2812
+ }
2813
+ }
2814
+ }
2815
+ if (id) {
2816
+ if (!UUID_REGEX.test(id)) {
2817
+ const task = storage.tasks.getTaskByCode(owner, repo, id);
2818
+ if (!task) throw new Error(`Task not found: ${id}`);
2819
+ resolvedIds.push(task.id);
2820
+ } else {
2821
+ resolvedIds.push(id);
2822
+ }
2823
+ }
2736
2824
  if (task_code) {
2737
2825
  const task = storage.tasks.getTaskByCode(owner, repo, task_code);
2738
2826
  if (!task) throw new Error(`Task not found: ${task_code}`);
@@ -2768,7 +2856,7 @@ async function handleTaskGet(args, storage) {
2768
2856
  const { owner, repo, id, task_code, structured: isStructuredRequest } = validated;
2769
2857
  let task;
2770
2858
  if (id) {
2771
- task = storage.tasks.getTaskById(id);
2859
+ task = UUID_REGEX.test(id) ? storage.tasks.getTaskById(id) : storage.tasks.getTaskByCode(owner, repo, id);
2772
2860
  } else if (task_code) {
2773
2861
  task = storage.tasks.getTaskByCode(owner, repo, task_code);
2774
2862
  } else {
@@ -3063,6 +3151,10 @@ async function handleDecisionLog(args, db2, vectors2) {
3063
3151
  tags,
3064
3152
  structured: validated.structured
3065
3153
  };
3154
+ const conflict = await db2.memoryVectors.checkConflicts(formattedContent, owner, repo, "decision", vectors2, 0.55);
3155
+ if (conflict) {
3156
+ memoryStoreParams.supersedes = conflict.id;
3157
+ }
3066
3158
  return handleMemoryStore(memoryStoreParams, db2, vectors2);
3067
3159
  }
3068
3160
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vheins/local-memory-mcp",
3
- "version": "0.19.13",
3
+ "version": "0.19.14",
4
4
  "description": "MCP Local Memory Service for coding copilot agents",
5
5
  "mcpName": "io.github.vheins/local-memory-mcp",
6
6
  "type": "module",