mindpm 1.2.40 → 1.2.41

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.
Files changed (2) hide show
  1. package/dist/index.js +58 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -412,6 +412,20 @@ function resolveProjectOrDefault(projectRef) {
412
412
  if (sessionProjects.length > 1) return null;
413
413
  return getMostRecentProject();
414
414
  }
415
+ function resolveTaskId(taskRef) {
416
+ const db2 = getDb();
417
+ const byId = db2.prepare("SELECT id FROM tasks WHERE id = ?").get(taskRef);
418
+ if (byId) return byId.id;
419
+ const match = taskRef.match(/^(.+)-(\d+)$/);
420
+ if (match) {
421
+ const [, slug, seqStr] = match;
422
+ const row = db2.prepare(
423
+ "SELECT t.id FROM tasks t JOIN projects p ON t.project_id = p.id WHERE LOWER(p.slug) = LOWER(?) AND t.seq = ?"
424
+ ).get(slug, parseInt(seqStr, 10));
425
+ if (row) return row.id;
426
+ }
427
+ return null;
428
+ }
415
429
  function recordTaskHistory(taskId, event, oldValue, newValue) {
416
430
  const db2 = getDb();
417
431
  db2.prepare(
@@ -639,7 +653,12 @@ var createTask = async (req, res, params) => {
639
653
  var updateTask = async (req, res, params) => {
640
654
  const db2 = getDb();
641
655
  const body = await parseBody(req);
642
- const existing = db2.prepare("SELECT * FROM tasks WHERE id = ?").get(params.id);
656
+ const resolvedId = resolveTaskId(params.id);
657
+ if (!resolvedId) {
658
+ sendJson(res, 404, { error: "Task not found" });
659
+ return;
660
+ }
661
+ const existing = db2.prepare("SELECT * FROM tasks WHERE id = ?").get(resolvedId);
643
662
  if (!existing) {
644
663
  sendJson(res, 404, { error: "Task not found" });
645
664
  return;
@@ -682,23 +701,28 @@ var updateTask = async (req, res, params) => {
682
701
  sendJson(res, 400, { error: "No updates provided" });
683
702
  return;
684
703
  }
685
- sqlParams.push(params.id);
704
+ sqlParams.push(resolvedId);
686
705
  db2.prepare(`UPDATE tasks SET ${updates.join(", ")} WHERE id = ?`).run(...sqlParams);
687
706
  if (body.status !== void 0 && body.status !== existing.status) {
688
- recordTaskHistory(params.id, "status_changed", existing.status, body.status);
707
+ recordTaskHistory(resolvedId, "status_changed", existing.status, body.status);
689
708
  }
690
709
  if (body.priority !== void 0 && body.priority !== existing.priority) {
691
- recordTaskHistory(params.id, "priority_changed", existing.priority, body.priority);
710
+ recordTaskHistory(resolvedId, "priority_changed", existing.priority, body.priority);
692
711
  }
693
712
  if (body.title !== void 0 && body.title !== existing.title) {
694
- recordTaskHistory(params.id, "title_changed", existing.title, body.title);
713
+ recordTaskHistory(resolvedId, "title_changed", existing.title, body.title);
695
714
  }
696
- const updated = db2.prepare("SELECT t.*, p.slug || '-' || t.seq AS short_id FROM tasks t JOIN projects p ON t.project_id = p.id WHERE t.id = ?").get(params.id);
715
+ const updated = db2.prepare("SELECT t.*, p.slug || '-' || t.seq AS short_id FROM tasks t JOIN projects p ON t.project_id = p.id WHERE t.id = ?").get(resolvedId);
697
716
  sendJson(res, 200, updated);
698
717
  };
699
718
  var deleteTask = async (_req, res, params) => {
700
719
  const db2 = getDb();
701
- const existing = db2.prepare("SELECT * FROM tasks WHERE id = ?").get(params.id);
720
+ const resolvedId = resolveTaskId(params.id);
721
+ if (!resolvedId) {
722
+ sendJson(res, 404, { error: "Task not found" });
723
+ return;
724
+ }
725
+ const existing = db2.prepare("SELECT * FROM tasks WHERE id = ?").get(resolvedId);
702
726
  if (!existing) {
703
727
  sendJson(res, 404, { error: "Task not found" });
704
728
  return;
@@ -714,14 +738,19 @@ var deleteTask = async (_req, res, params) => {
714
738
  db2.prepare("DELETE FROM notes WHERE task_id = ?").run(taskId);
715
739
  db2.prepare("DELETE FROM tasks WHERE id = ?").run(taskId);
716
740
  });
717
- deleteTransaction(params.id);
741
+ deleteTransaction(resolvedId);
718
742
  sendJson(res, 200, { message: "Task deleted" });
719
743
  };
720
744
  var getTaskHistory = async (_req, res, params) => {
721
745
  const db2 = getDb();
746
+ const resolvedId = resolveTaskId(params.id);
747
+ if (!resolvedId) {
748
+ sendJson(res, 200, []);
749
+ return;
750
+ }
722
751
  const rows = db2.prepare(
723
752
  "SELECT * FROM task_history WHERE task_id = ? ORDER BY created_at ASC"
724
- ).all(params.id);
753
+ ).all(resolvedId);
725
754
  sendJson(res, 200, rows);
726
755
  };
727
756
  var getMetrics = async (req, res, params) => {
@@ -1174,7 +1203,7 @@ function registerTaskTools(server2) {
1174
1203
  title: "Update Task",
1175
1204
  description: "Update any field of a task. Proactively use this when a task status changes, priorities shift, or new information comes in.",
1176
1205
  inputSchema: {
1177
- task_id: z2.string().describe("Task ID to update"),
1206
+ task_id: z2.string().describe('Task ID to update (hex ID or short ID like "zrdt-180")'),
1178
1207
  title: z2.string().optional().describe("New title"),
1179
1208
  description: z2.string().optional().describe("New description"),
1180
1209
  status: z2.enum(["todo", "in_progress", "blocked", "in_review", "done", "cancelled"]).optional().describe("New status"),
@@ -1186,7 +1215,11 @@ function registerTaskTools(server2) {
1186
1215
  },
1187
1216
  async ({ task_id, title, description, status, priority, tags, blocked_by, addBlockedBy }) => {
1188
1217
  const db2 = getDb();
1189
- const existing = db2.prepare("SELECT * FROM tasks WHERE id = ?").get(task_id);
1218
+ const resolvedId = resolveTaskId(task_id);
1219
+ if (!resolvedId) {
1220
+ return { content: [{ type: "text", text: `Task "${task_id}" not found.` }], isError: true };
1221
+ }
1222
+ const existing = db2.prepare("SELECT * FROM tasks WHERE id = ?").get(resolvedId);
1190
1223
  if (!existing) {
1191
1224
  return { content: [{ type: "text", text: `Task "${task_id}" not found.` }], isError: true };
1192
1225
  }
@@ -1234,13 +1267,13 @@ function registerTaskTools(server2) {
1234
1267
  if (updates.length === 0) {
1235
1268
  return { content: [{ type: "text", text: "No updates provided." }], isError: true };
1236
1269
  }
1237
- params.push(task_id);
1270
+ params.push(resolvedId);
1238
1271
  db2.prepare(`UPDATE tasks SET ${updates.join(", ")} WHERE id = ?`).run(...params);
1239
1272
  if (status !== void 0 && status !== existing.status) {
1240
- recordTaskHistory(task_id, "status_changed", existing.status, status);
1273
+ recordTaskHistory(resolvedId, "status_changed", existing.status, status);
1241
1274
  }
1242
1275
  return {
1243
- content: [{ type: "text", text: JSON.stringify({ task_id, message: `Task "${existing.title}" updated.` }) }]
1276
+ content: [{ type: "text", text: JSON.stringify({ task_id: resolvedId, message: `Task "${existing.title}" updated.` }) }]
1244
1277
  };
1245
1278
  }
1246
1279
  );
@@ -1302,18 +1335,22 @@ function registerTaskTools(server2) {
1302
1335
  title: "Get Task",
1303
1336
  description: "Get full detail for a specific task including sub-tasks and related notes.",
1304
1337
  inputSchema: {
1305
- task_id: z2.string().describe("Task ID")
1338
+ task_id: z2.string().describe('Task ID (hex ID or short ID like "zrdt-180")')
1306
1339
  }
1307
1340
  },
1308
1341
  async ({ task_id }) => {
1309
1342
  const db2 = getDb();
1310
- const task = db2.prepare("SELECT t.*, p.slug || '-' || t.seq AS short_id FROM tasks t JOIN projects p ON t.project_id = p.id WHERE t.id = ?").get(task_id);
1343
+ const resolvedId = resolveTaskId(task_id);
1344
+ if (!resolvedId) {
1345
+ return { content: [{ type: "text", text: `Task "${task_id}" not found.` }], isError: true };
1346
+ }
1347
+ const task = db2.prepare("SELECT t.*, p.slug || '-' || t.seq AS short_id FROM tasks t JOIN projects p ON t.project_id = p.id WHERE t.id = ?").get(resolvedId);
1311
1348
  if (!task) {
1312
1349
  return { content: [{ type: "text", text: `Task "${task_id}" not found.` }], isError: true };
1313
1350
  }
1314
1351
  const sessionPreamble = maybeAutoSession(task.project_id);
1315
- const subtasks = db2.prepare("SELECT t.*, p.slug || '-' || t.seq AS short_id FROM tasks t JOIN projects p ON t.project_id = p.id WHERE t.parent_task_id = ?").all(task_id);
1316
- const notes = db2.prepare("SELECT * FROM notes WHERE task_id = ? ORDER BY created_at DESC").all(task_id);
1352
+ const subtasks = db2.prepare("SELECT t.*, p.slug || '-' || t.seq AS short_id FROM tasks t JOIN projects p ON t.project_id = p.id WHERE t.parent_task_id = ?").all(resolvedId);
1353
+ const notes = db2.prepare("SELECT * FROM notes WHERE task_id = ? ORDER BY created_at DESC").all(resolvedId);
1317
1354
  const resultText = JSON.stringify({ task, subtasks, notes }, null, 2);
1318
1355
  return {
1319
1356
  content: [{ type: "text", text: sessionPreamble ? `${sessionPreamble}
@@ -1461,7 +1498,7 @@ function registerNoteTools(server2) {
1461
1498
  project: z4.string().optional().describe("Project name or ID (always pass this when known \u2014 omitting may target the wrong project)"),
1462
1499
  content: z4.string().describe("The note content"),
1463
1500
  category: z4.enum(["general", "architecture", "bug", "idea", "research", "meeting", "review"]).optional().describe("Note category (default: general)"),
1464
- task_id: z4.string().optional().describe("Link this note to a specific task"),
1501
+ task_id: z4.string().optional().describe('Link this note to a specific task (hex ID or short ID like "zrdt-180")'),
1465
1502
  tags: z4.array(z4.string()).optional().describe("Tags for categorization")
1466
1503
  }
1467
1504
  },
@@ -1472,12 +1509,13 @@ function registerNoteTools(server2) {
1472
1509
  }
1473
1510
  const db2 = getDb();
1474
1511
  const id = generateId();
1512
+ const resolvedTaskId = task_id ? resolveTaskId(task_id) : null;
1475
1513
  db2.prepare(
1476
1514
  `INSERT INTO notes (id, project_id, task_id, content, category, tags) VALUES (?, ?, ?, ?, ?, ?)`
1477
1515
  ).run(
1478
1516
  id,
1479
1517
  resolved.id,
1480
- task_id ?? null,
1518
+ resolvedTaskId,
1481
1519
  content,
1482
1520
  category ?? "general",
1483
1521
  tags ? JSON.stringify(tags) : null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindpm",
3
- "version": "1.2.40",
3
+ "version": "1.2.41",
4
4
  "description": "Persistent project memory for LLMs via MCP. Never re-explain your project again.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",