nexo-brain 7.37.1 → 7.37.3

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexo-brain",
3
- "version": "7.37.1",
3
+ "version": "7.37.3",
4
4
  "description": "Local cognitive runtime for Claude Code \u2014 persistent memory, overnight learning, doctor diagnostics, personal scripts, recovery-aware jobs, startup preflight, and optional dashboard/power helper.",
5
5
  "author": {
6
6
  "name": "NEXO Brain",
package/README.md CHANGED
@@ -18,7 +18,11 @@
18
18
 
19
19
  [Watch the overview video](https://nexo-brain.com/watch/) · [Watch on YouTube](https://www.youtube.com/watch?v=i2lkGhKyVqI) · [Open the infographic](https://nexo-brain.com/assets/nexo-brain-infographic-v5.png)
20
20
 
21
- Version `7.37.1` is the current packaged-runtime line. Patch release over v7.37.0 - release hardening for Desktop-bundled Brain: large existing `local-context.db` files no longer run a surprise full `VACUUM` on the first writer, `schema_abstraction` MCP tools are loaded by the essential startup set, and learning tools tolerate Desktop compatibility payloads. Builds on v7.37.0 (transparent server self-heal + email zombie reinjection guard).
21
+ Version `7.37.3` is the current packaged-runtime line. Patch release over v7.37.2 - release pipeline timeout hardening: the Brain publish workflow keeps the full pre-publish pytest gate, but now gives slow GitHub runners enough time to finish the suite and release readiness before public-channel publication.
22
+
23
+ Previously in `7.37.2`: patch release over v7.37.1 - runtime shutdown and CI stability: session keepalive writers now stop before the shared SQLite connection closes, SQLite close is serialized under the write lock, and the full Brain test workflow has enough time to finish instead of cancelling slow-but-valid runs. The v7.37.2 tag attempt did not publish npm/GitHub release artifacts; v7.37.3 is the public line.
24
+
25
+ Previously in `7.37.1`: patch release over v7.37.0 - release hardening for Desktop-bundled Brain: large existing `local-context.db` files no longer run a surprise full `VACUUM` on the first writer, `schema_abstraction` MCP tools are loaded by the essential startup set, and learning tools tolerate Desktop compatibility payloads. Builds on v7.37.0 (transparent server self-heal + email zombie reinjection guard).
22
26
 
23
27
  Previously in `7.31.9`: patch release over v7.31.8 - UI release closeout now has to prove the original reported symptom was reopened with observable evidence before claiming the release is ready.
24
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexo-brain",
3
- "version": "7.37.1",
3
+ "version": "7.37.3",
4
4
  "mcpName": "io.github.wazionapps/nexo",
5
5
  "description": "NEXO Brain — Shared brain for AI agents. Persistent memory, semantic RAG, natural forgetting, metacognitive guard, trust scoring, 150+ MCP tools. Works with Claude Code, Codex, Claude Desktop & any MCP client. 100% local, free.",
6
6
  "homepage": "https://nexo-brain.com",
package/src/db/_core.py CHANGED
@@ -131,7 +131,8 @@ class _SerializedConnection:
131
131
  return self._conn.commit()
132
132
 
133
133
  def close(self):
134
- return self._conn.close()
134
+ with _write_lock:
135
+ return self._conn.close()
135
136
 
136
137
  def __getattr__(self, name):
137
138
  return getattr(self._conn, name)
@@ -111,7 +111,7 @@ def _safe_packet_payload(value, *, _depth: int = 0):
111
111
  return [_safe_packet_payload(item, _depth=_depth + 1) for item in list(value)[:100]]
112
112
  return _safe_packet_text(value)
113
113
 
114
- _keepalive_threads: dict[str, threading.Event] = {} # sid stop_event
114
+ _keepalive_threads: dict[str, tuple[threading.Event, threading.Thread]] = {} # sid -> (stop_event, thread)
115
115
 
116
116
 
117
117
  def _env_flag(name: str, default: bool = False) -> bool:
@@ -235,16 +235,34 @@ def _start_keepalive(sid: str) -> None:
235
235
  """Start a keepalive thread for the given session."""
236
236
  _stop_keepalive(sid) # clean up any leftover
237
237
  stop_event = threading.Event()
238
- _keepalive_threads[sid] = stop_event
239
238
  t = threading.Thread(target=_keepalive_loop, args=(sid, stop_event), daemon=True)
239
+ _keepalive_threads[sid] = (stop_event, t)
240
240
  t.start()
241
241
 
242
242
 
243
- def _stop_keepalive(sid: str) -> None:
243
+ def _stop_keepalive(sid: str, join_timeout: float = 1.0) -> None:
244
244
  """Signal the keepalive thread for the given session to stop."""
245
- stop_event = _keepalive_threads.pop(sid, None)
246
- if stop_event is not None:
245
+ entry = _keepalive_threads.pop(sid, None)
246
+ if entry is None:
247
+ return
248
+ stop_event, thread = entry
249
+ stop_event.set()
250
+ if thread is not threading.current_thread():
251
+ thread.join(timeout=max(0.0, join_timeout))
252
+
253
+
254
+ def _stop_all_keepalives(join_timeout: float = 1.0) -> None:
255
+ """Signal and briefly join all keepalive threads before DB shutdown."""
256
+ entries = list(_keepalive_threads.values())
257
+ _keepalive_threads.clear()
258
+ for stop_event, _thread in entries:
247
259
  stop_event.set()
260
+ deadline = time.monotonic() + max(0.0, join_timeout)
261
+ for _stop_event, thread in entries:
262
+ if thread is threading.current_thread():
263
+ continue
264
+ remaining = max(0.0, deadline - time.monotonic())
265
+ thread.join(timeout=remaining)
248
266
 
249
267
 
250
268
  def _generate_sid() -> str:
@@ -3283,6 +3283,19 @@
3283
3283
  },
3284
3284
  "triggers_after": []
3285
3285
  },
3286
+ "nexo_memory_forget": {
3287
+ "description": "Selective forget for revoked secrets or reversible fact correction",
3288
+ "category": "memory",
3289
+ "source": "server",
3290
+ "requires": [],
3291
+ "provides": [],
3292
+ "internal_calls": [],
3293
+ "enforcement": {
3294
+ "level": "none",
3295
+ "rules": []
3296
+ },
3297
+ "triggers_after": []
3298
+ },
3286
3299
  "nexo_memory_health": {
3287
3300
  "description": "Report Memory Observations v2 health and table status",
3288
3301
  "category": "memory",