@vheins/local-memory-mcp 0.12.1 → 0.13.1

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.
@@ -81,8 +81,8 @@ function loadServerInstructions() {
81
81
  // src/mcp/capabilities.ts
82
82
  var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
83
83
  var pkgVersion = "0.1.0";
84
- if ("0.12.1") {
85
- pkgVersion = "0.12.1";
84
+ if ("0.13.1") {
85
+ pkgVersion = "0.13.1";
86
86
  } else {
87
87
  let searchDir = __dirname2;
88
88
  for (let i = 0; i < 5; i++) {
@@ -356,6 +356,8 @@ var MigrationManager = class {
356
356
  depends_on TEXT,
357
357
  est_tokens INTEGER NOT NULL DEFAULT 0,
358
358
  in_progress_at TEXT,
359
+ commit_id TEXT,
360
+ changed_files TEXT,
359
361
  FOREIGN KEY (parent_id) REFERENCES tasks(id) ON DELETE SET NULL,
360
362
  FOREIGN KEY (depends_on) REFERENCES tasks(id) ON DELETE SET NULL
361
363
  );
@@ -573,7 +575,17 @@ var MigrationManager = class {
573
575
  },
574
576
  { name: "role", table: "tasks", definition: "ALTER TABLE tasks ADD COLUMN role TEXT NOT NULL DEFAULT 'unknown'" },
575
577
  { name: "doc_path", table: "tasks", definition: "ALTER TABLE tasks ADD COLUMN doc_path TEXT" },
576
- { name: "response", table: "action_log", definition: "ALTER TABLE action_log ADD COLUMN response TEXT" }
578
+ { name: "response", table: "action_log", definition: "ALTER TABLE action_log ADD COLUMN response TEXT" },
579
+ {
580
+ name: "commit_id",
581
+ table: "tasks",
582
+ definition: "ALTER TABLE tasks ADD COLUMN commit_id TEXT"
583
+ },
584
+ {
585
+ name: "changed_files",
586
+ table: "tasks",
587
+ definition: "ALTER TABLE tasks ADD COLUMN changed_files TEXT"
588
+ }
577
589
  ];
578
590
  for (const col of columnsToAdd) {
579
591
  try {
@@ -680,17 +692,21 @@ var MigrationManager = class {
680
692
  depends_on TEXT,
681
693
  est_tokens INTEGER NOT NULL DEFAULT 0,
682
694
  in_progress_at TEXT,
695
+ commit_id TEXT,
696
+ changed_files TEXT,
683
697
  FOREIGN KEY (parent_id) REFERENCES tasks(id) ON DELETE SET NULL,
684
698
  FOREIGN KEY (depends_on) REFERENCES tasks(id) ON DELETE SET NULL
685
699
  );
686
700
 
687
701
  INSERT INTO tasks__migrated (
688
702
  id, repo, task_code, phase, title, description, status, priority,
689
- agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at
703
+ agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at,
704
+ commit_id, changed_files
690
705
  )
691
706
  SELECT
692
707
  id, repo, task_code, phase, title, description, status, priority,
693
- agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at
708
+ agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at,
709
+ commit_id, changed_files
694
710
  FROM tasks;
695
711
 
696
712
  DROP TABLE tasks;
@@ -1055,6 +1071,8 @@ var BaseEntity = class {
1055
1071
  finished_at: r.finished_at || null,
1056
1072
  canceled_at: r.canceled_at || null,
1057
1073
  est_tokens: r.est_tokens || 0,
1074
+ commit_id: r.commit_id || null,
1075
+ changed_files: this.safeJSONParse(r.changed_files, []),
1058
1076
  tags: this.safeJSONParse(r.tags, []),
1059
1077
  metadata: this.safeJSONParse(r.metadata, {}),
1060
1078
  parent_id: r.parent_id || null,
@@ -1554,8 +1572,9 @@ var TaskEntity = class extends BaseEntity {
1554
1572
  this.run(
1555
1573
  `INSERT INTO tasks (
1556
1574
  id, repo, task_code, phase, title, description, status, priority,
1557
- agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at
1558
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1575
+ agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at,
1576
+ commit_id, changed_files
1577
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1559
1578
  [
1560
1579
  task.id,
1561
1580
  task.repo,
@@ -1577,7 +1596,9 @@ var TaskEntity = class extends BaseEntity {
1577
1596
  task.parent_id || null,
1578
1597
  task.depends_on || null,
1579
1598
  task.est_tokens || 0,
1580
- task.in_progress_at || null
1599
+ task.in_progress_at || null,
1600
+ task.commit_id || null,
1601
+ task.changed_files ? JSON.stringify(task.changed_files) : null
1581
1602
  ]
1582
1603
  );
1583
1604
  }
@@ -1603,11 +1624,13 @@ var TaskEntity = class extends BaseEntity {
1603
1624
  "parent_id",
1604
1625
  "depends_on",
1605
1626
  "est_tokens",
1606
- "in_progress_at"
1627
+ "in_progress_at",
1628
+ "commit_id",
1629
+ "changed_files"
1607
1630
  ]);
1608
1631
  Object.keys(updates).forEach((key) => {
1609
1632
  if (VALID_COLUMNS.has(key) && anyUpdates[key] !== void 0) {
1610
- if (key === "tags" || key === "metadata") {
1633
+ if (key === "tags" || key === "metadata" || key === "changed_files") {
1611
1634
  fields.push(`${key} = ?`);
1612
1635
  values.push(JSON.stringify(anyUpdates[key]));
1613
1636
  } else {
@@ -1829,8 +1852,9 @@ var TaskEntity = class extends BaseEntity {
1829
1852
  this.run(
1830
1853
  `INSERT INTO tasks (
1831
1854
  id, repo, task_code, phase, title, description, status, priority,
1832
- agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at
1833
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1855
+ agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, metadata, parent_id, depends_on, est_tokens, in_progress_at,
1856
+ commit_id, changed_files
1857
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1834
1858
  [
1835
1859
  task.id,
1836
1860
  task.repo,
@@ -1852,7 +1876,9 @@ var TaskEntity = class extends BaseEntity {
1852
1876
  task.parent_id || null,
1853
1877
  task.depends_on || null,
1854
1878
  task.est_tokens || 0,
1855
- task.in_progress_at || null
1879
+ task.in_progress_at || null,
1880
+ task.commit_id || null,
1881
+ task.changed_files ? JSON.stringify(task.changed_files) : null
1856
1882
  ]
1857
1883
  );
1858
1884
  count++;
@@ -3318,6 +3344,8 @@ var TaskUpdateSchema = z.object({
3318
3344
  parent_id: z.string().optional(),
3319
3345
  depends_on: z.string().uuid().optional(),
3320
3346
  est_tokens: z.number().int().min(0).optional(),
3347
+ commit_id: z.string().optional(),
3348
+ changed_files: z.array(z.string()).optional(),
3321
3349
  force: z.boolean().optional(),
3322
3350
  structured: z.boolean().default(false)
3323
3351
  }).refine((data) => data.id !== void 0 || data.ids !== void 0 || data.task_code !== void 0, {
@@ -4182,7 +4210,7 @@ var TOOL_DEFINITIONS = [
4182
4210
  {
4183
4211
  name: "task-update",
4184
4212
  title: "Task Update",
4185
- 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.",
4213
+ 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. You may also include 'commit_id' (git commit hash) and 'changed_files' (list of files changed) for traceability.",
4186
4214
  annotations: {
4187
4215
  readOnlyHint: false,
4188
4216
  idempotentHint: false,
@@ -4229,6 +4257,15 @@ var TOOL_DEFINITIONS = [
4229
4257
  minimum: 0,
4230
4258
  description: "Estimated total tokens actually used for this task. Required when status changes to 'completed'."
4231
4259
  },
4260
+ commit_id: {
4261
+ type: "string",
4262
+ description: "Git commit hash. Recommended when status changes to 'completed' for traceability."
4263
+ },
4264
+ changed_files: {
4265
+ type: "array",
4266
+ items: { type: "string" },
4267
+ description: "List of files changed. Recommended when status changes to 'completed' for traceability."
4268
+ },
4232
4269
  force: {
4233
4270
  type: "boolean",
4234
4271
  description: "If true, bypasses status transition validation (e.g. pending -> completed)."
@@ -10,7 +10,7 @@ import {
10
10
  createFileSink,
11
11
  listResources,
12
12
  logger
13
- } from "../chunk-I57EED66.js";
13
+ } from "../chunk-UZWV2DYU.js";
14
14
 
15
15
  // src/dashboard/server.ts
16
16
  import express from "express";
@@ -739,8 +739,16 @@ var TasksController = class {
739
739
  if (attributes.status && attributes.status !== existingTask.status && !toolArgs.comment) {
740
740
  toolArgs.comment = `Status updated via dashboard to ${attributes.status}`;
741
741
  }
742
- if (attributes.status === "completed" && toolArgs.est_tokens === void 0) {
743
- toolArgs.est_tokens = existingTask.est_tokens || 0;
742
+ if (attributes.status === "completed") {
743
+ if (toolArgs.est_tokens === void 0) {
744
+ toolArgs.est_tokens = existingTask.est_tokens || 0;
745
+ }
746
+ if (toolArgs.commit_id === void 0) {
747
+ toolArgs.commit_id = existingTask.commit_id || null;
748
+ }
749
+ if (toolArgs.changed_files === void 0) {
750
+ toolArgs.changed_files = existingTask.changed_files || [];
751
+ }
744
752
  }
745
753
  await mcpClient.callTool("task-update", toolArgs);
746
754
  await db.refresh();
@@ -57,7 +57,7 @@ import {
57
57
  toContextSlug,
58
58
  updateSessionFromInitialize,
59
59
  updateSessionRoots
60
- } from "../chunk-I57EED66.js";
60
+ } from "../chunk-UZWV2DYU.js";
61
61
 
62
62
  // src/mcp/server.ts
63
63
  import readline from "readline";
@@ -822,6 +822,16 @@ async function archiveTaskToMemory(taskId, repo, storage, vectors2) {
822
822
  `;
823
823
  content += `Description: ${task.description || "No description"}
824
824
  `;
825
+ content += `Commit: ${task.commit_id || "N/A"}
826
+ `;
827
+ if (task.changed_files && task.changed_files.length > 0) {
828
+ content += `Files changed:
829
+ `;
830
+ for (const f of task.changed_files) {
831
+ content += ` - ${f}
832
+ `;
833
+ }
834
+ }
825
835
  if (comments && comments.length > 0) {
826
836
  content += `
827
837
  Comments & History:
@@ -1203,8 +1213,10 @@ async function handleTaskUpdate(args, storage, vectors2) {
1203
1213
  );
1204
1214
  }
1205
1215
  }
1206
- if (updates.status === "completed" && isStatusChanging && updates.est_tokens === void 0) {
1207
- throw new Error("est_tokens is required when changing task status to completed");
1216
+ if (updates.status === "completed" && isStatusChanging) {
1217
+ if (updates.est_tokens === void 0) {
1218
+ throw new Error("est_tokens is required when changing task status to completed");
1219
+ }
1208
1220
  }
1209
1221
  if (updates.task_code && storage.tasks.isTaskCodeDuplicate(repo, updates.task_code, targetId)) {
1210
1222
  throw new Error(`Duplicate task_code: '${updates.task_code}' already exists`);
@@ -1225,8 +1237,11 @@ async function handleTaskUpdate(args, storage, vectors2) {
1225
1237
  }
1226
1238
  finalUpdates.tags = currentTags;
1227
1239
  }
1228
- if (updates.status === "completed") finalUpdates.finished_at = now;
1229
- else if (updates.status === "canceled") finalUpdates.canceled_at = now;
1240
+ if (updates.status === "completed") {
1241
+ finalUpdates.finished_at = now;
1242
+ finalUpdates.commit_id = updates.commit_id;
1243
+ finalUpdates.changed_files = updates.changed_files;
1244
+ } else if (updates.status === "canceled") finalUpdates.canceled_at = now;
1230
1245
  else if (updates.status === "in_progress" && existingTask.status !== "in_progress")
1231
1246
  finalUpdates.in_progress_at = now;
1232
1247
  storage.tasks.updateTask(targetId, finalUpdates);
@@ -1255,7 +1270,7 @@ async function handleTaskUpdate(args, storage, vectors2) {
1255
1270
  updatedCount++;
1256
1271
  }
1257
1272
  const isCompleted = updates.status === "completed" && updatedCount > 0;
1258
- let summaryText = isCompleted ? `Updated ${updatedCount} task(s) in repo "${repo}". \u2705 Task marked as completed \u2014 don't forget to commit your changes!` : `Updated ${updatedCount} task(s) in repo "${repo}".`;
1273
+ let summaryText = isCompleted ? `Updated ${updatedCount} task(s) in repo "${repo}". \u2705 Task marked as completed with commit ${updates.commit_id} (${(updates.changed_files || []).length} files changed).` : `Updated ${updatedCount} task(s) in repo "${repo}".`;
1259
1274
  if (releasedClaims || expiredHandoffs) {
1260
1275
  summaryText += ` Auto-closed coordination: released ${releasedClaims} claim(s), expired ${expiredHandoffs} handoff(s).`;
1261
1276
  }
@@ -94,7 +94,13 @@ agent: Task Executor
94
94
  - **Link Dependencies**: Set parent task's `depends_on` to the new blocker-fix task (parent waits for fix before retry)
95
95
  - **Skip Creation** (if external): Log that blocker is external, keep task status as `blocked`, no automatic task created.
96
96
 
97
- 11. **Repeat**: Claim next task from `task-list`.
97
+ 11. **Loop**: Follow `~/.agents/AGENTS.md` **CONTINUOUS EXECUTION MODE**:
98
+ - `task-list` (pending) → claim next
99
+ - If empty → promote backlog → loop
100
+ - If backlog empty → check stale in_progress → loop
101
+ - If stale empty → check handoff → loop
102
+ - **Only then → STOP**
103
+ - **Violation = incomplete execution**
98
104
 
99
105
  ## 3. BACKLOG MAINTENANCE
100
106
  If active queue is empty:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vheins/local-memory-mcp",
3
- "version": "0.12.1",
3
+ "version": "0.13.1",
4
4
  "description": "MCP Local Memory Service for coding copilot agents",
5
5
  "mcpName": "io.github.vheins/local-memory-mcp",
6
6
  "type": "module",