nexo-brain 2.3.0 → 2.3.2

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.
Files changed (299) hide show
  1. package/README.md +1 -1
  2. package/bin/nexo-brain.js +92 -9
  3. package/bin/postinstall.js +22 -15
  4. package/package.json +7 -4
  5. package/src/auto_update.py +194 -5
  6. package/src/crons/sync.py +6 -2
  7. package/src/db/_core.py +1 -0
  8. package/src/db/_entities.py +1 -0
  9. package/src/db/_episodic.py +1 -0
  10. package/src/db/_learnings.py +1 -0
  11. package/src/db/_reminders.py +1 -0
  12. package/src/db/_schema.py +11 -1
  13. package/src/db/_sessions.py +1 -0
  14. package/src/db/_skills.py +1 -0
  15. package/src/hooks/capture-tool-logs.sh +23 -6
  16. package/src/hooks/session-start.sh +4 -3
  17. package/src/plugin_loader.py +1 -0
  18. package/src/plugins/update.py +377 -26
  19. package/src/scripts/deep-sleep/apply_findings.py +1 -0
  20. package/src/scripts/deep-sleep/collect.py +1 -0
  21. package/src/scripts/deep-sleep/extract.py +1 -0
  22. package/src/scripts/deep-sleep/synthesize.py +1 -0
  23. package/src/scripts/nexo-catchup.py +29 -4
  24. package/src/scripts/nexo-daily-self-audit.py +21 -1
  25. package/src/scripts/nexo-evolution-run.py +21 -1
  26. package/src/scripts/nexo-learning-housekeep.py +1 -0
  27. package/src/scripts/nexo-postmortem-consolidator.py +34 -9
  28. package/src/scripts/nexo-sleep.py +32 -10
  29. package/src/scripts/nexo-synthesis.py +29 -9
  30. package/src/scripts/nexo-update.sh +109 -7
  31. package/src/scripts/nexo-watchdog.sh +122 -58
  32. package/src/server.py +66 -1
  33. package/src/tools_coordination.py +1 -0
  34. package/src/tools_sessions.py +1 -0
  35. package/scripts/migrate-to-unified 2.sh +0 -813
  36. package/scripts/migrate-to-unified.sh +0 -813
  37. package/scripts/migrate-v1.5-to-v1.6 2.py +0 -778
  38. package/scripts/migrate-v1.5-to-v1.6.py +0 -778
  39. package/scripts/migrate-v1.7-to-v1.8 2.py +0 -214
  40. package/scripts/migrate-v1.7-to-v1.8.py +0 -214
  41. package/scripts/nexo-preflight.sh +0 -236
  42. package/scripts/pre-commit-check 2.sh +0 -55
  43. package/scripts/pre-commit-check.sh +0 -55
  44. package/src/__pycache__/auto_close_sessions.cpython-314.pyc +0 -0
  45. package/src/__pycache__/auto_update.cpython-310.pyc +0 -0
  46. package/src/__pycache__/hnsw_index.cpython-310.pyc +0 -0
  47. package/src/__pycache__/hnsw_index.cpython-314.pyc +0 -0
  48. package/src/__pycache__/kg_populate.cpython-310.pyc +0 -0
  49. package/src/__pycache__/knowledge_graph.cpython-310.pyc +0 -0
  50. package/src/__pycache__/plugin_loader.cpython-310.pyc +0 -0
  51. package/src/__pycache__/plugin_loader.cpython-314.pyc +0 -0
  52. package/src/__pycache__/tools_coordination.cpython-310.pyc +0 -0
  53. package/src/__pycache__/tools_credentials.cpython-310.pyc +0 -0
  54. package/src/__pycache__/tools_learnings.cpython-310.pyc +0 -0
  55. package/src/__pycache__/tools_menu.cpython-310.pyc +0 -0
  56. package/src/__pycache__/tools_reminders.cpython-310.pyc +0 -0
  57. package/src/__pycache__/tools_reminders_crud.cpython-310.pyc +0 -0
  58. package/src/__pycache__/tools_sessions.cpython-310.pyc +0 -0
  59. package/src/__pycache__/tools_task_history.cpython-310.pyc +0 -0
  60. package/src/auto_close_sessions 2.py +0 -159
  61. package/src/auto_update 2.py +0 -634
  62. package/src/claim_graph 2.py +0 -323
  63. package/src/cognitive/__init__ 2.py +0 -62
  64. package/src/cognitive/__pycache__/__init__.cpython-310.pyc +0 -0
  65. package/src/cognitive/__pycache__/__init__.cpython-312.pyc +0 -0
  66. package/src/cognitive/__pycache__/__init__.cpython-314.pyc +0 -0
  67. package/src/cognitive/__pycache__/_core.cpython-310.pyc +0 -0
  68. package/src/cognitive/__pycache__/_core.cpython-312.pyc +0 -0
  69. package/src/cognitive/__pycache__/_core.cpython-314.pyc +0 -0
  70. package/src/cognitive/__pycache__/_decay.cpython-310.pyc +0 -0
  71. package/src/cognitive/__pycache__/_decay.cpython-312.pyc +0 -0
  72. package/src/cognitive/__pycache__/_decay.cpython-314.pyc +0 -0
  73. package/src/cognitive/__pycache__/_ingest.cpython-310.pyc +0 -0
  74. package/src/cognitive/__pycache__/_ingest.cpython-312.pyc +0 -0
  75. package/src/cognitive/__pycache__/_ingest.cpython-314.pyc +0 -0
  76. package/src/cognitive/__pycache__/_memory.cpython-310.pyc +0 -0
  77. package/src/cognitive/__pycache__/_memory.cpython-312.pyc +0 -0
  78. package/src/cognitive/__pycache__/_memory.cpython-314.pyc +0 -0
  79. package/src/cognitive/__pycache__/_search.cpython-310.pyc +0 -0
  80. package/src/cognitive/__pycache__/_search.cpython-312.pyc +0 -0
  81. package/src/cognitive/__pycache__/_search.cpython-314.pyc +0 -0
  82. package/src/cognitive/__pycache__/_trust.cpython-310.pyc +0 -0
  83. package/src/cognitive/__pycache__/_trust.cpython-312.pyc +0 -0
  84. package/src/cognitive/__pycache__/_trust.cpython-314.pyc +0 -0
  85. package/src/cognitive/_core 2.py +0 -567
  86. package/src/cognitive/_decay 2.py +0 -382
  87. package/src/cognitive/_ingest 2.py +0 -892
  88. package/src/cognitive/_memory 2.py +0 -912
  89. package/src/cognitive/_search 2.py +0 -949
  90. package/src/cognitive/_trust 2.py +0 -464
  91. package/src/crons/__pycache__/sync.cpython-314.pyc +0 -0
  92. package/src/crons/manifest 2.json +0 -106
  93. package/src/crons/sync 2.py +0 -217
  94. package/src/dashboard/__init__ 2.py +0 -0
  95. package/src/dashboard/__pycache__/__init__.cpython-310.pyc +0 -0
  96. package/src/dashboard/__pycache__/app.cpython-310.pyc +0 -0
  97. package/src/dashboard/app 2.py +0 -789
  98. package/src/db/__init__ 2.py +0 -89
  99. package/src/db/__pycache__/__init__.cpython-310.pyc +0 -0
  100. package/src/db/__pycache__/__init__.cpython-312.pyc +0 -0
  101. package/src/db/__pycache__/__init__.cpython-314.pyc +0 -0
  102. package/src/db/__pycache__/_core.cpython-310.pyc +0 -0
  103. package/src/db/__pycache__/_core.cpython-312.pyc +0 -0
  104. package/src/db/__pycache__/_core.cpython-314.pyc +0 -0
  105. package/src/db/__pycache__/_credentials.cpython-310.pyc +0 -0
  106. package/src/db/__pycache__/_credentials.cpython-312.pyc +0 -0
  107. package/src/db/__pycache__/_credentials.cpython-314.pyc +0 -0
  108. package/src/db/__pycache__/_cron_runs.cpython-310.pyc +0 -0
  109. package/src/db/__pycache__/_cron_runs.cpython-314.pyc +0 -0
  110. package/src/db/__pycache__/_entities.cpython-310.pyc +0 -0
  111. package/src/db/__pycache__/_entities.cpython-312.pyc +0 -0
  112. package/src/db/__pycache__/_entities.cpython-314.pyc +0 -0
  113. package/src/db/__pycache__/_episodic.cpython-310.pyc +0 -0
  114. package/src/db/__pycache__/_episodic.cpython-312.pyc +0 -0
  115. package/src/db/__pycache__/_episodic.cpython-314.pyc +0 -0
  116. package/src/db/__pycache__/_evolution.cpython-310.pyc +0 -0
  117. package/src/db/__pycache__/_evolution.cpython-312.pyc +0 -0
  118. package/src/db/__pycache__/_evolution.cpython-314.pyc +0 -0
  119. package/src/db/__pycache__/_fts.cpython-310.pyc +0 -0
  120. package/src/db/__pycache__/_fts.cpython-312.pyc +0 -0
  121. package/src/db/__pycache__/_fts.cpython-314.pyc +0 -0
  122. package/src/db/__pycache__/_learnings.cpython-310.pyc +0 -0
  123. package/src/db/__pycache__/_learnings.cpython-312.pyc +0 -0
  124. package/src/db/__pycache__/_learnings.cpython-314.pyc +0 -0
  125. package/src/db/__pycache__/_reminders.cpython-310.pyc +0 -0
  126. package/src/db/__pycache__/_reminders.cpython-312.pyc +0 -0
  127. package/src/db/__pycache__/_reminders.cpython-314.pyc +0 -0
  128. package/src/db/__pycache__/_schema.cpython-310.pyc +0 -0
  129. package/src/db/__pycache__/_schema.cpython-312.pyc +0 -0
  130. package/src/db/__pycache__/_schema.cpython-314.pyc +0 -0
  131. package/src/db/__pycache__/_sessions.cpython-310.pyc +0 -0
  132. package/src/db/__pycache__/_sessions.cpython-312.pyc +0 -0
  133. package/src/db/__pycache__/_sessions.cpython-314.pyc +0 -0
  134. package/src/db/__pycache__/_skills.cpython-310.pyc +0 -0
  135. package/src/db/__pycache__/_skills.cpython-312.pyc +0 -0
  136. package/src/db/__pycache__/_skills.cpython-314.pyc +0 -0
  137. package/src/db/__pycache__/_tasks.cpython-310.pyc +0 -0
  138. package/src/db/__pycache__/_tasks.cpython-312.pyc +0 -0
  139. package/src/db/__pycache__/_tasks.cpython-314.pyc +0 -0
  140. package/src/db/_core 2.py +0 -417
  141. package/src/db/_credentials 2.py +0 -124
  142. package/src/db/_entities 2.py +0 -178
  143. package/src/db/_episodic 2.py +0 -738
  144. package/src/db/_evolution 2.py +0 -54
  145. package/src/db/_fts 2.py +0 -406
  146. package/src/db/_learnings 2.py +0 -168
  147. package/src/db/_reminders 2.py +0 -338
  148. package/src/db/_schema 2.py +0 -364
  149. package/src/db/_sessions 2.py +0 -300
  150. package/src/db/_tasks 2.py +0 -91
  151. package/src/evolution_cycle 2.py +0 -266
  152. package/src/hnsw_index 2.py +0 -254
  153. package/src/hooks/auto_capture 2.py +0 -208
  154. package/src/hooks/caffeinate-guard 2.sh +0 -8
  155. package/src/hooks/capture-session 2.sh +0 -21
  156. package/src/hooks/capture-tool-logs 2.sh +0 -127
  157. package/src/hooks/daily-briefing-check 2.sh +0 -33
  158. package/src/hooks/inbox-hook 2.sh +0 -76
  159. package/src/hooks/post-compact 2.sh +0 -148
  160. package/src/hooks/pre-compact 2.sh +0 -151
  161. package/src/hooks/session-start 2.sh +0 -268
  162. package/src/hooks/session-stop 2.sh +0 -140
  163. package/src/kg_populate 2.py +0 -290
  164. package/src/knowledge_graph 2.py +0 -257
  165. package/src/maintenance 2.py +0 -59
  166. package/src/migrate_embeddings 2.py +0 -122
  167. package/src/plugin_loader 2.py +0 -202
  168. package/src/plugins/__init__ 2.py +0 -0
  169. package/src/plugins/__pycache__/__init__ 2.cpython-310.pyc +0 -0
  170. package/src/plugins/__pycache__/__init__.cpython-310.pyc +0 -0
  171. package/src/plugins/__pycache__/__init__.cpython-314.pyc +0 -0
  172. package/src/plugins/__pycache__/adaptive_mode 2.cpython-310.pyc +0 -0
  173. package/src/plugins/__pycache__/adaptive_mode.cpython-310.pyc +0 -0
  174. package/src/plugins/__pycache__/adaptive_mode.cpython-314.pyc +0 -0
  175. package/src/plugins/__pycache__/agents 2.cpython-310.pyc +0 -0
  176. package/src/plugins/__pycache__/agents.cpython-310.pyc +0 -0
  177. package/src/plugins/__pycache__/artifact_registry 2.cpython-310.pyc +0 -0
  178. package/src/plugins/__pycache__/artifact_registry.cpython-310.pyc +0 -0
  179. package/src/plugins/__pycache__/backup 2.cpython-310.pyc +0 -0
  180. package/src/plugins/__pycache__/backup.cpython-310.pyc +0 -0
  181. package/src/plugins/__pycache__/cognitive_memory 2.cpython-310.pyc +0 -0
  182. package/src/plugins/__pycache__/cognitive_memory.cpython-310.pyc +0 -0
  183. package/src/plugins/__pycache__/core_rules 2.cpython-310.pyc +0 -0
  184. package/src/plugins/__pycache__/core_rules.cpython-310.pyc +0 -0
  185. package/src/plugins/__pycache__/cortex 2.cpython-310.pyc +0 -0
  186. package/src/plugins/__pycache__/cortex.cpython-310.pyc +0 -0
  187. package/src/plugins/__pycache__/entities 2.cpython-310.pyc +0 -0
  188. package/src/plugins/__pycache__/entities.cpython-310.pyc +0 -0
  189. package/src/plugins/__pycache__/episodic_memory 2.cpython-310.pyc +0 -0
  190. package/src/plugins/__pycache__/episodic_memory.cpython-310.pyc +0 -0
  191. package/src/plugins/__pycache__/evolution 2.cpython-310.pyc +0 -0
  192. package/src/plugins/__pycache__/evolution.cpython-310.pyc +0 -0
  193. package/src/plugins/__pycache__/guard 2.cpython-310.pyc +0 -0
  194. package/src/plugins/__pycache__/guard.cpython-310.pyc +0 -0
  195. package/src/plugins/__pycache__/knowledge_graph_tools 2.cpython-310.pyc +0 -0
  196. package/src/plugins/__pycache__/knowledge_graph_tools.cpython-310.pyc +0 -0
  197. package/src/plugins/__pycache__/preferences 2.cpython-310.pyc +0 -0
  198. package/src/plugins/__pycache__/preferences.cpython-310.pyc +0 -0
  199. package/src/plugins/__pycache__/schedule.cpython-310.pyc +0 -0
  200. package/src/plugins/__pycache__/schedule.cpython-314.pyc +0 -0
  201. package/src/plugins/__pycache__/skills.cpython-310.pyc +0 -0
  202. package/src/plugins/__pycache__/skills.cpython-314.pyc +0 -0
  203. package/src/plugins/__pycache__/update 2.cpython-310.pyc +0 -0
  204. package/src/plugins/__pycache__/update.cpython-310.pyc +0 -0
  205. package/src/plugins/adaptive_mode 2.py +0 -805
  206. package/src/plugins/agents 2.py +0 -52
  207. package/src/plugins/artifact_registry 2.py +0 -450
  208. package/src/plugins/backup 2.py +0 -104
  209. package/src/plugins/cognitive_memory 2.py +0 -564
  210. package/src/plugins/core_rules 2.py +0 -252
  211. package/src/plugins/cortex 2.py +0 -299
  212. package/src/plugins/entities 2.py +0 -67
  213. package/src/plugins/episodic_memory 2.py +0 -533
  214. package/src/plugins/evolution 2.py +0 -115
  215. package/src/plugins/guard 2.py +0 -746
  216. package/src/plugins/knowledge_graph_tools 2.py +0 -105
  217. package/src/plugins/preferences 2.py +0 -47
  218. package/src/plugins/update 2.py +0 -256
  219. package/src/requirements 2.txt +0 -12
  220. package/src/rules/__init__ 2.py +0 -0
  221. package/src/rules/core-rules 2.json +0 -331
  222. package/src/rules/migrate 2.py +0 -207
  223. package/src/scripts/__pycache__/nexo-auto-update.cpython-314.pyc +0 -0
  224. package/src/scripts/__pycache__/nexo-catchup.cpython-314.pyc +0 -0
  225. package/src/scripts/__pycache__/nexo-cognitive-decay.cpython-314.pyc +0 -0
  226. package/src/scripts/__pycache__/nexo-daily-self-audit.cpython-314.pyc +0 -0
  227. package/src/scripts/__pycache__/nexo-evolution-run.cpython-314.pyc +0 -0
  228. package/src/scripts/__pycache__/nexo-followup-hygiene.cpython-314.pyc +0 -0
  229. package/src/scripts/__pycache__/nexo-immune.cpython-314.pyc +0 -0
  230. package/src/scripts/__pycache__/nexo-install.cpython-314.pyc +0 -0
  231. package/src/scripts/__pycache__/nexo-learning-housekeep.cpython-314.pyc +0 -0
  232. package/src/scripts/__pycache__/nexo-learning-validator.cpython-314.pyc +0 -0
  233. package/src/scripts/__pycache__/nexo-migrate.cpython-314.pyc +0 -0
  234. package/src/scripts/__pycache__/nexo-postmortem-consolidator.cpython-314.pyc +0 -0
  235. package/src/scripts/__pycache__/nexo-pre-commit.cpython-314.pyc +0 -0
  236. package/src/scripts/__pycache__/nexo-proactive-dashboard.cpython-314.pyc +0 -0
  237. package/src/scripts/__pycache__/nexo-reflection.cpython-314.pyc +0 -0
  238. package/src/scripts/__pycache__/nexo-runtime-preflight.cpython-314.pyc +0 -0
  239. package/src/scripts/__pycache__/nexo-send-email.cpython-314.pyc +0 -0
  240. package/src/scripts/__pycache__/nexo-send-reply.cpython-314.pyc +0 -0
  241. package/src/scripts/__pycache__/nexo-sleep.cpython-314.pyc +0 -0
  242. package/src/scripts/__pycache__/nexo-synthesis.cpython-314.pyc +0 -0
  243. package/src/scripts/__pycache__/nexo-watchdog-smoke.cpython-314.pyc +0 -0
  244. package/src/scripts/check-context 2.py +0 -264
  245. package/src/scripts/nexo-auto-update 2.py +0 -6
  246. package/src/scripts/nexo-backup 2.sh +0 -25
  247. package/src/scripts/nexo-brain-activation 2.sh +0 -140
  248. package/src/scripts/nexo-catchup 2.py +0 -242
  249. package/src/scripts/nexo-cognitive-decay 2.py +0 -182
  250. package/src/scripts/nexo-daily-self-audit 2.py +0 -552
  251. package/src/scripts/nexo-deep-sleep 2.sh +0 -97
  252. package/src/scripts/nexo-evolution-run 2.py +0 -597
  253. package/src/scripts/nexo-followup-hygiene 2.py +0 -112
  254. package/src/scripts/nexo-github-monitor 2.py +0 -256
  255. package/src/scripts/nexo-immune 2.py +0 -927
  256. package/src/scripts/nexo-inbox-hook 2.sh +0 -74
  257. package/src/scripts/nexo-install 2.py +0 -6
  258. package/src/scripts/nexo-learning-housekeep 2.py +0 -245
  259. package/src/scripts/nexo-learning-validator 2.py +0 -207
  260. package/src/scripts/nexo-migrate 2.py +0 -232
  261. package/src/scripts/nexo-postmortem-consolidator 2.py +0 -421
  262. package/src/scripts/nexo-pre-commit 2.py +0 -120
  263. package/src/scripts/nexo-prevent-sleep 2.sh +0 -29
  264. package/src/scripts/nexo-proactive-dashboard 2.py +0 -345
  265. package/src/scripts/nexo-reflection 2.py +0 -253
  266. package/src/scripts/nexo-runtime-preflight 2.py +0 -274
  267. package/src/scripts/nexo-send-email 2.py +0 -25
  268. package/src/scripts/nexo-send-email.py +0 -25
  269. package/src/scripts/nexo-send-reply 2.py +0 -178
  270. package/src/scripts/nexo-send-reply.py +0 -178
  271. package/src/scripts/nexo-sleep 2.py +0 -592
  272. package/src/scripts/nexo-snapshot-restore 2.sh +0 -35
  273. package/src/scripts/nexo-synthesis 2.py +0 -253
  274. package/src/scripts/nexo-tcc-approve 2.sh +0 -79
  275. package/src/scripts/nexo-update 2.sh +0 -161
  276. package/src/scripts/nexo-watchdog 2.sh +0 -878
  277. package/src/scripts/nexo-watchdog-smoke 2.py +0 -119
  278. package/src/server 2.py +0 -733
  279. package/src/storage_router 2.py +0 -32
  280. package/src/tools_coordination 2.py +0 -102
  281. package/src/tools_credentials 2.py +0 -68
  282. package/src/tools_learnings 2.py +0 -220
  283. package/src/tools_menu 2.py +0 -227
  284. package/src/tools_reminders 2.py +0 -86
  285. package/src/tools_reminders_crud 2.py +0 -159
  286. package/src/tools_sessions 2.py +0 -476
  287. package/src/tools_task_history 2.py +0 -57
  288. package/templates/CLAUDE.md 2.template +0 -63
  289. package/templates/openclaw 2.json +0 -13
  290. package/tests/__init__ 2.py +0 -0
  291. package/tests/__init__.py +0 -0
  292. package/tests/conftest 2.py +0 -71
  293. package/tests/conftest.py +0 -71
  294. package/tests/test_cognitive 2.py +0 -205
  295. package/tests/test_cognitive.py +0 -205
  296. package/tests/test_knowledge_graph 2.py +0 -140
  297. package/tests/test_knowledge_graph.py +0 -140
  298. package/tests/test_migrations 2.py +0 -137
  299. package/tests/test_migrations.py +0 -137
@@ -1,813 +0,0 @@
1
- #!/usr/bin/env bash
2
- # ============================================================================
3
- # NEXO Migration: Old Layout → Unified Architecture
4
- # ============================================================================
5
- #
6
- # FROM: ~/claude/nexo-mcp/ (code + data mixed)
7
- # TO: Code → ~/Documents/_PhpstormProjects/nexo/src/
8
- # Data → ~/claude/data/ (DBs)
9
- # Plugins → ~/claude/plugins/ (personal plugins)
10
- # Backups → ~/claude/backups/ (already there)
11
- #
12
- # Usage: bash scripts/migrate-to-unified.sh [--dry-run]
13
- #
14
- # Safety: Creates full backups before any changes.
15
- # Stops on first critical error with rollback instructions.
16
- # ============================================================================
17
-
18
- set -euo pipefail
19
-
20
- # ── Colors ──────────────────────────────────────────────────────────────────
21
- RED='\033[0;31m'
22
- GREEN='\033[0;32m'
23
- YELLOW='\033[1;33m'
24
- CYAN='\033[0;36m'
25
- BOLD='\033[1m'
26
- NC='\033[0m'
27
-
28
- # ── Helpers ─────────────────────────────────────────────────────────────────
29
- info() { echo -e "${CYAN}[INFO]${NC} $*"; }
30
- ok() { echo -e "${GREEN}[OK]${NC} $*"; }
31
- warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
32
- fail() { echo -e "${RED}[FAIL]${NC} $*"; }
33
- step() { echo -e "\n${BOLD}━━━ Step $1: $2 ━━━${NC}"; }
34
- divider() { echo -e "${CYAN}────────────────────────────────────────────────────────${NC}"; }
35
-
36
- DRY_RUN=false
37
- [[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true && warn "DRY RUN — no changes will be made"
38
-
39
- TIMESTAMP=$(date +%Y%m%d-%H%M%S)
40
-
41
- # ── Paths ───────────────────────────────────────────────────────────────────
42
- NEXO_HOME="${NEXO_HOME:-$HOME/claude}"
43
- NEXO_CODE="$HOME/Documents/_PhpstormProjects/nexo"
44
- OLD_INSTALL="$NEXO_HOME/nexo-mcp"
45
- NEW_DATA="$NEXO_HOME/data"
46
- NEW_PLUGINS="$NEXO_HOME/plugins"
47
- NEW_SCRIPTS="$NEXO_HOME/scripts"
48
- BACKUP_DIR="$NEXO_HOME/backups/pre-migration-$TIMESTAMP"
49
-
50
- # Old DB locations (primary copies based on file size analysis)
51
- OLD_NEXO_DB="$OLD_INSTALL/db/nexo.db"
52
- OLD_COGNITIVE_DB="$OLD_INSTALL/cognitive.db"
53
-
54
- # New DB locations
55
- NEW_NEXO_DB="$NEW_DATA/nexo.db"
56
- NEW_COGNITIVE_DB="$NEW_DATA/cognitive.db"
57
-
58
- # Config files
59
- MCP_CONFIG="$HOME/.claude/mcp-cortex.json"
60
- CLAUDE_MD="$HOME/.claude/CLAUDE.md"
61
- PROJECT_ATLAS="$NEXO_HOME/brain/project-atlas.json"
62
-
63
- # LaunchAgents
64
- LA_DIR="$HOME/Library/LaunchAgents"
65
- LA_AUTO_CLOSE="$LA_DIR/com.nexo.auto-close-sessions.plist"
66
- LA_DASHBOARD="$LA_DIR/com.nexo.dashboard.plist"
67
-
68
- ERRORS=0
69
-
70
- run_or_dry() {
71
- if $DRY_RUN; then
72
- info "[DRY] $*"
73
- else
74
- eval "$@"
75
- fi
76
- }
77
-
78
- # ============================================================================
79
- # STEP 0: SAFETY CHECKS
80
- # ============================================================================
81
- step "0" "Safety Checks"
82
-
83
- # Check NEXO_HOME
84
- if [[ ! -d "$NEXO_HOME" ]]; then
85
- fail "NEXO_HOME ($NEXO_HOME) does not exist"
86
- exit 1
87
- fi
88
- ok "NEXO_HOME exists: $NEXO_HOME"
89
-
90
- # Check repo
91
- if [[ ! -f "$NEXO_CODE/src/server.py" ]]; then
92
- fail "Repo not found at $NEXO_CODE/src/server.py"
93
- exit 1
94
- fi
95
- ok "Repo exists: $NEXO_CODE"
96
-
97
- # Check old install
98
- if [[ ! -d "$OLD_INSTALL" ]]; then
99
- fail "Old install not found: $OLD_INSTALL"
100
- exit 1
101
- fi
102
- ok "Old install found: $OLD_INSTALL"
103
-
104
- # Check DBs exist
105
- if [[ ! -f "$OLD_NEXO_DB" ]]; then
106
- fail "nexo.db not found at $OLD_NEXO_DB"
107
- exit 1
108
- fi
109
- ok "nexo.db found ($(du -h "$OLD_NEXO_DB" | cut -f1))"
110
-
111
- if [[ ! -f "$OLD_COGNITIVE_DB" ]]; then
112
- fail "cognitive.db not found at $OLD_COGNITIVE_DB"
113
- exit 1
114
- fi
115
- ok "cognitive.db found ($(du -h "$OLD_COGNITIVE_DB" | cut -f1))"
116
-
117
- # Integrity checks
118
- info "Running SQLite integrity checks..."
119
- NEXO_INTEGRITY=$(sqlite3 "$OLD_NEXO_DB" "PRAGMA integrity_check;" 2>&1)
120
- if [[ "$NEXO_INTEGRITY" != "ok" ]]; then
121
- fail "nexo.db integrity check FAILED: $NEXO_INTEGRITY"
122
- exit 1
123
- fi
124
- ok "nexo.db integrity: OK"
125
-
126
- COG_INTEGRITY=$(sqlite3 "$OLD_COGNITIVE_DB" "PRAGMA integrity_check;" 2>&1)
127
- if [[ "$COG_INTEGRITY" != "ok" ]]; then
128
- fail "cognitive.db integrity check FAILED: $COG_INTEGRITY"
129
- exit 1
130
- fi
131
- ok "cognitive.db integrity: OK"
132
-
133
- # Check for WAL mode — need to checkpoint before copying
134
- info "Checkpointing WAL files..."
135
- sqlite3 "$OLD_NEXO_DB" "PRAGMA wal_checkpoint(TRUNCATE);" 2>/dev/null || true
136
- sqlite3 "$OLD_COGNITIVE_DB" "PRAGMA wal_checkpoint(TRUNCATE);" 2>/dev/null || true
137
- ok "WAL checkpointed"
138
-
139
- # Check MCP config
140
- if [[ ! -f "$MCP_CONFIG" ]]; then
141
- fail "MCP config not found: $MCP_CONFIG"
142
- exit 1
143
- fi
144
- ok "MCP config found"
145
-
146
- # Check LaunchAgents
147
- for plist in "$LA_AUTO_CLOSE" "$LA_DASHBOARD"; do
148
- if [[ ! -f "$plist" ]]; then
149
- warn "LaunchAgent not found: $plist (will skip)"
150
- else
151
- ok "LaunchAgent found: $(basename "$plist")"
152
- fi
153
- done
154
-
155
- # ── Confirmation ────────────────────────────────────────────────────────────
156
- divider
157
- echo -e "${BOLD}Migration Summary:${NC}"
158
- echo " Old install: $OLD_INSTALL"
159
- echo " New code: $NEXO_CODE/src/"
160
- echo " New data: $NEW_DATA/"
161
- echo " New plugins: $NEW_PLUGINS/"
162
- echo " Backup to: $BACKUP_DIR/"
163
- echo ""
164
- echo " DBs: nexo.db ($(du -h "$OLD_NEXO_DB" | cut -f1)) + cognitive.db ($(du -h "$OLD_COGNITIVE_DB" | cut -f1))"
165
- echo " Status migration: PENDIENTE→PENDING, COMPLETADO→COMPLETED, ELIMINADO→DELETED"
166
- echo ""
167
-
168
- if ! $DRY_RUN; then
169
- read -p "Proceed with migration? [y/N] " -n 1 -r
170
- echo
171
- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
172
- info "Migration cancelled."
173
- exit 0
174
- fi
175
- fi
176
-
177
- # ============================================================================
178
- # STEP 1: BACKUP EVERYTHING
179
- # ============================================================================
180
- step "1" "Backup Everything"
181
-
182
- run_or_dry "mkdir -p '$BACKUP_DIR'"
183
-
184
- # Backup DBs
185
- run_or_dry "cp '$OLD_NEXO_DB' '$BACKUP_DIR/nexo.db'"
186
- ok "Backed up nexo.db"
187
-
188
- run_or_dry "cp '$OLD_COGNITIVE_DB' '$BACKUP_DIR/cognitive.db'"
189
- ok "Backed up cognitive.db"
190
-
191
- # Backup WAL/SHM files if they exist
192
- for ext in -shm -wal; do
193
- [[ -f "${OLD_NEXO_DB}${ext}" ]] && run_or_dry "cp '${OLD_NEXO_DB}${ext}' '$BACKUP_DIR/nexo.db${ext}'"
194
- [[ -f "${OLD_COGNITIVE_DB}${ext}" ]] && run_or_dry "cp '${OLD_COGNITIVE_DB}${ext}' '$BACKUP_DIR/cognitive.db${ext}'"
195
- done
196
- ok "Backed up WAL/SHM files"
197
-
198
- # Backup MCP config
199
- run_or_dry "cp '$MCP_CONFIG' '${MCP_CONFIG}.pre-migration'"
200
- ok "Backed up mcp-cortex.json"
201
-
202
- # Backup LaunchAgents
203
- for plist in "$LA_AUTO_CLOSE" "$LA_DASHBOARD"; do
204
- if [[ -f "$plist" ]]; then
205
- run_or_dry "cp '$plist' '$BACKUP_DIR/$(basename "$plist")'"
206
- fi
207
- done
208
- ok "Backed up LaunchAgents"
209
-
210
- # Backup project-atlas.json
211
- if [[ -f "$PROJECT_ATLAS" ]]; then
212
- run_or_dry "cp '$PROJECT_ATLAS' '$BACKUP_DIR/project-atlas.json'"
213
- ok "Backed up project-atlas.json"
214
- fi
215
-
216
- # Backup CLAUDE.md
217
- run_or_dry "cp '$CLAUDE_MD' '$BACKUP_DIR/CLAUDE.md'"
218
- ok "Backed up CLAUDE.md"
219
-
220
- # Backup plugin
221
- if [[ -f "$OLD_INSTALL/plugins/email.py" ]]; then
222
- run_or_dry "cp '$OLD_INSTALL/plugins/email.py' '$BACKUP_DIR/email.py'"
223
- ok "Backed up email.py plugin"
224
- fi
225
-
226
- if ! $DRY_RUN; then
227
- info "Full backup at: $BACKUP_DIR"
228
- ls -la "$BACKUP_DIR/"
229
- fi
230
-
231
- # ============================================================================
232
- # STEP 2: CREATE DIRECTORY STRUCTURE
233
- # ============================================================================
234
- step "2" "Create Directory Structure"
235
-
236
- run_or_dry "mkdir -p '$NEW_DATA'"
237
- ok "Created $NEW_DATA/"
238
-
239
- run_or_dry "mkdir -p '$NEW_PLUGINS'"
240
- ok "Created $NEW_PLUGINS/"
241
-
242
- run_or_dry "mkdir -p '$NEW_SCRIPTS'"
243
- ok "Created $NEW_SCRIPTS/ (may already exist)"
244
-
245
- # ============================================================================
246
- # STEP 3: COPY DATA
247
- # ============================================================================
248
- step "3" "Copy Data to New Locations"
249
-
250
- # Copy nexo.db
251
- if [[ -f "$NEW_NEXO_DB" ]]; then
252
- warn "nexo.db already exists at destination — backing up existing"
253
- run_or_dry "mv '$NEW_NEXO_DB' '${NEW_NEXO_DB}.pre-migration'"
254
- fi
255
- run_or_dry "cp '$OLD_NEXO_DB' '$NEW_NEXO_DB'"
256
- ok "Copied nexo.db → $NEW_DATA/"
257
-
258
- # Copy cognitive.db
259
- if [[ -f "$NEW_COGNITIVE_DB" ]]; then
260
- warn "cognitive.db already exists at destination — backing up existing"
261
- run_or_dry "mv '$NEW_COGNITIVE_DB' '${NEW_COGNITIVE_DB}.pre-migration'"
262
- fi
263
- run_or_dry "cp '$OLD_COGNITIVE_DB' '$NEW_COGNITIVE_DB'"
264
- ok "Copied cognitive.db → $NEW_DATA/"
265
-
266
- # Copy plugin
267
- if [[ -f "$OLD_INSTALL/plugins/email.py" ]]; then
268
- run_or_dry "cp '$OLD_INSTALL/plugins/email.py' '$NEW_PLUGINS/email.py'"
269
- ok "Copied email.py → $NEW_PLUGINS/"
270
- else
271
- warn "email.py plugin not found in old install"
272
- fi
273
-
274
- # Verify copies
275
- if ! $DRY_RUN; then
276
- info "Verifying copied DBs..."
277
- V1=$(sqlite3 "$NEW_NEXO_DB" "PRAGMA integrity_check;" 2>&1)
278
- if [[ "$V1" != "ok" ]]; then
279
- fail "COPIED nexo.db failed integrity check!"
280
- fail "ROLLBACK: Delete $NEW_DATA/ and restore from $BACKUP_DIR/"
281
- exit 1
282
- fi
283
- ok "nexo.db copy verified"
284
-
285
- V2=$(sqlite3 "$NEW_COGNITIVE_DB" "PRAGMA integrity_check;" 2>&1)
286
- if [[ "$V2" != "ok" ]]; then
287
- fail "COPIED cognitive.db failed integrity check!"
288
- fail "ROLLBACK: Delete $NEW_DATA/ and restore from $BACKUP_DIR/"
289
- exit 1
290
- fi
291
- ok "cognitive.db copy verified"
292
-
293
- # Verify row counts match
294
- OLD_COUNT=$(sqlite3 "$OLD_NEXO_DB" "SELECT COUNT(*) FROM reminders;" 2>/dev/null)
295
- NEW_COUNT=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM reminders;" 2>/dev/null)
296
- if [[ "$OLD_COUNT" != "$NEW_COUNT" ]]; then
297
- fail "Row count mismatch! Old=$OLD_COUNT New=$NEW_COUNT"
298
- exit 1
299
- fi
300
- ok "Row count verified: $NEW_COUNT reminders"
301
- fi
302
-
303
- # ============================================================================
304
- # STEP 4: DB STATUS MIGRATION (Spanish → English)
305
- # ============================================================================
306
- step "4" "DB Status Migration (Spanish → English)"
307
-
308
- if ! $DRY_RUN; then
309
- info "Migrating status values in nexo.db..."
310
-
311
- # Reminders
312
- R_PEND=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM reminders WHERE status='PENDIENTE';")
313
- R_COMP=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM reminders WHERE status='COMPLETADO';")
314
- R_ELIM=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM reminders WHERE status='ELIMINADO';" 2>/dev/null || echo "0")
315
-
316
- sqlite3 "$NEW_NEXO_DB" <<'SQL'
317
- UPDATE reminders SET status = 'PENDING' WHERE status = 'PENDIENTE';
318
- UPDATE reminders SET status = 'COMPLETED' WHERE status = 'COMPLETADO';
319
- UPDATE reminders SET status = 'DELETED' WHERE status = 'ELIMINADO';
320
- SQL
321
- ok "Reminders: PENDIENTE($R_PEND)→PENDING, COMPLETADO($R_COMP)→COMPLETED, ELIMINADO($R_ELIM)→DELETED"
322
-
323
- # Followups
324
- F_PEND=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM followups WHERE status='PENDIENTE';")
325
- F_COMP=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM followups WHERE status='COMPLETADO';")
326
- F_ELIM=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM followups WHERE status='ELIMINADO';" 2>/dev/null || echo "0")
327
-
328
- sqlite3 "$NEW_NEXO_DB" <<'SQL'
329
- UPDATE followups SET status = 'PENDING' WHERE status = 'PENDIENTE';
330
- UPDATE followups SET status = 'COMPLETED' WHERE status = 'COMPLETADO';
331
- UPDATE followups SET status = 'DELETED' WHERE status = 'ELIMINADO';
332
- SQL
333
- ok "Followups: PENDIENTE($F_PEND)→PENDING, COMPLETADO($F_COMP)→COMPLETED, ELIMINADO($F_ELIM)→DELETED"
334
-
335
- # Verify no Spanish values remain
336
- REMAINING=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM reminders WHERE status IN ('PENDIENTE','COMPLETADO','ELIMINADO');")
337
- REMAINING2=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM followups WHERE status IN ('PENDIENTE','COMPLETADO','ELIMINADO');")
338
- if [[ "$REMAINING" != "0" || "$REMAINING2" != "0" ]]; then
339
- fail "Spanish status values still present! reminders=$REMAINING followups=$REMAINING2"
340
- exit 1
341
- fi
342
- ok "All status values migrated to English"
343
- else
344
- info "[DRY] Would migrate PENDIENTE→PENDING, COMPLETADO→COMPLETED, ELIMINADO→DELETED"
345
- fi
346
-
347
- # ============================================================================
348
- # STEP 5: CREATE VENV AT REPO
349
- # ============================================================================
350
- step "5" "Create Virtual Environment at Repo"
351
-
352
- VENV_DIR="$NEXO_CODE/.venv"
353
-
354
- if [[ -d "$VENV_DIR" ]]; then
355
- warn "Existing .venv found — removing to recreate"
356
- run_or_dry "rm -rf '$VENV_DIR'"
357
- fi
358
-
359
- if command -v uv &>/dev/null; then
360
- info "Using uv to create venv..."
361
- run_or_dry "cd '$NEXO_CODE' && uv venv"
362
- run_or_dry "cd '$NEXO_CODE' && uv pip install -e './src[all]' 2>/dev/null || uv pip install -e './src' 2>/dev/null || uv pip install mcp fastmcp httpx sqlite-utils 2>/dev/null"
363
- else
364
- info "uv not found, using python3 -m venv..."
365
- run_or_dry "python3 -m venv '$VENV_DIR'"
366
- run_or_dry "'$VENV_DIR/bin/pip' install --upgrade pip"
367
- # Try editable install first, fall back to requirements
368
- run_or_dry "cd '$NEXO_CODE' && '$VENV_DIR/bin/pip' install -e './src' 2>/dev/null || '$VENV_DIR/bin/pip' install mcp fastmcp httpx 2>/dev/null"
369
- fi
370
-
371
- # Verify the venv works
372
- if ! $DRY_RUN; then
373
- if [[ -f "$VENV_DIR/bin/python" ]]; then
374
- ok "venv created at $VENV_DIR"
375
- # Test import — add src to path since server.py does relative imports
376
- IMPORT_TEST=$("$VENV_DIR/bin/python" -c "
377
- import sys
378
- sys.path.insert(0, '$NEXO_CODE/src')
379
- try:
380
- from db import init_db
381
- print('OK')
382
- except Exception as e:
383
- print(f'PARTIAL: {e}')
384
- " 2>&1)
385
- if [[ "$IMPORT_TEST" == "OK" ]]; then
386
- ok "Import test passed"
387
- else
388
- warn "Import test: $IMPORT_TEST (may need manual dependency install)"
389
- fi
390
- else
391
- fail "venv creation failed!"
392
- warn "You can manually create it later: cd $NEXO_CODE && uv venv && uv pip install -e src/"
393
- ((ERRORS++))
394
- fi
395
- fi
396
-
397
- # ============================================================================
398
- # STEP 6: UPDATE MCP CONFIG
399
- # ============================================================================
400
- step "6" "Update MCP Config"
401
-
402
- if ! $DRY_RUN; then
403
- # Write new config — new python path, new server.py path, NEXO_HOME env
404
- cat > "$MCP_CONFIG" <<MCPEOF
405
- {
406
- "mcpServers": {
407
- "nexo": {
408
- "command": "$NEXO_CODE/.venv/bin/python",
409
- "args": [
410
- "$NEXO_CODE/src/server.py"
411
- ],
412
- "env": {
413
- "NEXO_HOME": "$NEXO_HOME"
414
- }
415
- }
416
- }
417
- }
418
- MCPEOF
419
- ok "Updated $MCP_CONFIG"
420
- info "New config:"
421
- cat "$MCP_CONFIG"
422
- else
423
- info "[DRY] Would update MCP config with new paths"
424
- fi
425
-
426
- # ============================================================================
427
- # STEP 7: UPDATE LAUNCHAGENTS
428
- # ============================================================================
429
- step "7" "Update LaunchAgents"
430
-
431
- # Unload current agents first
432
- for plist in "$LA_AUTO_CLOSE" "$LA_DASHBOARD"; do
433
- if [[ -f "$plist" ]]; then
434
- run_or_dry "launchctl unload '$plist' 2>/dev/null || true"
435
- fi
436
- done
437
-
438
- # Update auto-close-sessions.plist
439
- if [[ -f "$LA_AUTO_CLOSE" ]] && ! $DRY_RUN; then
440
- cat > "$LA_AUTO_CLOSE" <<'PLISTEOF'
441
- <?xml version="1.0" encoding="UTF-8"?>
442
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
443
- <plist version="1.0">
444
- <dict>
445
- <key>Label</key>
446
- <string>com.nexo.auto-close-sessions</string>
447
- <key>ProgramArguments</key>
448
- <array>
449
- PLISTEOF
450
- # Now append the dynamic paths
451
- cat >> "$LA_AUTO_CLOSE" <<PLISTEOF
452
- <string>$NEXO_CODE/.venv/bin/python</string>
453
- <string>$NEXO_CODE/src/auto_close_sessions.py</string>
454
- PLISTEOF
455
- cat >> "$LA_AUTO_CLOSE" <<'PLISTEOF'
456
- </array>
457
- <key>StartInterval</key>
458
- <integer>300</integer>
459
- <key>StandardOutPath</key>
460
- PLISTEOF
461
- cat >> "$LA_AUTO_CLOSE" <<PLISTEOF
462
- <string>$NEXO_HOME/coordination/auto-close-stdout.log</string>
463
- <key>StandardErrorPath</key>
464
- <string>$NEXO_HOME/coordination/auto-close-stderr.log</string>
465
- PLISTEOF
466
- cat >> "$LA_AUTO_CLOSE" <<'PLISTEOF'
467
- <key>RunAtLoad</key>
468
- <true/>
469
- <key>EnvironmentVariables</key>
470
- <dict>
471
- <key>PATH</key>
472
- <string>/opt/homebrew/bin:/Library/Frameworks/Python.framework/Versions/3.12/bin:/usr/local/bin:/usr/bin:/bin</string>
473
- <key>NEXO_SKIP_FS_INDEX</key>
474
- <string>1</string>
475
- PLISTEOF
476
- cat >> "$LA_AUTO_CLOSE" <<PLISTEOF
477
- <key>NEXO_HOME</key>
478
- <string>$NEXO_HOME</string>
479
- PLISTEOF
480
- cat >> "$LA_AUTO_CLOSE" <<'PLISTEOF'
481
- </dict>
482
- </dict>
483
- </plist>
484
- PLISTEOF
485
- ok "Updated com.nexo.auto-close-sessions.plist"
486
- fi
487
-
488
- # Update dashboard.plist
489
- if [[ -f "$LA_DASHBOARD" ]] && ! $DRY_RUN; then
490
- cat > "$LA_DASHBOARD" <<PLISTEOF
491
- <?xml version="1.0" encoding="UTF-8"?>
492
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
493
- <plist version="1.0">
494
- <dict>
495
- <key>Label</key>
496
- <string>com.nexo.dashboard</string>
497
- <key>ProgramArguments</key>
498
- <array>
499
- <string>$NEXO_CODE/.venv/bin/python</string>
500
- <string>-m</string>
501
- <string>dashboard.app</string>
502
- <string>--port</string>
503
- <string>6174</string>
504
- <string>--no-browser</string>
505
- </array>
506
- <key>WorkingDirectory</key>
507
- <string>$NEXO_CODE/src</string>
508
- <key>KeepAlive</key>
509
- <true/>
510
- <key>RunAtLoad</key>
511
- <true/>
512
- <key>StandardOutPath</key>
513
- <string>/tmp/nexo-dashboard.log</string>
514
- <key>StandardErrorPath</key>
515
- <string>/tmp/nexo-dashboard.err</string>
516
- <key>EnvironmentVariables</key>
517
- <dict>
518
- <key>PATH</key>
519
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
520
- <key>NEXO_HOME</key>
521
- <string>$NEXO_HOME</string>
522
- </dict>
523
- </dict>
524
- </plist>
525
- PLISTEOF
526
- ok "Updated com.nexo.dashboard.plist"
527
- fi
528
-
529
- # Reload agents
530
- for plist in "$LA_AUTO_CLOSE" "$LA_DASHBOARD"; do
531
- if [[ -f "$plist" ]]; then
532
- run_or_dry "launchctl load '$plist' 2>/dev/null || true"
533
- fi
534
- done
535
- ok "LaunchAgents reloaded"
536
-
537
- # ============================================================================
538
- # STEP 8: UPDATE BRAIN CONFIGS
539
- # ============================================================================
540
- step "8" "Update Brain Configs"
541
-
542
- # Update project-atlas.json
543
- if [[ -f "$PROJECT_ATLAS" ]] && ! $DRY_RUN; then
544
- # Use python for reliable JSON editing
545
- python3 <<PYEOF
546
- import json
547
-
548
- with open("$PROJECT_ATLAS", "r") as f:
549
- atlas = json.load(f)
550
-
551
- if "nexo" in atlas:
552
- nexo = atlas["nexo"]
553
- # Update locations
554
- if "locations" in nexo:
555
- nexo["locations"]["mcp_server"] = "$NEXO_CODE/src/"
556
- nexo["locations"]["data"] = "$NEW_DATA/"
557
- nexo["locations"]["plugins"] = "$NEW_PLUGINS/"
558
- # Keep other locations unchanged
559
- # Update database path
560
- nexo["database"] = "$NEW_DATA/nexo.db (SQLite)"
561
- nexo["deploy"] = "Local only. Code at repo, data at NEXO_HOME. MCP server restarts on save."
562
-
563
- with open("$PROJECT_ATLAS", "w") as f:
564
- json.dump(atlas, f, indent=2, ensure_ascii=False)
565
- f.write("\n")
566
-
567
- print("OK")
568
- PYEOF
569
- ok "Updated project-atlas.json"
570
- else
571
- warn "project-atlas.json not found or dry run"
572
- fi
573
-
574
- # Update CLAUDE.md — replace nexo-mcp reference in Repo Publico section
575
- if [[ -f "$CLAUDE_MD" ]] && ! $DRY_RUN; then
576
- sed -i.bak \
577
- 's|Tras cambios core en `~/claude/nexo-mcp/`:|Tras cambios core en `~/Documents/_PhpstormProjects/nexo/src/`:|' \
578
- "$CLAUDE_MD"
579
- rm -f "${CLAUDE_MD}.bak"
580
- ok "Updated CLAUDE.md (repo publico reference)"
581
- else
582
- info "[DRY] Would update CLAUDE.md"
583
- fi
584
-
585
- # ============================================================================
586
- # STEP 9: SET NEXO_HOME IN SHELL PROFILE
587
- # ============================================================================
588
- step "9" "Set Environment Variables in Shell Profile"
589
-
590
- SHELL_PROFILE=""
591
- if [[ -f "$HOME/.zshrc" ]]; then
592
- SHELL_PROFILE="$HOME/.zshrc"
593
- elif [[ -f "$HOME/.bash_profile" ]]; then
594
- SHELL_PROFILE="$HOME/.bash_profile"
595
- elif [[ -f "$HOME/.bashrc" ]]; then
596
- SHELL_PROFILE="$HOME/.bashrc"
597
- fi
598
-
599
- if [[ -n "$SHELL_PROFILE" ]]; then
600
- NEEDS_NEXO_HOME=true
601
- NEEDS_NEXO_CODE=true
602
-
603
- grep -q 'export NEXO_HOME=' "$SHELL_PROFILE" 2>/dev/null && NEEDS_NEXO_HOME=false
604
- grep -q 'export NEXO_CODE=' "$SHELL_PROFILE" 2>/dev/null && NEEDS_NEXO_CODE=false
605
-
606
- if $NEEDS_NEXO_HOME || $NEEDS_NEXO_CODE; then
607
- if ! $DRY_RUN; then
608
- echo "" >> "$SHELL_PROFILE"
609
- echo "# NEXO unified architecture (added by migrate-to-unified.sh)" >> "$SHELL_PROFILE"
610
- $NEEDS_NEXO_HOME && echo "export NEXO_HOME=~/claude" >> "$SHELL_PROFILE"
611
- $NEEDS_NEXO_CODE && echo "export NEXO_CODE=~/Documents/_PhpstormProjects/nexo/src" >> "$SHELL_PROFILE"
612
- fi
613
- ok "Added to $SHELL_PROFILE:"
614
- $NEEDS_NEXO_HOME && info " export NEXO_HOME=~/claude"
615
- $NEEDS_NEXO_CODE && info " export NEXO_CODE=~/Documents/_PhpstormProjects/nexo/src"
616
- else
617
- ok "Environment variables already set in $SHELL_PROFILE"
618
- fi
619
- else
620
- warn "No shell profile found — add manually:"
621
- echo " export NEXO_HOME=~/claude"
622
- echo " export NEXO_CODE=~/Documents/_PhpstormProjects/nexo/src"
623
- fi
624
-
625
- # ============================================================================
626
- # STEP 10: CLEANUP OLD INSTALL
627
- # ============================================================================
628
- step "10" "Cleanup Dead Files from Old Install"
629
-
630
- # Remove known dead/duplicate files that are now in the repo
631
- DEAD_FILES=(
632
- "$OLD_INSTALL/db_credentials.py"
633
- "$OLD_INSTALL/db_entities.py"
634
- "$OLD_INSTALL/db_episodic.py"
635
- "$OLD_INSTALL/db_evolution.py"
636
- "$OLD_INSTALL/db_learnings.py"
637
- "$OLD_INSTALL/db_reminders.py"
638
- "$OLD_INSTALL/db_schema.py"
639
- "$OLD_INSTALL/db_sessions.py"
640
- "$OLD_INSTALL/db_tasks.py"
641
- "$OLD_INSTALL/db.py.bak"
642
- "$OLD_INSTALL/cognitive.py.bak"
643
- "$OLD_INSTALL/nexo.db.orphan-backup"
644
- "$OLD_INSTALL/cognitive.db.bak-384dims-pre-upgrade"
645
- "$OLD_INSTALL/firebase-debug.log"
646
- "$OLD_INSTALL/test_fts.py"
647
- "$OLD_INSTALL/migrate_embeddings.py"
648
- "$OLD_INSTALL/migrate_memory.py"
649
- "$OLD_INSTALL/migrate_remaining.py"
650
- "$OLD_INSTALL/migrate.py"
651
- "$OLD_INSTALL/audit_migration.py"
652
- "$OLD_INSTALL/kg_populate.py"
653
- "$OLD_INSTALL/schema_cache.json"
654
- )
655
-
656
- CLEANED=0
657
- for f in "${DEAD_FILES[@]}"; do
658
- if [[ -f "$f" ]]; then
659
- run_or_dry "rm '$f'"
660
- ((CLEANED++))
661
- fi
662
- done
663
- ok "Removed $CLEANED dead files from old install"
664
-
665
- # Remove orphan DB copies (the 4KB stubs)
666
- if [[ -f "$OLD_INSTALL/nexo.db" ]]; then
667
- OLD_ROOT_SIZE=$(stat -f%z "$OLD_INSTALL/nexo.db" 2>/dev/null || stat -c%s "$OLD_INSTALL/nexo.db" 2>/dev/null)
668
- if [[ "$OLD_ROOT_SIZE" -le 8192 ]]; then
669
- run_or_dry "rm '$OLD_INSTALL/nexo.db' '$OLD_INSTALL/nexo.db-shm' '$OLD_INSTALL/nexo.db-wal' 2>/dev/null || true"
670
- ok "Removed orphan nexo.db stub from root"
671
- fi
672
- fi
673
-
674
- # Remove orphan cognitive.db stub in db/
675
- if [[ -f "$OLD_INSTALL/db/cognitive.db" ]]; then
676
- DB_COG_SIZE=$(stat -f%z "$OLD_INSTALL/db/cognitive.db" 2>/dev/null || stat -c%s "$OLD_INSTALL/db/cognitive.db" 2>/dev/null)
677
- if [[ "$DB_COG_SIZE" -le 8192 ]]; then
678
- run_or_dry "rm '$OLD_INSTALL/db/cognitive.db'"
679
- ok "Removed orphan cognitive.db stub from db/"
680
- fi
681
- fi
682
-
683
- # Clean __pycache__
684
- run_or_dry "find '$OLD_INSTALL' -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null || true"
685
- ok "Cleaned __pycache__ directories"
686
-
687
- warn "NOT deleting $OLD_INSTALL — verify everything works first, then:"
688
- warn " rm -rf $OLD_INSTALL"
689
-
690
- # ============================================================================
691
- # STEP 11: SMOKE TEST
692
- # ============================================================================
693
- step "11" "Smoke Test"
694
-
695
- if ! $DRY_RUN; then
696
- info "Testing MCP server can start..."
697
-
698
- # Quick test: can the new venv + new server.py import and init?
699
- SMOKE_RESULT=$("$NEXO_CODE/.venv/bin/python" -c "
700
- import sys, os
701
- os.environ['NEXO_HOME'] = '$NEXO_HOME'
702
- sys.path.insert(0, '$NEXO_CODE/src')
703
- try:
704
- from db import init_db
705
- # Test DB path resolution with NEXO_HOME
706
- print('IMPORT_OK')
707
- except Exception as e:
708
- print(f'IMPORT_FAIL: {e}')
709
- " 2>&1)
710
-
711
- if [[ "$SMOKE_RESULT" == *"IMPORT_OK"* ]]; then
712
- ok "Server import test passed"
713
- else
714
- warn "Server import test: $SMOKE_RESULT"
715
- ((ERRORS++))
716
- fi
717
-
718
- # Test DB access from new location
719
- DB_TEST=$(sqlite3 "$NEW_NEXO_DB" "SELECT COUNT(*) FROM sessions;" 2>&1)
720
- if [[ "$DB_TEST" =~ ^[0-9]+$ ]]; then
721
- ok "DB access test passed ($DB_TEST sessions)"
722
- else
723
- fail "DB access test failed: $DB_TEST"
724
- ((ERRORS++))
725
- fi
726
-
727
- # Run watchdog smoke test if it exists
728
- WATCHDOG_SMOKE="$NEXO_HOME/scripts/nexo-watchdog-smoke.py"
729
- if [[ -f "$WATCHDOG_SMOKE" ]]; then
730
- info "Running watchdog smoke test..."
731
- WATCHDOG_RESULT=$("$NEXO_CODE/.venv/bin/python" "$WATCHDOG_SMOKE" 2>&1 || true)
732
- if [[ "$WATCHDOG_RESULT" == *"PASS"* || "$WATCHDOG_RESULT" == *"OK"* || "$WATCHDOG_RESULT" == *"pass"* ]]; then
733
- ok "Watchdog smoke test passed"
734
- else
735
- warn "Watchdog smoke test output: $(echo "$WATCHDOG_RESULT" | head -5)"
736
- warn "May need NEXO_HOME-aware update to watchdog script"
737
- fi
738
- else
739
- info "Watchdog smoke test not found at $WATCHDOG_SMOKE — skipping"
740
- fi
741
- else
742
- info "[DRY] Would run smoke tests"
743
- fi
744
-
745
- # ============================================================================
746
- # STEP 12: SUMMARY
747
- # ============================================================================
748
- step "12" "Migration Summary"
749
- divider
750
-
751
- echo -e "${BOLD}What moved where:${NC}"
752
- echo " nexo.db: $OLD_NEXO_DB → $NEW_NEXO_DB"
753
- echo " cognitive.db: $OLD_COGNITIVE_DB → $NEW_COGNITIVE_DB"
754
- echo " email.py: $OLD_INSTALL/plugins/email.py → $NEW_PLUGINS/email.py"
755
- echo " MCP config: Updated to use $NEXO_CODE/.venv/bin/python + src/server.py"
756
- echo " LaunchAgents: Updated to new paths + NEXO_HOME env"
757
- echo " project-atlas: Updated nexo entry paths"
758
- echo " CLAUDE.md: Updated repo publico reference"
759
- echo " Shell profile: Added NEXO_HOME + NEXO_CODE exports"
760
- echo ""
761
-
762
- echo -e "${BOLD}DB Status Migration:${NC}"
763
- echo " PENDIENTE → PENDING"
764
- echo " COMPLETADO → COMPLETED"
765
- echo " ELIMINADO → DELETED"
766
- echo ""
767
-
768
- echo -e "${BOLD}Backup location:${NC}"
769
- echo " $BACKUP_DIR/"
770
- echo ""
771
-
772
- echo -e "${BOLD}To verify manually:${NC}"
773
- echo " 1. Open a new terminal (to pick up env vars)"
774
- echo " 2. Run: claude → check that NEXO starts and responds"
775
- echo " 3. Run: nexo_startup should work via MCP"
776
- echo " 4. Check reminders: nexo_reminders(filter='due') should show PENDING status"
777
- echo " 5. Dashboard: open http://localhost:6174"
778
- echo ""
779
-
780
- echo -e "${BOLD}If something is wrong — ROLLBACK:${NC}"
781
- echo " # 1. Restore MCP config"
782
- echo " cp ${MCP_CONFIG}.pre-migration $MCP_CONFIG"
783
- echo ""
784
- echo " # 2. Restore LaunchAgents"
785
- echo " cp $BACKUP_DIR/com.nexo.auto-close-sessions.plist $LA_AUTO_CLOSE"
786
- echo " cp $BACKUP_DIR/com.nexo.dashboard.plist $LA_DASHBOARD"
787
- echo " launchctl unload $LA_AUTO_CLOSE $LA_DASHBOARD 2>/dev/null"
788
- echo " launchctl load $LA_AUTO_CLOSE $LA_DASHBOARD"
789
- echo ""
790
- echo " # 3. Restore DBs (originals untouched in old location)"
791
- echo " # Old DBs are still at $OLD_INSTALL — nothing was deleted"
792
- echo ""
793
- echo " # 4. Restore configs"
794
- echo " cp $BACKUP_DIR/project-atlas.json $PROJECT_ATLAS"
795
- echo " cp $BACKUP_DIR/CLAUDE.md $CLAUDE_MD"
796
- echo ""
797
- echo " # 5. Remove env vars from shell profile"
798
- echo " # Edit $SHELL_PROFILE and remove the NEXO_HOME/NEXO_CODE lines"
799
- echo ""
800
-
801
- echo -e "${BOLD}Once verified, clean up old install:${NC}"
802
- echo " rm -rf $OLD_INSTALL"
803
- echo ""
804
-
805
- if [[ $ERRORS -gt 0 ]]; then
806
- warn "$ERRORS non-critical errors occurred — review above"
807
- else
808
- ok "Migration completed successfully!"
809
- fi
810
-
811
- divider
812
- echo -e "${GREEN}${BOLD}NEXO unified architecture is ready.${NC}"
813
- echo ""