nexo-brain 7.17.7 → 7.17.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": "7.17.7",
3
+ "version": "7.17.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,9 @@
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.17.7` is the current packaged-runtime line. Patch release over v7.17.6 - macOS TCC privacy denials now become a guided Full Disk Access permission state instead of an unexplained cron failure, with Desktop-ready status written for user action.
21
+ Version `7.17.8` is the current packaged-runtime line. Patch release over v7.17.7 - standalone `nexo chat` now surfaces macOS Full Disk Access guidance, and Brain clears stale permission state after a live access probe succeeds.
22
+
23
+ Previously in `7.17.7`: patch release over v7.17.6 - macOS TCC privacy denials now become a guided Full Disk Access permission state instead of an unexplained cron failure, with Desktop-ready status written for user action.
22
24
 
23
25
  Previously in `7.17.6`: patch release over v7.17.5 - cron health diagnostics are clearer for macOS TCC approval, and catch-up fallback executions now stay visible in `cron_runs` even on legacy or partially migrated runtimes.
24
26
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexo-brain",
3
- "version": "7.17.7",
3
+ "version": "7.17.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",
package/src/cli.py CHANGED
@@ -2187,6 +2187,29 @@ def _prompt_for_terminal_client(
2187
2187
  print("Invalid choice. Try again.", file=sys.stderr)
2188
2188
 
2189
2189
 
2190
+ def _ensure_chat_full_disk_access_notice(*, interactive: bool | None = None) -> dict:
2191
+ runtime_power = _load_runtime_power_support()
2192
+ if interactive is None:
2193
+ interactive = bool(getattr(sys.stdin, "isatty", lambda: False)())
2194
+ try:
2195
+ choice = runtime_power["ensure_full_disk_access_choice"](
2196
+ interactive=interactive,
2197
+ reason="chat",
2198
+ output_fn=lambda message: print(message, file=sys.stderr),
2199
+ )
2200
+ except EOFError:
2201
+ return {
2202
+ "status": "later",
2203
+ "prompted": False,
2204
+ "reasons": [],
2205
+ "message": "Full Disk Access setup skipped because stdin closed.",
2206
+ }
2207
+ message = str(choice.get("message") or "").strip()
2208
+ if message and (choice.get("prompted") or choice.get("relevant")):
2209
+ print(f"[NEXO] Full Disk Access: {message}", file=sys.stderr)
2210
+ return choice
2211
+
2212
+
2190
2213
  def _chat(args):
2191
2214
  target = args.path or "."
2192
2215
  selected_client = getattr(args, "client", None)
@@ -2211,6 +2234,11 @@ def _chat(args):
2211
2234
  except Exception:
2212
2235
  pass
2213
2236
 
2237
+ try:
2238
+ _ensure_chat_full_disk_access_notice()
2239
+ except Exception as exc:
2240
+ print(f"[NEXO] Full Disk Access check warning: {exc}", file=sys.stderr)
2241
+
2214
2242
  try:
2215
2243
  from client_preferences import (
2216
2244
  detect_installed_clients,
@@ -49,6 +49,7 @@ FULL_DISK_ACCESS_UNSET = "unset"
49
49
  FULL_DISK_ACCESS_GRANTED = "granted"
50
50
  FULL_DISK_ACCESS_DECLINED = "declined"
51
51
  FULL_DISK_ACCESS_LATER = "later"
52
+ FULL_DISK_ACCESS_STATE_FILE = NEXO_HOME / "runtime" / "state" / "full-disk-access-required.json"
52
53
  VALID_FULL_DISK_ACCESS_STATUSES = {
53
54
  FULL_DISK_ACCESS_UNSET,
54
55
  FULL_DISK_ACCESS_GRANTED,
@@ -794,14 +795,25 @@ def set_power_policy(policy: str) -> dict:
794
795
 
795
796
  def set_full_disk_access_status(status: str, *, reasons: list[str] | None = None) -> dict:
796
797
  schedule = load_schedule_config()
797
- schedule[FULL_DISK_ACCESS_STATUS_KEY] = normalize_full_disk_access_status(status)
798
+ normalized = normalize_full_disk_access_status(status)
799
+ schedule[FULL_DISK_ACCESS_STATUS_KEY] = normalized
798
800
  schedule[FULL_DISK_ACCESS_STATUS_VERSION_KEY] = FULL_DISK_ACCESS_STATUS_VERSION
801
+ if normalized == FULL_DISK_ACCESS_GRANTED:
802
+ reasons = []
803
+ clear_full_disk_access_required_state()
799
804
  if reasons is not None:
800
805
  schedule[FULL_DISK_ACCESS_REASONS_KEY] = normalize_full_disk_access_reasons(reasons)
801
806
  save_schedule_config(schedule)
802
807
  return schedule
803
808
 
804
809
 
810
+ def clear_full_disk_access_required_state() -> None:
811
+ try:
812
+ FULL_DISK_ACCESS_STATE_FILE.unlink(missing_ok=True)
813
+ except Exception:
814
+ pass
815
+
816
+
805
817
  def prompt_for_power_policy(
806
818
  *,
807
819
  reason: str = "install",
@@ -938,6 +950,9 @@ def ensure_full_disk_access_choice(
938
950
  )
939
951
 
940
952
  schedule[FULL_DISK_ACCESS_STATUS_KEY] = status
953
+ if status == FULL_DISK_ACCESS_GRANTED:
954
+ schedule[FULL_DISK_ACCESS_REASONS_KEY] = []
955
+ clear_full_disk_access_required_state()
941
956
  save_schedule_config(schedule)
942
957
  return {
943
958
  "status": status,