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.
- package/README.md +1 -1
- package/bin/nexo-brain.js +92 -9
- package/bin/postinstall.js +22 -15
- package/package.json +7 -4
- package/src/auto_update.py +194 -5
- package/src/crons/sync.py +6 -2
- package/src/db/_core.py +1 -0
- package/src/db/_entities.py +1 -0
- package/src/db/_episodic.py +1 -0
- package/src/db/_learnings.py +1 -0
- package/src/db/_reminders.py +1 -0
- package/src/db/_schema.py +11 -1
- package/src/db/_sessions.py +1 -0
- package/src/db/_skills.py +1 -0
- package/src/hooks/capture-tool-logs.sh +23 -6
- package/src/hooks/session-start.sh +4 -3
- package/src/plugin_loader.py +1 -0
- package/src/plugins/update.py +377 -26
- package/src/scripts/deep-sleep/apply_findings.py +1 -0
- package/src/scripts/deep-sleep/collect.py +1 -0
- package/src/scripts/deep-sleep/extract.py +1 -0
- package/src/scripts/deep-sleep/synthesize.py +1 -0
- package/src/scripts/nexo-catchup.py +29 -4
- package/src/scripts/nexo-daily-self-audit.py +21 -1
- package/src/scripts/nexo-evolution-run.py +21 -1
- package/src/scripts/nexo-learning-housekeep.py +1 -0
- package/src/scripts/nexo-postmortem-consolidator.py +34 -9
- package/src/scripts/nexo-sleep.py +32 -10
- package/src/scripts/nexo-synthesis.py +29 -9
- package/src/scripts/nexo-update.sh +109 -7
- package/src/scripts/nexo-watchdog.sh +122 -58
- package/src/server.py +66 -1
- package/src/tools_coordination.py +1 -0
- package/src/tools_sessions.py +1 -0
- package/scripts/migrate-to-unified 2.sh +0 -813
- package/scripts/migrate-to-unified.sh +0 -813
- package/scripts/migrate-v1.5-to-v1.6 2.py +0 -778
- package/scripts/migrate-v1.5-to-v1.6.py +0 -778
- package/scripts/migrate-v1.7-to-v1.8 2.py +0 -214
- package/scripts/migrate-v1.7-to-v1.8.py +0 -214
- package/scripts/nexo-preflight.sh +0 -236
- package/scripts/pre-commit-check 2.sh +0 -55
- package/scripts/pre-commit-check.sh +0 -55
- package/src/__pycache__/auto_close_sessions.cpython-314.pyc +0 -0
- package/src/__pycache__/auto_update.cpython-310.pyc +0 -0
- package/src/__pycache__/hnsw_index.cpython-310.pyc +0 -0
- package/src/__pycache__/hnsw_index.cpython-314.pyc +0 -0
- package/src/__pycache__/kg_populate.cpython-310.pyc +0 -0
- package/src/__pycache__/knowledge_graph.cpython-310.pyc +0 -0
- package/src/__pycache__/plugin_loader.cpython-310.pyc +0 -0
- package/src/__pycache__/plugin_loader.cpython-314.pyc +0 -0
- package/src/__pycache__/tools_coordination.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_credentials.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_learnings.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_menu.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_reminders.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_reminders_crud.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_sessions.cpython-310.pyc +0 -0
- package/src/__pycache__/tools_task_history.cpython-310.pyc +0 -0
- package/src/auto_close_sessions 2.py +0 -159
- package/src/auto_update 2.py +0 -634
- package/src/claim_graph 2.py +0 -323
- package/src/cognitive/__init__ 2.py +0 -62
- package/src/cognitive/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_core.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_core.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_core.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_decay.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_decay.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_decay.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_ingest.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_ingest.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_ingest.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_memory.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_memory.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_memory.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_search.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_search.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_search.cpython-314.pyc +0 -0
- package/src/cognitive/__pycache__/_trust.cpython-310.pyc +0 -0
- package/src/cognitive/__pycache__/_trust.cpython-312.pyc +0 -0
- package/src/cognitive/__pycache__/_trust.cpython-314.pyc +0 -0
- package/src/cognitive/_core 2.py +0 -567
- package/src/cognitive/_decay 2.py +0 -382
- package/src/cognitive/_ingest 2.py +0 -892
- package/src/cognitive/_memory 2.py +0 -912
- package/src/cognitive/_search 2.py +0 -949
- package/src/cognitive/_trust 2.py +0 -464
- package/src/crons/__pycache__/sync.cpython-314.pyc +0 -0
- package/src/crons/manifest 2.json +0 -106
- package/src/crons/sync 2.py +0 -217
- package/src/dashboard/__init__ 2.py +0 -0
- package/src/dashboard/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/dashboard/__pycache__/app.cpython-310.pyc +0 -0
- package/src/dashboard/app 2.py +0 -789
- package/src/db/__init__ 2.py +0 -89
- package/src/db/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/db/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/db/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_core.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_core.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_core.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_credentials.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_credentials.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_credentials.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_cron_runs.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_cron_runs.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_entities.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_entities.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_entities.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_episodic.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_episodic.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_episodic.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_evolution.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_evolution.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_evolution.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_fts.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_fts.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_fts.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_learnings.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_learnings.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_learnings.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_reminders.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_reminders.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_reminders.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_schema.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_schema.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_schema.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_sessions.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_sessions.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_sessions.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_skills.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_skills.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_skills.cpython-314.pyc +0 -0
- package/src/db/__pycache__/_tasks.cpython-310.pyc +0 -0
- package/src/db/__pycache__/_tasks.cpython-312.pyc +0 -0
- package/src/db/__pycache__/_tasks.cpython-314.pyc +0 -0
- package/src/db/_core 2.py +0 -417
- package/src/db/_credentials 2.py +0 -124
- package/src/db/_entities 2.py +0 -178
- package/src/db/_episodic 2.py +0 -738
- package/src/db/_evolution 2.py +0 -54
- package/src/db/_fts 2.py +0 -406
- package/src/db/_learnings 2.py +0 -168
- package/src/db/_reminders 2.py +0 -338
- package/src/db/_schema 2.py +0 -364
- package/src/db/_sessions 2.py +0 -300
- package/src/db/_tasks 2.py +0 -91
- package/src/evolution_cycle 2.py +0 -266
- package/src/hnsw_index 2.py +0 -254
- package/src/hooks/auto_capture 2.py +0 -208
- package/src/hooks/caffeinate-guard 2.sh +0 -8
- package/src/hooks/capture-session 2.sh +0 -21
- package/src/hooks/capture-tool-logs 2.sh +0 -127
- package/src/hooks/daily-briefing-check 2.sh +0 -33
- package/src/hooks/inbox-hook 2.sh +0 -76
- package/src/hooks/post-compact 2.sh +0 -148
- package/src/hooks/pre-compact 2.sh +0 -151
- package/src/hooks/session-start 2.sh +0 -268
- package/src/hooks/session-stop 2.sh +0 -140
- package/src/kg_populate 2.py +0 -290
- package/src/knowledge_graph 2.py +0 -257
- package/src/maintenance 2.py +0 -59
- package/src/migrate_embeddings 2.py +0 -122
- package/src/plugin_loader 2.py +0 -202
- package/src/plugins/__init__ 2.py +0 -0
- package/src/plugins/__pycache__/__init__ 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/__init__.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/__init__.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/adaptive_mode 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/adaptive_mode.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/adaptive_mode.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/agents 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/agents.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/artifact_registry 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/artifact_registry.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/backup 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/backup.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/cognitive_memory 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/cognitive_memory.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/core_rules 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/core_rules.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/cortex 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/cortex.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/entities 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/entities.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/episodic_memory 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/episodic_memory.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/evolution 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/evolution.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/guard 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/guard.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/knowledge_graph_tools 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/knowledge_graph_tools.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/preferences 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/preferences.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/schedule.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/schedule.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/skills.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/skills.cpython-314.pyc +0 -0
- package/src/plugins/__pycache__/update 2.cpython-310.pyc +0 -0
- package/src/plugins/__pycache__/update.cpython-310.pyc +0 -0
- package/src/plugins/adaptive_mode 2.py +0 -805
- package/src/plugins/agents 2.py +0 -52
- package/src/plugins/artifact_registry 2.py +0 -450
- package/src/plugins/backup 2.py +0 -104
- package/src/plugins/cognitive_memory 2.py +0 -564
- package/src/plugins/core_rules 2.py +0 -252
- package/src/plugins/cortex 2.py +0 -299
- package/src/plugins/entities 2.py +0 -67
- package/src/plugins/episodic_memory 2.py +0 -533
- package/src/plugins/evolution 2.py +0 -115
- package/src/plugins/guard 2.py +0 -746
- package/src/plugins/knowledge_graph_tools 2.py +0 -105
- package/src/plugins/preferences 2.py +0 -47
- package/src/plugins/update 2.py +0 -256
- package/src/requirements 2.txt +0 -12
- package/src/rules/__init__ 2.py +0 -0
- package/src/rules/core-rules 2.json +0 -331
- package/src/rules/migrate 2.py +0 -207
- package/src/scripts/__pycache__/nexo-auto-update.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-catchup.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-cognitive-decay.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-daily-self-audit.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-evolution-run.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-followup-hygiene.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-immune.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-install.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-learning-housekeep.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-learning-validator.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-migrate.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-postmortem-consolidator.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-pre-commit.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-proactive-dashboard.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-reflection.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-runtime-preflight.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-send-email.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-send-reply.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-sleep.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-synthesis.cpython-314.pyc +0 -0
- package/src/scripts/__pycache__/nexo-watchdog-smoke.cpython-314.pyc +0 -0
- package/src/scripts/check-context 2.py +0 -264
- package/src/scripts/nexo-auto-update 2.py +0 -6
- package/src/scripts/nexo-backup 2.sh +0 -25
- package/src/scripts/nexo-brain-activation 2.sh +0 -140
- package/src/scripts/nexo-catchup 2.py +0 -242
- package/src/scripts/nexo-cognitive-decay 2.py +0 -182
- package/src/scripts/nexo-daily-self-audit 2.py +0 -552
- package/src/scripts/nexo-deep-sleep 2.sh +0 -97
- package/src/scripts/nexo-evolution-run 2.py +0 -597
- package/src/scripts/nexo-followup-hygiene 2.py +0 -112
- package/src/scripts/nexo-github-monitor 2.py +0 -256
- package/src/scripts/nexo-immune 2.py +0 -927
- package/src/scripts/nexo-inbox-hook 2.sh +0 -74
- package/src/scripts/nexo-install 2.py +0 -6
- package/src/scripts/nexo-learning-housekeep 2.py +0 -245
- package/src/scripts/nexo-learning-validator 2.py +0 -207
- package/src/scripts/nexo-migrate 2.py +0 -232
- package/src/scripts/nexo-postmortem-consolidator 2.py +0 -421
- package/src/scripts/nexo-pre-commit 2.py +0 -120
- package/src/scripts/nexo-prevent-sleep 2.sh +0 -29
- package/src/scripts/nexo-proactive-dashboard 2.py +0 -345
- package/src/scripts/nexo-reflection 2.py +0 -253
- package/src/scripts/nexo-runtime-preflight 2.py +0 -274
- package/src/scripts/nexo-send-email 2.py +0 -25
- package/src/scripts/nexo-send-email.py +0 -25
- package/src/scripts/nexo-send-reply 2.py +0 -178
- package/src/scripts/nexo-send-reply.py +0 -178
- package/src/scripts/nexo-sleep 2.py +0 -592
- package/src/scripts/nexo-snapshot-restore 2.sh +0 -35
- package/src/scripts/nexo-synthesis 2.py +0 -253
- package/src/scripts/nexo-tcc-approve 2.sh +0 -79
- package/src/scripts/nexo-update 2.sh +0 -161
- package/src/scripts/nexo-watchdog 2.sh +0 -878
- package/src/scripts/nexo-watchdog-smoke 2.py +0 -119
- package/src/server 2.py +0 -733
- package/src/storage_router 2.py +0 -32
- package/src/tools_coordination 2.py +0 -102
- package/src/tools_credentials 2.py +0 -68
- package/src/tools_learnings 2.py +0 -220
- package/src/tools_menu 2.py +0 -227
- package/src/tools_reminders 2.py +0 -86
- package/src/tools_reminders_crud 2.py +0 -159
- package/src/tools_sessions 2.py +0 -476
- package/src/tools_task_history 2.py +0 -57
- package/templates/CLAUDE.md 2.template +0 -63
- package/templates/openclaw 2.json +0 -13
- package/tests/__init__ 2.py +0 -0
- package/tests/__init__.py +0 -0
- package/tests/conftest 2.py +0 -71
- package/tests/conftest.py +0 -71
- package/tests/test_cognitive 2.py +0 -205
- package/tests/test_cognitive.py +0 -205
- package/tests/test_knowledge_graph 2.py +0 -140
- package/tests/test_knowledge_graph.py +0 -140
- package/tests/test_migrations 2.py +0 -137
- 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 ""
|