nexo-brain 5.3.7 → 5.3.8

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": "5.3.7",
3
+ "version": "5.3.8",
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,7 @@
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 `5.3.4` closes the last packaged-runtime core/personal leak from the hook migration work: legacy hook aliases stay out of the personal bucket, `nexo update` removes those retired aliases when the canonical hooks already exist, and both `nexo` and `nexo chat` now show latest vs installed version at a glance.
21
+ Version `5.3.8` is the current packaged-runtime line: packaged installs now self-heal more of the update path, portable user-data export/import is explicit, tracked Codex drift no longer leaves runtime doctor red after cleanup, and the packaged migrator copies newly added root runtime modules into `~/.nexo` instead of leaving them stranded in the npm tarball.
22
22
 
23
23
  Start here:
24
24
  - [5-minute quickstart](docs/quickstart-5-minutes.md)
@@ -89,7 +89,7 @@ Versions `3.1.7` through `3.2.0` close the recent-memory gap:
89
89
  - when even that misses, NEXO now exposes raw transcript fallback tools for Claude Code and Codex session stores
90
90
  - NEXO can now inspect itself through a live system catalog derived from canonical sources instead of relying only on stale docs or operator memory
91
91
 
92
- Version `5.3.7` closes the remaining packaged-runtime happy-path gap and finally exposes portable user-data migration commands: packaged `nexo update` now self-heals cron definitions and LaunchAgents after a successful npm bump, new `nexo export` / `nexo import` commands move operator data as a safe bundle instead of leaving that flow implicit, and runtime doctor now distinguishes tracked historical Codex drift from an actually broken runtime so cleaned installs stop staying red for stale transcript debt alone. Version `5.3.6` hardened the Claude Code bootstrap path and related runtime hygiene: managed client sync now writes the NEXO MCP server where current Claude Code actually reads it (`~/.claude.json`), script classification is stricter about core-vs-personal runtime artifacts, schedule status distinguishes genuinely running jobs from broken ones, and retroactive learnings stop opening keyword-only false positives outside their declared `applies_to` scope. Version `5.3.5` already keeps CLI version visibility honest right after `nexo update`: if the cached npm version lags behind the runtime you just installed, `nexo` / `nexo chat` now clamp `Latest` to the installed version and refresh the cache instead of showing a stale older release. Version `5.3.4` already cleaned up legacy core alias leakage and added the version-status banner. Version `5.3.3` closed the remaining packaged-runtime doctor mismatch: the built-in hourly backup helper is now inventoried as a core LaunchAgent, so clean installs no longer get a false unknown-LaunchAgent warning. Version `5.3.2` already hardened the runtime boundary by persisting which runtime scripts/hooks are core product artifacts, keeping `nexo scripts` from mixing those into the personal bucket, and migrating the legacy Claude Code heartbeat wrappers into managed core hooks.
92
+ Version `5.3.8` is the immediate packaged-migration hotfix for `5.3.7`: the installer/runtime migrator now discovers all top-level runtime Python modules from `src/` dynamically instead of relying on a manual allowlist, so new product surfaces like `nexo export` / `nexo import` actually arrive in `~/.nexo` after update instead of being present only in the published npm tarball. Version `5.3.7` closed the remaining packaged-runtime happy-path gap and finally exposed portable user-data migration commands: packaged `nexo update` now self-heals cron definitions and LaunchAgents after a successful npm bump, new `nexo export` / `nexo import` commands move operator data as a safe bundle instead of leaving that flow implicit, and runtime doctor now distinguishes tracked historical Codex drift from an actually broken runtime so cleaned installs stop staying red for stale transcript debt alone. Version `5.3.6` hardened the Claude Code bootstrap path and related runtime hygiene: managed client sync now writes the NEXO MCP server where current Claude Code actually reads it (`~/.claude.json`), script classification is stricter about core-vs-personal runtime artifacts, schedule status distinguishes genuinely running jobs from broken ones, and retroactive learnings stop opening keyword-only false positives outside their declared `applies_to` scope. Version `5.3.5` already keeps CLI version visibility honest right after `nexo update`: if the cached npm version lags behind the runtime you just installed, `nexo` / `nexo chat` now clamp `Latest` to the installed version and refresh the cache instead of showing a stale older release. Version `5.3.4` already cleaned up legacy core alias leakage and added the version-status banner. Version `5.3.3` closed the remaining packaged-runtime doctor mismatch: the built-in hourly backup helper is now inventoried as a core LaunchAgent, so clean installs no longer get a false unknown-LaunchAgent warning. Version `5.3.2` already hardened the runtime boundary by persisting which runtime scripts/hooks are core product artifacts, keeping `nexo scripts` from mixing those into the personal bucket, and migrating the legacy Claude Code heartbeat wrappers into managed core hooks.
93
93
 
94
94
  Version `5.3.1` normalizes packaged npm installs so they behave like packaged npm installs: `nexo update` now keeps the runtime anchored to `~/.nexo`, refreshes packaged bootstrap/client artifacts after upgrade, avoids repo-only release-artifact drift in installed runtimes, and keeps personal scripts on the canonical packaged path.
95
95
 
package/bin/nexo-brain.js CHANGED
@@ -120,8 +120,8 @@ function writeRuntimeCoreArtifactsManifest(nexoHome, srcDir) {
120
120
  }
121
121
  }
122
122
 
123
- function getCoreRuntimeFlatFiles() {
124
- return [
123
+ function getCoreRuntimeFlatFiles(srcDir = path.join(__dirname, "..", "src")) {
124
+ const staticFiles = [
125
125
  "server.py",
126
126
  "plugin_loader.py",
127
127
  "knowledge_graph.py",
@@ -155,6 +155,11 @@ function getCoreRuntimeFlatFiles() {
155
155
  "runtime_power.py",
156
156
  "requirements.txt",
157
157
  ];
158
+ const discoveredRootModules = fs.existsSync(srcDir)
159
+ ? fs.readdirSync(srcDir)
160
+ .filter((name) => name.endsWith(".py") && fs.statSync(path.join(srcDir, name)).isFile())
161
+ : [];
162
+ return [...new Set([...staticFiles, ...discoveredRootModules])];
158
163
  }
159
164
 
160
165
  function getCoreRuntimePackages() {
@@ -1480,7 +1485,7 @@ async function main() {
1480
1485
  log(" Hooks updated.");
1481
1486
 
1482
1487
  // Update core Python files (flat .py files in src/)
1483
- const coreFlatFiles = getCoreRuntimeFlatFiles();
1488
+ const coreFlatFiles = getCoreRuntimeFlatFiles(srcDir);
1484
1489
  coreFlatFiles.forEach((f) => {
1485
1490
  const src = path.join(srcDir, f);
1486
1491
  if (fs.existsSync(src)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexo-brain",
3
- "version": "5.3.7",
3
+ "version": "5.3.8",
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",
@@ -95,12 +95,32 @@ def _copy_file_if_present(src: Path, dest: Path) -> bool:
95
95
 
96
96
 
97
97
  def _safe_extract(archive_path: Path, dest_dir: Path) -> None:
98
+ resolved_dest = dest_dir.resolve()
98
99
  with tarfile.open(archive_path, "r:*") as tar:
99
- for member in tar.getmembers():
100
+ members = tar.getmembers()
101
+ for member in members:
100
102
  target = (dest_dir / member.name).resolve()
101
- if not str(target).startswith(str(dest_dir.resolve())):
103
+ if target != resolved_dest and resolved_dest not in target.parents:
102
104
  raise ValueError(f"archive path escapes destination: {member.name}")
103
- tar.extractall(dest_dir)
105
+ if member.issym() or member.islnk():
106
+ raise ValueError(f"archive contains unsupported link member: {member.name}")
107
+
108
+ for member in members:
109
+ target = (dest_dir / member.name).resolve()
110
+ if member.isdir():
111
+ target.mkdir(parents=True, exist_ok=True)
112
+ target.chmod(member.mode & 0o777)
113
+ continue
114
+ if not member.isfile():
115
+ raise ValueError(f"archive contains unsupported member type: {member.name}")
116
+
117
+ target.parent.mkdir(parents=True, exist_ok=True)
118
+ extracted = tar.extractfile(member)
119
+ if extracted is None:
120
+ raise ValueError(f"archive member could not be read: {member.name}")
121
+ with extracted, target.open("wb") as handle:
122
+ shutil.copyfileobj(extracted, handle)
123
+ target.chmod(member.mode & 0o777)
104
124
 
105
125
 
106
126
  def _load_personal_scripts() -> tuple[list[dict], list[dict]]:
@@ -298,5 +318,11 @@ def import_user_bundle(bundle_path: str) -> dict:
298
318
  "restored": restored,
299
319
  "reconciled": reconcile_result,
300
320
  }
321
+ except Exception as exc:
322
+ return {
323
+ "ok": False,
324
+ "error": str(exc),
325
+ "safety_backup": str(safety_backup),
326
+ }
301
327
  finally:
302
328
  shutil.rmtree(stage_dir, ignore_errors=True)