prism-mcp-server 20.7.0 → 20.7.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.
@@ -158,12 +158,36 @@ export async function getStorage() {
158
158
  return storageInstance;
159
159
  }
160
160
  export async function closeStorage() {
161
- if (storageInstance) {
162
- await storageInstance.close();
161
+ if (!storageInstance)
162
+ return;
163
+ const closing = storageInstance;
164
+ // Clear the slot in `finally`: if close() throws, the previous code left a
165
+ // DEAD instance installed as the singleton, and every later getStorage()
166
+ // handed that broken connection to callers. An empty slot is strictly
167
+ // safer — the next getStorage() re-opens cleanly. The error still
168
+ // propagates, so a caller like restoreFromBackup can abort before swapping
169
+ // the database file.
170
+ try {
171
+ await closing.close();
172
+ }
173
+ finally {
163
174
  storageInstance = null;
164
175
  }
165
176
  }
166
- /** Test-only: inject a pre-initialized storage instance into the singleton slot. */
177
+ /**
178
+ * Test-only: inject a pre-initialized storage instance into the singleton slot.
179
+ *
180
+ * CONTRACT: the CALLER owns the lifecycle of what it injects. This function
181
+ * deliberately does NOT close the instance it replaces — callers pair the
182
+ * injection with their own cleanup (see createTestDb().cleanup), so closing
183
+ * here would double-close a storage the test still owns.
184
+ *
185
+ * Worth knowing when auditing handle leaks: an instance dropped without
186
+ * close() keeps its sqlite lock, and on Windows that lock blocks unlink of
187
+ * the database file until the process exits (libsql close() does not release
188
+ * it either — tursodatabase/libsql-js#228 — so closing is hygiene, not a
189
+ * guarantee).
190
+ */
167
191
  export function _setStorageForTesting(instance) {
168
192
  storageInstance = instance;
169
193
  }
@@ -165,7 +165,24 @@ export async function restoreFromBackup(dbPath, backupPath) {
165
165
  // Create pre-restore backup
166
166
  const preRestoreResult = await createBackup(dbPath);
167
167
  debugLog(`Pre-restore backup: ${preRestoreResult.success ? "OK" : "FAILED"}`);
168
- // Copy backup over current database
168
+ // Release the live connection BEFORE swapping the file underneath it.
169
+ //
170
+ // NOT a platform workaround. Measured on windows-x64 (2026-08-05):
171
+ // overwriting the database while a connection is open SUCCEEDS on
172
+ // every platform — SQLite shares the file for reading and writing,
173
+ // and only unlink/rename are blocked. So restore was never broken.
174
+ //
175
+ // The reason is correctness: replacing a database file beneath a live
176
+ // connection leaves that connection pointing at bytes it did not
177
+ // read, with a stale page cache and a WAL that no longer describes
178
+ // the file. SQLite documents this as unsafe. closeStorage() makes the
179
+ // swap atomic from the connection's point of view — the next
180
+ // getStorage() opens the restored file cleanly.
181
+ const { closeStorage } = await import("../storage/index.js");
182
+ await closeStorage();
183
+ // Copy backup over current database. closeStorage() cleared the
184
+ // singleton, so the next getStorage() re-opens against the restored
185
+ // file and no caller retains a handle to the replaced one.
169
186
  copyFileSync(backupPath, dbPath);
170
187
  return {
171
188
  success: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prism-mcp-server",
3
- "version": "20.7.0",
3
+ "version": "20.7.1",
4
4
  "mcpName": "io.github.dcostenco/prism-coder",
5
5
  "description": "Prism Coder \u2014 Cognitive memory + tool-calling intelligence for AI agents. Mind Palace persistent memory (BFCL Gold Certified, 100% Tool-Call Accuracy, 114 Agent Skills, PHI Guard, Tier Enforcement, Prompt-Based Skill Routing, Zero-Search HDC/HRR retrieval, HRR Semantic Drift Detection across BCBA/Coding/AAC domains, HIPAA-hardened local or subscription-gated Synalux storage, SLERP-optimized GRPO alignment) plus the prism-coder 1.7B\u201332B open-weights LLM fleet.",
6
6
  "module": "index.ts",