cf-memory-mcp 3.61.0 → 3.62.0

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.
@@ -2672,6 +2672,42 @@ class CFMemoryMCP {
2672
2672
  }
2673
2673
  }
2674
2674
 
2675
+ /**
2676
+ * Drop the implicit-session disk cache iff the cached session id is
2677
+ * in `deletedSessionIds`. Called from the delete CLI so a subsequent
2678
+ * end_session against the implicit cache won't write to a session
2679
+ * that no longer exists on the server. Also clears the in-memory map
2680
+ * for the matching cwd. Returns true when something was dropped.
2681
+ */
2682
+ invalidateImplicitSessionIfMatches(deletedSessionIds) {
2683
+ if (!deletedSessionIds || !deletedSessionIds.length) return false;
2684
+ const matchSet = new Set(deletedSessionIds);
2685
+ let dropped = false;
2686
+ try {
2687
+ const implicitPath = this.getImplicitSessionDiskPath();
2688
+ if (implicitPath && fs.existsSync(implicitPath)) {
2689
+ const entry = JSON.parse(fs.readFileSync(implicitPath, 'utf8'));
2690
+ if (matchSet.has(entry.session_id)) {
2691
+ fs.unlinkSync(implicitPath);
2692
+ dropped = true;
2693
+ }
2694
+ }
2695
+ } catch (_) { /* non-fatal */ }
2696
+ // Also evict in-memory entries so a long-lived bridge stops
2697
+ // auto-filling the deleted id.
2698
+ try {
2699
+ if (this._implicitSessionByCwd && this._implicitSessionByCwd.size) {
2700
+ for (const [cwd, sid] of this._implicitSessionByCwd.entries()) {
2701
+ if (matchSet.has(sid)) {
2702
+ this._implicitSessionByCwd.delete(cwd);
2703
+ dropped = true;
2704
+ }
2705
+ }
2706
+ }
2707
+ } catch (_) { /* non-fatal */ }
2708
+ return dropped;
2709
+ }
2710
+
2675
2711
  /**
2676
2712
  * Return the implicit session_id for the current cwd, creating one via
2677
2713
  * start_session when no session is active. Lets agents skip explicit
@@ -5215,6 +5251,12 @@ async function runDeleteCli() {
5215
5251
  });
5216
5252
  const deleteText = deleteRes?.result?.content?.[0]?.text;
5217
5253
  const payload = JSON.parse(deleteText || '{}');
5254
+ // Implicit-cache invalidation: if any deleted id matches the
5255
+ // current cwd's implicit session, drop the cache so the next
5256
+ // end_session creates a fresh one.
5257
+ if (payload.deleted) {
5258
+ server.invalidateImplicitSessionIfMatches(payload.deleted_session_ids || []);
5259
+ }
5218
5260
  if (flags.json) {
5219
5261
  process.stdout.write(JSON.stringify(payload, null, 2) + '\n');
5220
5262
  process.exit(payload.deleted ? 0 : 3);
@@ -5254,6 +5296,12 @@ async function runDeleteCli() {
5254
5296
  });
5255
5297
  const deleteText = deleteRes?.result?.content?.[0]?.text;
5256
5298
  const payload = JSON.parse(deleteText || '{}');
5299
+ // Drop the implicit-session disk cache if the deleted id matches
5300
+ // it. Otherwise a subsequent end_session would try to write to a
5301
+ // session that no longer exists.
5302
+ if (payload.deleted) {
5303
+ server.invalidateImplicitSessionIfMatches([fullId]);
5304
+ }
5257
5305
  if (flags.json) {
5258
5306
  process.stdout.write(JSON.stringify({ ...payload, session_id: fullId }, null, 2) + '\n');
5259
5307
  process.exit(payload.deleted ? 0 : 3);
@@ -6097,11 +6145,15 @@ async function runCleanCli() {
6097
6145
  const removed = [];
6098
6146
  try {
6099
6147
  if (all) {
6100
- // Clear ALL disk caches in ~/.cf-memory/.
6148
+ // Clear ALL disk caches in ~/.cf-memory/: handoff-*.json
6149
+ // (offline resume cache) AND implicit-*.json (persistent
6150
+ // implicit session id per cwd).
6101
6151
  const dir = path.join(os.homedir(), '.cf-memory');
6102
6152
  if (fs.existsSync(dir)) {
6103
6153
  for (const entry of fs.readdirSync(dir)) {
6104
- if (entry.startsWith('handoff-') && entry.endsWith('.json')) {
6154
+ const isHandoff = entry.startsWith('handoff-') && entry.endsWith('.json');
6155
+ const isImplicit = entry.startsWith('implicit-') && entry.endsWith('.json');
6156
+ if (isHandoff || isImplicit) {
6105
6157
  const full = path.join(dir, entry);
6106
6158
  fs.unlinkSync(full);
6107
6159
  removed.push(full);
@@ -6109,10 +6161,17 @@ async function runCleanCli() {
6109
6161
  }
6110
6162
  }
6111
6163
  } else {
6112
- const p = server.getDiskCachePath();
6113
- if (p && fs.existsSync(p)) {
6114
- fs.unlinkSync(p);
6115
- removed.push(p);
6164
+ // cwd-only mode: drop both the handoff cache AND the
6165
+ // implicit session cache for this cwd.
6166
+ const handoffPath = server.getDiskCachePath();
6167
+ if (handoffPath && fs.existsSync(handoffPath)) {
6168
+ fs.unlinkSync(handoffPath);
6169
+ removed.push(handoffPath);
6170
+ }
6171
+ const implicitPath = server.getImplicitSessionDiskPath();
6172
+ if (implicitPath && fs.existsSync(implicitPath)) {
6173
+ fs.unlinkSync(implicitPath);
6174
+ removed.push(implicitPath);
6116
6175
  }
6117
6176
  }
6118
6177
  if (flags.json) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cf-memory-mcp",
3
- "version": "3.61.0",
3
+ "version": "3.62.0",
4
4
  "description": "Cloudflare-hosted MCP server for code indexing, retrieval, and assistant memory with a direct remote MCP endpoint and local stdio bridge.",
5
5
  "main": "bin/cf-memory-mcp.js",
6
6
  "bin": {