nexo-brain 5.0.0 → 5.0.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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +7 -1
- package/package.json +1 -1
- package/src/client_sync.py +45 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.1",
|
|
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
|
@@ -87,6 +87,12 @@ Versions `3.1.7` through `3.2.0` close the recent-memory gap:
|
|
|
87
87
|
- when even that misses, NEXO now exposes raw transcript fallback tools for Claude Code and Codex session stores
|
|
88
88
|
- NEXO can now inspect itself through a live system catalog derived from canonical sources instead of relying only on stale docs or operator memory
|
|
89
89
|
|
|
90
|
+
Version `5.0.1` hardens the live 5.0 upgrade path:
|
|
91
|
+
|
|
92
|
+
- managed Claude Code hooks are now cleaned up when an older release left obsolete core-managed entries behind
|
|
93
|
+
- upgrades no longer preserve the stale `heartbeat-guard.sh` path that could create warning storms and fake "hung" symptoms after `nexo update`
|
|
94
|
+
- the corrected path has been revalidated on a real install with `nexo clients sync`, Codex/Claude Code headless runtime access, email-monitor recovery, and a full `nexo update`
|
|
95
|
+
|
|
90
96
|
Version `5.0.0` closes the loop between memory, decisions, outcomes, and reusable behavior:
|
|
91
97
|
|
|
92
98
|
- goal profiles are now explicit and auditable instead of living as hidden heuristics
|
|
@@ -702,7 +708,7 @@ The installer handles everything and syncs the same `nexo` MCP brain into Claude
|
|
|
702
708
|
- Node.js project detected
|
|
703
709
|
Configuring MCP server...
|
|
704
710
|
Setting up nervous system...
|
|
705
|
-
|
|
711
|
+
15 core recovery-aware jobs configured.
|
|
706
712
|
Dashboard configured at localhost:6174.
|
|
707
713
|
Caffeinate enabled.
|
|
708
714
|
Generating operator instructions...
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.1",
|
|
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/client_sync.py
CHANGED
|
@@ -386,6 +386,32 @@ CORE_HOOK_SPECS = [
|
|
|
386
386
|
},
|
|
387
387
|
]
|
|
388
388
|
|
|
389
|
+
LEGACY_CORE_HOOK_IDENTITIES_BY_EVENT = {
|
|
390
|
+
"PostToolUse": {
|
|
391
|
+
"heartbeat-guard.sh",
|
|
392
|
+
},
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def _current_core_hook_identities_by_event() -> dict[str, set[str]]:
|
|
397
|
+
identities: dict[str, set[str]] = {}
|
|
398
|
+
for spec in CORE_HOOK_SPECS:
|
|
399
|
+
identities.setdefault(spec["event"], set()).add(spec["identity"])
|
|
400
|
+
return identities
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
CURRENT_CORE_HOOK_IDENTITIES_BY_EVENT = _current_core_hook_identities_by_event()
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def _managed_core_hook_identities_by_event() -> dict[str, set[str]]:
|
|
407
|
+
managed = {event: set(identities) for event, identities in CURRENT_CORE_HOOK_IDENTITIES_BY_EVENT.items()}
|
|
408
|
+
for event, identities in LEGACY_CORE_HOOK_IDENTITIES_BY_EVENT.items():
|
|
409
|
+
managed.setdefault(event, set()).update(identities)
|
|
410
|
+
return managed
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
MANAGED_CORE_HOOK_IDENTITIES_BY_EVENT = _managed_core_hook_identities_by_event()
|
|
414
|
+
|
|
389
415
|
|
|
390
416
|
def _resolve_hook_source_dir(runtime_root: Path) -> Path:
|
|
391
417
|
direct = runtime_root / "hooks"
|
|
@@ -450,6 +476,25 @@ def _merge_core_hooks(existing_hooks, *, runtime_root: Path, nexo_home: Path) ->
|
|
|
450
476
|
hooks_dir = _resolve_hook_source_dir(runtime_root)
|
|
451
477
|
managed_count = 0
|
|
452
478
|
|
|
479
|
+
for event, managed_identities in MANAGED_CORE_HOOK_IDENTITIES_BY_EVENT.items():
|
|
480
|
+
sections = _normalize_hook_sections(hooks_payload.get(event))
|
|
481
|
+
desired_identities = CURRENT_CORE_HOOK_IDENTITIES_BY_EVENT.get(event, set())
|
|
482
|
+
cleaned_sections: list[dict] = []
|
|
483
|
+
for section in sections:
|
|
484
|
+
cleaned_hooks = []
|
|
485
|
+
for hook in section["hooks"]:
|
|
486
|
+
identity = _hook_identity(hook.get("command", ""))
|
|
487
|
+
if identity in managed_identities and identity not in desired_identities:
|
|
488
|
+
continue
|
|
489
|
+
cleaned_hooks.append(hook)
|
|
490
|
+
cleaned_sections.append(
|
|
491
|
+
{
|
|
492
|
+
"matcher": section.get("matcher", "*") or "*",
|
|
493
|
+
"hooks": cleaned_hooks,
|
|
494
|
+
}
|
|
495
|
+
)
|
|
496
|
+
hooks_payload[event] = cleaned_sections
|
|
497
|
+
|
|
453
498
|
for spec in CORE_HOOK_SPECS:
|
|
454
499
|
event = spec["event"]
|
|
455
500
|
sections = _normalize_hook_sections(hooks_payload.get(event))
|