nexo-brain 2.0.0 → 2.2.0

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 (370) hide show
  1. package/README.md +143 -44
  2. package/bin/nexo-brain.js +53 -26
  3. package/package.json +15 -3
  4. package/scripts/migrate-to-unified 2.sh +813 -0
  5. package/scripts/migrate-v1.5-to-v1.6 2.py +778 -0
  6. package/scripts/migrate-v1.7-to-v1.8 2.py +214 -0
  7. package/scripts/pre-commit-check 2.sh +55 -0
  8. package/src/__pycache__/auto_update.cpython-310.pyc +0 -0
  9. package/src/__pycache__/hnsw_index.cpython-310.pyc +0 -0
  10. package/src/__pycache__/kg_populate.cpython-310.pyc +0 -0
  11. package/src/__pycache__/knowledge_graph.cpython-310.pyc +0 -0
  12. package/src/__pycache__/plugin_loader.cpython-310.pyc +0 -0
  13. package/src/__pycache__/tools_coordination.cpython-310.pyc +0 -0
  14. package/src/__pycache__/tools_credentials.cpython-310.pyc +0 -0
  15. package/src/__pycache__/tools_learnings.cpython-310.pyc +0 -0
  16. package/src/__pycache__/tools_menu.cpython-310.pyc +0 -0
  17. package/src/__pycache__/tools_reminders.cpython-310.pyc +0 -0
  18. package/src/__pycache__/tools_reminders_crud.cpython-310.pyc +0 -0
  19. package/src/__pycache__/tools_sessions.cpython-310.pyc +0 -0
  20. package/src/__pycache__/tools_task_history.cpython-310.pyc +0 -0
  21. package/src/auto_close_sessions 2.py +159 -0
  22. package/src/auto_update 2.py +634 -0
  23. package/src/claim_graph 2.py +323 -0
  24. package/src/cognitive/__init__ 2.py +62 -0
  25. package/src/cognitive/__pycache__/__init__.cpython-310.pyc +0 -0
  26. package/src/cognitive/__pycache__/_core.cpython-310.pyc +0 -0
  27. package/src/cognitive/__pycache__/_decay.cpython-310.pyc +0 -0
  28. package/src/cognitive/__pycache__/_ingest.cpython-310.pyc +0 -0
  29. package/src/cognitive/__pycache__/_memory.cpython-310.pyc +0 -0
  30. package/src/cognitive/__pycache__/_search.cpython-310.pyc +0 -0
  31. package/src/cognitive/__pycache__/_trust.cpython-310.pyc +0 -0
  32. package/src/cognitive/_core 2.py +567 -0
  33. package/src/cognitive/_decay 2.py +382 -0
  34. package/src/cognitive/_ingest 2.py +892 -0
  35. package/src/cognitive/_memory 2.py +912 -0
  36. package/src/cognitive/_search 2.py +949 -0
  37. package/src/cognitive/_trust 2.py +464 -0
  38. package/src/cognitive/_trust.py +10 -36
  39. package/src/crons/manifest 2.json +106 -0
  40. package/src/crons/manifest.json +106 -0
  41. package/src/crons/sync 2.py +217 -0
  42. package/src/crons/sync.py +217 -0
  43. package/src/dashboard/__init__ 2.py +0 -0
  44. package/src/dashboard/__pycache__/__init__.cpython-310.pyc +0 -0
  45. package/src/dashboard/__pycache__/app.cpython-310.pyc +0 -0
  46. package/src/dashboard/app 2.py +789 -0
  47. package/src/dashboard/app.py +16 -2
  48. package/src/dashboard/templates/dashboard.html +3 -2
  49. package/src/db/__init__ 2.py +89 -0
  50. package/src/db/__pycache__/__init__.cpython-310.pyc +0 -0
  51. package/src/db/__pycache__/__init__.cpython-312.pyc +0 -0
  52. package/src/db/__pycache__/__init__.cpython-314.pyc +0 -0
  53. package/src/db/__pycache__/_core.cpython-310.pyc +0 -0
  54. package/src/db/__pycache__/_core.cpython-312.pyc +0 -0
  55. package/src/db/__pycache__/_core.cpython-314.pyc +0 -0
  56. package/src/db/__pycache__/_credentials.cpython-310.pyc +0 -0
  57. package/src/db/__pycache__/_credentials.cpython-312.pyc +0 -0
  58. package/src/db/__pycache__/_credentials.cpython-314.pyc +0 -0
  59. package/src/db/__pycache__/_entities.cpython-310.pyc +0 -0
  60. package/src/db/__pycache__/_entities.cpython-312.pyc +0 -0
  61. package/src/db/__pycache__/_entities.cpython-314.pyc +0 -0
  62. package/src/db/__pycache__/_episodic.cpython-310.pyc +0 -0
  63. package/src/db/__pycache__/_episodic.cpython-312.pyc +0 -0
  64. package/src/db/__pycache__/_episodic.cpython-314.pyc +0 -0
  65. package/src/db/__pycache__/_evolution.cpython-310.pyc +0 -0
  66. package/src/db/__pycache__/_evolution.cpython-312.pyc +0 -0
  67. package/src/db/__pycache__/_evolution.cpython-314.pyc +0 -0
  68. package/src/db/__pycache__/_fts.cpython-310.pyc +0 -0
  69. package/src/db/__pycache__/_fts.cpython-312.pyc +0 -0
  70. package/src/db/__pycache__/_fts.cpython-314.pyc +0 -0
  71. package/src/db/__pycache__/_learnings.cpython-310.pyc +0 -0
  72. package/src/db/__pycache__/_learnings.cpython-312.pyc +0 -0
  73. package/src/db/__pycache__/_learnings.cpython-314.pyc +0 -0
  74. package/src/db/__pycache__/_reminders.cpython-310.pyc +0 -0
  75. package/src/db/__pycache__/_reminders.cpython-312.pyc +0 -0
  76. package/src/db/__pycache__/_reminders.cpython-314.pyc +0 -0
  77. package/src/db/__pycache__/_schema.cpython-310.pyc +0 -0
  78. package/src/db/__pycache__/_schema.cpython-312.pyc +0 -0
  79. package/src/db/__pycache__/_schema.cpython-314.pyc +0 -0
  80. package/src/db/__pycache__/_sessions.cpython-310.pyc +0 -0
  81. package/src/db/__pycache__/_sessions.cpython-312.pyc +0 -0
  82. package/src/db/__pycache__/_sessions.cpython-314.pyc +0 -0
  83. package/src/db/__pycache__/_tasks.cpython-310.pyc +0 -0
  84. package/src/db/__pycache__/_tasks.cpython-312.pyc +0 -0
  85. package/src/db/__pycache__/_tasks.cpython-314.pyc +0 -0
  86. package/src/db/_core 2.py +417 -0
  87. package/src/db/_credentials 2.py +124 -0
  88. package/src/db/_entities 2.py +178 -0
  89. package/src/db/_episodic 2.py +738 -0
  90. package/src/db/_episodic.py +1 -1
  91. package/src/db/_evolution 2.py +54 -0
  92. package/src/db/_fts 2.py +406 -0
  93. package/src/db/_learnings 2.py +168 -0
  94. package/src/db/_reminders 2.py +338 -0
  95. package/src/db/_reminders.py +9 -5
  96. package/src/db/_schema 2.py +364 -0
  97. package/src/db/_sessions 2.py +300 -0
  98. package/src/db/_tasks 2.py +91 -0
  99. package/src/evolution_cycle 2.py +266 -0
  100. package/src/hnsw_index 2.py +254 -0
  101. package/src/hooks/auto_capture 2.py +208 -0
  102. package/src/hooks/caffeinate-guard 2.sh +8 -0
  103. package/src/hooks/capture-session 2.sh +21 -0
  104. package/src/hooks/capture-session.sh +2 -0
  105. package/src/hooks/capture-tool-logs 2.sh +127 -0
  106. package/src/hooks/capture-tool-logs.sh +3 -2
  107. package/src/hooks/daily-briefing-check 2.sh +33 -0
  108. package/src/hooks/inbox-hook 2.sh +76 -0
  109. package/src/hooks/inbox-hook.sh +3 -2
  110. package/src/hooks/post-compact 2.sh +148 -0
  111. package/src/hooks/post-compact.sh +1 -1
  112. package/src/hooks/pre-compact 2.sh +151 -0
  113. package/src/hooks/pre-compact.sh +1 -1
  114. package/src/hooks/session-start 2.sh +268 -0
  115. package/src/hooks/session-start.sh +6 -3
  116. package/src/hooks/session-stop 2.sh +140 -0
  117. package/src/hooks/session-stop.sh +3 -2
  118. package/src/kg_populate 2.py +290 -0
  119. package/src/knowledge_graph 2.py +257 -0
  120. package/src/maintenance 2.py +59 -0
  121. package/src/migrate_embeddings 2.py +122 -0
  122. package/src/plugin_loader 2.py +202 -0
  123. package/src/plugins/__init__ 2.py +0 -0
  124. package/src/plugins/__pycache__/__init__ 2.cpython-310.pyc +0 -0
  125. package/src/plugins/__pycache__/__init__.cpython-310.pyc +0 -0
  126. package/src/plugins/__pycache__/adaptive_mode 2.cpython-310.pyc +0 -0
  127. package/src/plugins/__pycache__/adaptive_mode.cpython-310.pyc +0 -0
  128. package/src/plugins/__pycache__/agents 2.cpython-310.pyc +0 -0
  129. package/src/plugins/__pycache__/agents.cpython-310.pyc +0 -0
  130. package/src/plugins/__pycache__/artifact_registry 2.cpython-310.pyc +0 -0
  131. package/src/plugins/__pycache__/artifact_registry.cpython-310.pyc +0 -0
  132. package/src/plugins/__pycache__/backup 2.cpython-310.pyc +0 -0
  133. package/src/plugins/__pycache__/backup.cpython-310.pyc +0 -0
  134. package/src/plugins/__pycache__/cognitive_memory 2.cpython-310.pyc +0 -0
  135. package/src/plugins/__pycache__/cognitive_memory.cpython-310.pyc +0 -0
  136. package/src/plugins/__pycache__/core_rules 2.cpython-310.pyc +0 -0
  137. package/src/plugins/__pycache__/core_rules.cpython-310.pyc +0 -0
  138. package/src/plugins/__pycache__/cortex 2.cpython-310.pyc +0 -0
  139. package/src/plugins/__pycache__/cortex.cpython-310.pyc +0 -0
  140. package/src/plugins/__pycache__/entities 2.cpython-310.pyc +0 -0
  141. package/src/plugins/__pycache__/entities.cpython-310.pyc +0 -0
  142. package/src/plugins/__pycache__/episodic_memory 2.cpython-310.pyc +0 -0
  143. package/src/plugins/__pycache__/episodic_memory.cpython-310.pyc +0 -0
  144. package/src/plugins/__pycache__/evolution 2.cpython-310.pyc +0 -0
  145. package/src/plugins/__pycache__/evolution.cpython-310.pyc +0 -0
  146. package/src/plugins/__pycache__/guard 2.cpython-310.pyc +0 -0
  147. package/src/plugins/__pycache__/guard.cpython-310.pyc +0 -0
  148. package/src/plugins/__pycache__/knowledge_graph_tools 2.cpython-310.pyc +0 -0
  149. package/src/plugins/__pycache__/knowledge_graph_tools.cpython-310.pyc +0 -0
  150. package/src/plugins/__pycache__/preferences 2.cpython-310.pyc +0 -0
  151. package/src/plugins/__pycache__/preferences.cpython-310.pyc +0 -0
  152. package/src/plugins/__pycache__/update 2.cpython-310.pyc +0 -0
  153. package/src/plugins/__pycache__/update.cpython-310.pyc +0 -0
  154. package/src/plugins/adaptive_mode 2.py +805 -0
  155. package/src/plugins/agents 2.py +52 -0
  156. package/src/plugins/artifact_registry 2.py +450 -0
  157. package/src/plugins/backup 2.py +104 -0
  158. package/src/plugins/cognitive_memory 2.py +564 -0
  159. package/src/plugins/core_rules 2.py +252 -0
  160. package/src/plugins/core_rules.py +34 -17
  161. package/src/plugins/cortex 2.py +299 -0
  162. package/src/plugins/entities 2.py +67 -0
  163. package/src/plugins/episodic_memory 2.py +533 -0
  164. package/src/plugins/evolution 2.py +115 -0
  165. package/src/plugins/guard 2.py +746 -0
  166. package/src/plugins/knowledge_graph_tools 2.py +105 -0
  167. package/src/plugins/preferences 2.py +47 -0
  168. package/src/plugins/update 2.py +256 -0
  169. package/src/plugins/update.py +18 -0
  170. package/src/requirements 2.txt +12 -0
  171. package/src/rules/__init__ 2.py +0 -0
  172. package/src/rules/core-rules 2.json +331 -0
  173. package/src/rules/migrate 2.py +207 -0
  174. package/src/scripts/check-context 2.py +264 -0
  175. package/src/scripts/check-context.py +4 -7
  176. package/src/scripts/deep-sleep/apply_findings.py +570 -167
  177. package/src/scripts/deep-sleep/collect.py +480 -0
  178. package/src/scripts/deep-sleep/extract-prompt.md +233 -0
  179. package/src/scripts/deep-sleep/extract.py +249 -0
  180. package/src/scripts/deep-sleep/synthesize-prompt.md +197 -0
  181. package/src/scripts/deep-sleep/synthesize.py +191 -0
  182. package/src/scripts/nexo-auto-update 2.py +6 -0
  183. package/src/scripts/nexo-backup 2.sh +25 -0
  184. package/src/scripts/nexo-brain-activation 2.sh +140 -0
  185. package/src/scripts/nexo-catchup 2.py +242 -0
  186. package/src/scripts/nexo-catchup.py +5 -8
  187. package/src/scripts/nexo-cognitive-decay 2.py +182 -0
  188. package/src/scripts/nexo-daily-self-audit 2.py +552 -0
  189. package/src/scripts/nexo-daily-self-audit.py +28 -19
  190. package/src/scripts/nexo-deep-sleep 2.sh +97 -0
  191. package/src/scripts/nexo-deep-sleep.sh +31 -16
  192. package/src/scripts/nexo-evolution-run 2.py +597 -0
  193. package/src/scripts/nexo-evolution-run.py +5 -20
  194. package/src/scripts/nexo-followup-hygiene 2.py +112 -0
  195. package/src/scripts/nexo-followup-hygiene.py +4 -2
  196. package/src/scripts/nexo-github-monitor 2.py +256 -0
  197. package/src/scripts/nexo-github-monitor.py +6 -9
  198. package/src/scripts/nexo-immune 2.py +927 -0
  199. package/src/scripts/nexo-immune.py +4 -17
  200. package/src/scripts/nexo-inbox-hook 2.sh +74 -0
  201. package/src/scripts/nexo-install 2.py +6 -0
  202. package/src/scripts/nexo-learning-housekeep 2.py +245 -0
  203. package/src/scripts/nexo-learning-validator 2.py +207 -0
  204. package/src/scripts/nexo-learning-validator.py +0 -29
  205. package/src/scripts/nexo-migrate 2.py +232 -0
  206. package/src/scripts/nexo-postmortem-consolidator 2.py +421 -0
  207. package/src/scripts/nexo-postmortem-consolidator.py +9 -20
  208. package/src/scripts/nexo-pre-commit 2.py +120 -0
  209. package/src/scripts/nexo-prevent-sleep 2.sh +29 -0
  210. package/src/scripts/nexo-proactive-dashboard 2.py +345 -0
  211. package/src/scripts/nexo-proactive-dashboard.py +1 -0
  212. package/src/scripts/nexo-reflection 2.py +253 -0
  213. package/src/scripts/nexo-runtime-preflight 2.py +274 -0
  214. package/src/scripts/nexo-send-email 2.py +25 -0
  215. package/src/scripts/nexo-send-reply 2.py +178 -0
  216. package/src/scripts/nexo-sleep 2.py +592 -0
  217. package/src/scripts/nexo-sleep.py +8 -18
  218. package/src/scripts/nexo-snapshot-restore 2.sh +35 -0
  219. package/src/scripts/nexo-synthesis 2.py +253 -0
  220. package/src/scripts/nexo-synthesis.py +8 -19
  221. package/src/scripts/nexo-tcc-approve 2.sh +79 -0
  222. package/src/scripts/nexo-update 2.sh +161 -0
  223. package/src/scripts/nexo-watchdog 2.sh +878 -0
  224. package/src/scripts/nexo-watchdog-smoke 2.py +119 -0
  225. package/src/server 2.py +733 -0
  226. package/src/server.py +6 -1
  227. package/src/storage_router 2.py +32 -0
  228. package/src/tools_coordination 2.py +102 -0
  229. package/src/tools_credentials 2.py +68 -0
  230. package/src/tools_learnings 2.py +220 -0
  231. package/src/tools_menu 2.py +227 -0
  232. package/src/tools_menu.py +1 -1
  233. package/src/tools_reminders 2.py +86 -0
  234. package/src/tools_reminders_crud 2.py +159 -0
  235. package/src/tools_reminders_crud.py +7 -0
  236. package/src/tools_sessions 2.py +476 -0
  237. package/src/tools_sessions.py +67 -0
  238. package/src/tools_task_history 2.py +57 -0
  239. package/templates/CLAUDE.md 2.template +63 -0
  240. package/templates/openclaw 2.json +13 -0
  241. package/tests/__init__ 2.py +0 -0
  242. package/tests/conftest 2.py +71 -0
  243. package/tests/test_cognitive 2.py +205 -0
  244. package/tests/test_knowledge_graph 2.py +140 -0
  245. package/tests/test_migrations 2.py +137 -0
  246. package/src/__pycache__/auto_close_sessions.cpython-310.pyc +0 -0
  247. package/src/__pycache__/auto_close_sessions.cpython-314.pyc +0 -0
  248. package/src/__pycache__/auto_update.cpython-314.pyc +0 -0
  249. package/src/__pycache__/claim_graph.cpython-310.pyc +0 -0
  250. package/src/__pycache__/claim_graph.cpython-314.pyc +0 -0
  251. package/src/__pycache__/evolution_cycle.cpython-310.pyc +0 -0
  252. package/src/__pycache__/evolution_cycle.cpython-314.pyc +0 -0
  253. package/src/__pycache__/hnsw_index.cpython-314.pyc +0 -0
  254. package/src/__pycache__/kg_populate.cpython-314.pyc +0 -0
  255. package/src/__pycache__/knowledge_graph.cpython-314.pyc +0 -0
  256. package/src/__pycache__/maintenance.cpython-310.pyc +0 -0
  257. package/src/__pycache__/maintenance.cpython-314.pyc +0 -0
  258. package/src/__pycache__/migrate_embeddings.cpython-310.pyc +0 -0
  259. package/src/__pycache__/migrate_embeddings.cpython-314.pyc +0 -0
  260. package/src/__pycache__/plugin_loader.cpython-314.pyc +0 -0
  261. package/src/__pycache__/server.cpython-310.pyc +0 -0
  262. package/src/__pycache__/server.cpython-314.pyc +0 -0
  263. package/src/__pycache__/storage_router.cpython-310.pyc +0 -0
  264. package/src/__pycache__/storage_router.cpython-314.pyc +0 -0
  265. package/src/__pycache__/tools_coordination.cpython-314.pyc +0 -0
  266. package/src/__pycache__/tools_credentials.cpython-314.pyc +0 -0
  267. package/src/__pycache__/tools_learnings.cpython-314.pyc +0 -0
  268. package/src/__pycache__/tools_menu.cpython-314.pyc +0 -0
  269. package/src/__pycache__/tools_reminders.cpython-314.pyc +0 -0
  270. package/src/__pycache__/tools_reminders_crud.cpython-314.pyc +0 -0
  271. package/src/__pycache__/tools_sessions.cpython-314.pyc +0 -0
  272. package/src/__pycache__/tools_task_history.cpython-314.pyc +0 -0
  273. package/src/cognitive/__pycache__/__init__.cpython-314.pyc +0 -0
  274. package/src/cognitive/__pycache__/_core.cpython-314.pyc +0 -0
  275. package/src/cognitive/__pycache__/_decay.cpython-314.pyc +0 -0
  276. package/src/cognitive/__pycache__/_ingest.cpython-314.pyc +0 -0
  277. package/src/cognitive/__pycache__/_memory.cpython-314.pyc +0 -0
  278. package/src/cognitive/__pycache__/_search.cpython-314.pyc +0 -0
  279. package/src/cognitive/__pycache__/_trust.cpython-314.pyc +0 -0
  280. package/src/dashboard/__pycache__/__init__.cpython-314.pyc +0 -0
  281. package/src/dashboard/__pycache__/app.cpython-314.pyc +0 -0
  282. package/src/hooks/__pycache__/auto_capture.cpython-310.pyc +0 -0
  283. package/src/hooks/__pycache__/auto_capture.cpython-314.pyc +0 -0
  284. package/src/plugins/__pycache__/__init__.cpython-314.pyc +0 -0
  285. package/src/plugins/__pycache__/adaptive_mode.cpython-314.pyc +0 -0
  286. package/src/plugins/__pycache__/agents.cpython-314.pyc +0 -0
  287. package/src/plugins/__pycache__/artifact_registry.cpython-314.pyc +0 -0
  288. package/src/plugins/__pycache__/backup.cpython-314.pyc +0 -0
  289. package/src/plugins/__pycache__/cognitive_memory.cpython-314.pyc +0 -0
  290. package/src/plugins/__pycache__/core_rules.cpython-314.pyc +0 -0
  291. package/src/plugins/__pycache__/cortex.cpython-314.pyc +0 -0
  292. package/src/plugins/__pycache__/entities.cpython-314.pyc +0 -0
  293. package/src/plugins/__pycache__/episodic_memory.cpython-314.pyc +0 -0
  294. package/src/plugins/__pycache__/evolution.cpython-314.pyc +0 -0
  295. package/src/plugins/__pycache__/guard.cpython-314.pyc +0 -0
  296. package/src/plugins/__pycache__/knowledge_graph_tools.cpython-314.pyc +0 -0
  297. package/src/plugins/__pycache__/preferences.cpython-314.pyc +0 -0
  298. package/src/rules/__pycache__/__init__.cpython-310.pyc +0 -0
  299. package/src/rules/__pycache__/__init__.cpython-314.pyc +0 -0
  300. package/src/rules/__pycache__/migrate.cpython-310.pyc +0 -0
  301. package/src/rules/__pycache__/migrate.cpython-314.pyc +0 -0
  302. package/src/scripts/__pycache__/check-context.cpython-310.pyc +0 -0
  303. package/src/scripts/__pycache__/check-context.cpython-314.pyc +0 -0
  304. package/src/scripts/__pycache__/nexo-auto-update.cpython-310.pyc +0 -0
  305. package/src/scripts/__pycache__/nexo-auto-update.cpython-314.pyc +0 -0
  306. package/src/scripts/__pycache__/nexo-catchup.cpython-310.pyc +0 -0
  307. package/src/scripts/__pycache__/nexo-catchup.cpython-314.pyc +0 -0
  308. package/src/scripts/__pycache__/nexo-cognitive-decay.cpython-310.pyc +0 -0
  309. package/src/scripts/__pycache__/nexo-cognitive-decay.cpython-314.pyc +0 -0
  310. package/src/scripts/__pycache__/nexo-daily-self-audit.cpython-310.pyc +0 -0
  311. package/src/scripts/__pycache__/nexo-daily-self-audit.cpython-314.pyc +0 -0
  312. package/src/scripts/__pycache__/nexo-evolution-run.cpython-310.pyc +0 -0
  313. package/src/scripts/__pycache__/nexo-evolution-run.cpython-314.pyc +0 -0
  314. package/src/scripts/__pycache__/nexo-followup-hygiene.cpython-310.pyc +0 -0
  315. package/src/scripts/__pycache__/nexo-followup-hygiene.cpython-314.pyc +0 -0
  316. package/src/scripts/__pycache__/nexo-github-monitor.cpython-310.pyc +0 -0
  317. package/src/scripts/__pycache__/nexo-github-monitor.cpython-314.pyc +0 -0
  318. package/src/scripts/__pycache__/nexo-immune.cpython-310.pyc +0 -0
  319. package/src/scripts/__pycache__/nexo-immune.cpython-314.pyc +0 -0
  320. package/src/scripts/__pycache__/nexo-install.cpython-310.pyc +0 -0
  321. package/src/scripts/__pycache__/nexo-install.cpython-314.pyc +0 -0
  322. package/src/scripts/__pycache__/nexo-learning-housekeep.cpython-310.pyc +0 -0
  323. package/src/scripts/__pycache__/nexo-learning-housekeep.cpython-314.pyc +0 -0
  324. package/src/scripts/__pycache__/nexo-learning-validator.cpython-310.pyc +0 -0
  325. package/src/scripts/__pycache__/nexo-learning-validator.cpython-314.pyc +0 -0
  326. package/src/scripts/__pycache__/nexo-migrate.cpython-310.pyc +0 -0
  327. package/src/scripts/__pycache__/nexo-migrate.cpython-314.pyc +0 -0
  328. package/src/scripts/__pycache__/nexo-postmortem-consolidator.cpython-310.pyc +0 -0
  329. package/src/scripts/__pycache__/nexo-postmortem-consolidator.cpython-314.pyc +0 -0
  330. package/src/scripts/__pycache__/nexo-pre-commit.cpython-310.pyc +0 -0
  331. package/src/scripts/__pycache__/nexo-pre-commit.cpython-314.pyc +0 -0
  332. package/src/scripts/__pycache__/nexo-proactive-dashboard.cpython-310.pyc +0 -0
  333. package/src/scripts/__pycache__/nexo-proactive-dashboard.cpython-314.pyc +0 -0
  334. package/src/scripts/__pycache__/nexo-reflection.cpython-310.pyc +0 -0
  335. package/src/scripts/__pycache__/nexo-reflection.cpython-314.pyc +0 -0
  336. package/src/scripts/__pycache__/nexo-runtime-preflight.cpython-310.pyc +0 -0
  337. package/src/scripts/__pycache__/nexo-runtime-preflight.cpython-314.pyc +0 -0
  338. package/src/scripts/__pycache__/nexo-send-email.cpython-310.pyc +0 -0
  339. package/src/scripts/__pycache__/nexo-send-email.cpython-314.pyc +0 -0
  340. package/src/scripts/__pycache__/nexo-send-reply.cpython-310.pyc +0 -0
  341. package/src/scripts/__pycache__/nexo-send-reply.cpython-314.pyc +0 -0
  342. package/src/scripts/__pycache__/nexo-sleep.cpython-310.pyc +0 -0
  343. package/src/scripts/__pycache__/nexo-sleep.cpython-314.pyc +0 -0
  344. package/src/scripts/__pycache__/nexo-synthesis.cpython-310.pyc +0 -0
  345. package/src/scripts/__pycache__/nexo-synthesis.cpython-314.pyc +0 -0
  346. package/src/scripts/__pycache__/nexo-watchdog-smoke.cpython-310.pyc +0 -0
  347. package/src/scripts/__pycache__/nexo-watchdog-smoke.cpython-314.pyc +0 -0
  348. package/src/scripts/deep-sleep/__pycache__/analyze_session.cpython-310.pyc +0 -0
  349. package/src/scripts/deep-sleep/__pycache__/analyze_session.cpython-314.pyc +0 -0
  350. package/src/scripts/deep-sleep/__pycache__/apply_findings.cpython-310.pyc +0 -0
  351. package/src/scripts/deep-sleep/__pycache__/apply_findings.cpython-314.pyc +0 -0
  352. package/src/scripts/deep-sleep/__pycache__/collect_transcripts.cpython-310.pyc +0 -0
  353. package/src/scripts/deep-sleep/__pycache__/collect_transcripts.cpython-314.pyc +0 -0
  354. package/src/scripts/deep-sleep/analyze_session.py +0 -217
  355. package/src/scripts/deep-sleep/collect_transcripts.py +0 -145
  356. package/src/scripts/deep-sleep/prompt.md +0 -109
  357. package/tests/__pycache__/__init__.cpython-310.pyc +0 -0
  358. package/tests/__pycache__/__init__.cpython-314.pyc +0 -0
  359. package/tests/__pycache__/conftest.cpython-310-pytest-9.0.2.pyc +0 -0
  360. package/tests/__pycache__/conftest.cpython-310.pyc +0 -0
  361. package/tests/__pycache__/conftest.cpython-314-pytest-9.0.2.pyc +0 -0
  362. package/tests/__pycache__/test_cognitive.cpython-310-pytest-9.0.2.pyc +0 -0
  363. package/tests/__pycache__/test_cognitive.cpython-310.pyc +0 -0
  364. package/tests/__pycache__/test_cognitive.cpython-314-pytest-9.0.2.pyc +0 -0
  365. package/tests/__pycache__/test_knowledge_graph.cpython-310-pytest-9.0.2.pyc +0 -0
  366. package/tests/__pycache__/test_knowledge_graph.cpython-310.pyc +0 -0
  367. package/tests/__pycache__/test_knowledge_graph.cpython-314-pytest-9.0.2.pyc +0 -0
  368. package/tests/__pycache__/test_migrations.cpython-310-pytest-9.0.2.pyc +0 -0
  369. package/tests/__pycache__/test_migrations.cpython-310.pyc +0 -0
  370. package/tests/__pycache__/test_migrations.cpython-314-pytest-9.0.2.pyc +0 -0
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env python3
2
+ """Context checker for NEXO operations - prevents duplicate actions.
3
+
4
+ Mechanical checks (email sent, file exists, action done) run in Python.
5
+ When the 'smart' command is used, passes context to Claude CLI for
6
+ intelligent duplicate/conflict detection that goes beyond file checks.
7
+ """
8
+
9
+ import os
10
+ import sys
11
+ import json
12
+ import hashlib
13
+ import subprocess
14
+ from datetime import datetime
15
+ from pathlib import Path
16
+
17
+ NEXO_HOME = Path(os.environ.get("NEXO_HOME", str(Path.home() / ".nexo")))
18
+
19
+ CLAUDE_CLI = Path.home() / ".local" / "bin" / "claude"
20
+
21
+ class ContextChecker:
22
+ def __init__(self):
23
+ self.state_dir = NEXO_HOME / 'state'
24
+ self.state_dir.mkdir(exist_ok=True)
25
+
26
+ def check_email_sent(self, to_addr, subject, since_hours=72):
27
+ """Check if email was already sent to address with subject."""
28
+ sent_path = Path.home() / 'mail' / '.nexo-sent' / '.Sent' # Configure for your mail setup
29
+ if not sent_path.exists():
30
+ return False
31
+
32
+ subject_lower = subject.lower()
33
+ to_lower = to_addr.lower()
34
+ cutoff = datetime.now().timestamp() - (since_hours * 3600)
35
+ cur_dir = sent_path / 'cur'
36
+ if not cur_dir.exists():
37
+ return False
38
+
39
+ for msg_file in cur_dir.iterdir():
40
+ try:
41
+ if msg_file.stat().st_mtime < cutoff:
42
+ continue
43
+ content = msg_file.read_text(errors='ignore')
44
+ except (OSError, UnicodeDecodeError):
45
+ continue
46
+
47
+ content_lower = content.lower()
48
+ if f"to:{to_lower}" in content_lower or f"to: {to_lower}" in content_lower:
49
+ if subject_lower in content_lower:
50
+ return True
51
+ return False
52
+
53
+ def check_file_exists(self, pattern, search_dirs=None):
54
+ """Check if file matching pattern exists in common locations."""
55
+ if search_dirs is None:
56
+ search_dirs = [
57
+ '/var/www/vhosts',
58
+ str(NEXO_HOME),
59
+ '/opt'
60
+ ]
61
+
62
+ for base_dir in search_dirs:
63
+ if not os.path.exists(base_dir):
64
+ continue
65
+ matches = []
66
+ try:
67
+ for root, _, files in os.walk(base_dir):
68
+ for filename in files:
69
+ if pattern in filename:
70
+ matches.append(str(Path(root) / filename))
71
+ if len(matches) >= 5:
72
+ return matches
73
+ except OSError:
74
+ continue
75
+ return []
76
+
77
+ def check_action_done(self, action_type, identifier, ttl_days=7):
78
+ """Check if action was already performed recently."""
79
+ action_file = self.state_dir / 'actions.json'
80
+
81
+ # Load existing actions
82
+ actions = {}
83
+ if action_file.exists():
84
+ with open(action_file) as f:
85
+ actions = json.load(f)
86
+
87
+ # Create action key
88
+ key = hashlib.md5(f"{action_type}:{identifier}".encode()).hexdigest()
89
+
90
+ # Check if exists and not expired
91
+ if key in actions:
92
+ action_time = datetime.fromisoformat(actions[key]['timestamp'])
93
+ age_days = (datetime.now() - action_time).days
94
+ if age_days < ttl_days:
95
+ return True, actions[key]
96
+
97
+ return False, None
98
+
99
+ def mark_action_done(self, action_type, identifier, metadata=None):
100
+ """Mark action as completed."""
101
+ action_file = self.state_dir / 'actions.json'
102
+
103
+ # Load existing actions
104
+ actions = {}
105
+ if action_file.exists():
106
+ with open(action_file) as f:
107
+ actions = json.load(f)
108
+
109
+ # Add new action
110
+ key = hashlib.md5(f"{action_type}:{identifier}".encode()).hexdigest()
111
+ actions[key] = {
112
+ 'type': action_type,
113
+ 'identifier': identifier,
114
+ 'timestamp': datetime.now().isoformat(),
115
+ 'metadata': metadata or {}
116
+ }
117
+
118
+ # Save
119
+ with open(action_file, 'w') as f:
120
+ json.dump(actions, f, indent=2)
121
+
122
+ return key
123
+
124
+ def smart_check(action_description: str, context: str = "") -> dict:
125
+ """Use Claude CLI to intelligently check if an action would be redundant.
126
+
127
+ Goes beyond simple file/hash checks — understands intent and context
128
+ to detect semantic duplicates (e.g., "send welcome email" vs
129
+ "email onboarding message" to same person).
130
+ """
131
+ checker = ContextChecker()
132
+
133
+ # Gather mechanical context first
134
+ state_file = checker.state_dir / 'actions.json'
135
+ recent_actions = {}
136
+ if state_file.exists():
137
+ try:
138
+ all_actions = json.loads(state_file.read_text())
139
+ cutoff = datetime.now().timestamp() - (7 * 86400)
140
+ for k, v in all_actions.items():
141
+ try:
142
+ ts = datetime.fromisoformat(v['timestamp']).timestamp()
143
+ if ts > cutoff:
144
+ recent_actions[k] = v
145
+ except (ValueError, KeyError):
146
+ pass
147
+ except Exception:
148
+ pass
149
+
150
+ if not CLAUDE_CLI.exists():
151
+ return {"redundant": False, "reason": "CLI unavailable, cannot smart-check"}
152
+
153
+ prompt = f"""You are a context deduplication engine for NEXO operations.
154
+
155
+ PROPOSED ACTION:
156
+ {action_description}
157
+
158
+ ADDITIONAL CONTEXT:
159
+ {context or "None"}
160
+
161
+ RECENT ACTIONS (last 7 days):
162
+ {json.dumps(list(recent_actions.values()), indent=1, default=str)}
163
+
164
+ Respond with ONLY valid JSON (no markdown):
165
+ {{
166
+ "redundant": true/false,
167
+ "confidence": 0.0-1.0,
168
+ "reason": "<one line explanation>",
169
+ "matching_action": "<identifier of matching action if redundant, else null>"
170
+ }}
171
+
172
+ Rules:
173
+ - Same recipient + same intent within 72h = redundant
174
+ - Same file modification with same content = redundant
175
+ - Similar but different scope (e.g., different recipients) = NOT redundant
176
+ - When in doubt, say not redundant (false negatives are cheaper than false positives)"""
177
+ )
178
+ if auth_check.returncode != 0:
179
+ # CLI not authenticated, skip gracefully
180
+ return {"redundant": False, "reason": "CLI not authenticated — skipped analysis", "suggestion": "N/A"}
181
+
182
+ env = os.environ.copy()
183
+ env["NEXO_HEADLESS"] = "1" # Skip stop hook post-mortem
184
+ env.pop("CLAUDECODE", None)
185
+ env.pop("CLAUDE_CODE", None)
186
+
187
+ try:
188
+ result = subprocess.run(
189
+ [str(CLAUDE_CLI), "-p", prompt, "--model", "opus", "--output-format", "text",
190
+ "--allowedTools", "Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*"],
191
+ capture_output=True, text=True, timeout=21600, env=env
192
+ )
193
+ if result.returncode == 0:
194
+ text = result.stdout.strip()
195
+ if "```json" in text:
196
+ text = text.split("```json")[1].split("```")[0]
197
+ elif "```" in text:
198
+ text = text.split("```")[1].split("```")[0]
199
+ return json.loads(text.strip())
200
+ except Exception:
201
+ pass
202
+
203
+ return {"redundant": False, "reason": "CLI check failed, defaulting to not redundant"}
204
+
205
+
206
+ def main():
207
+ """CLI interface for context checking."""
208
+ if len(sys.argv) < 3:
209
+ print("Usage: check-context.py <command> <args>")
210
+ print("Commands:")
211
+ print(" email <to> <subject> - Check if email was sent")
212
+ print(" file <pattern> - Check if file exists")
213
+ print(" action <type> <id> - Check if action was done")
214
+ print(" smart <description> [ctx] - Intelligent duplicate check via CLI")
215
+ sys.exit(1)
216
+
217
+ checker = ContextChecker()
218
+ command = sys.argv[1]
219
+
220
+ if command == 'email':
221
+ if len(sys.argv) < 4:
222
+ print("Usage: check-context.py email <to> <subject>")
223
+ sys.exit(1)
224
+ exists = checker.check_email_sent(sys.argv[2], sys.argv[3])
225
+ print("EXISTS" if exists else "NOT_FOUND")
226
+ sys.exit(0 if not exists else 1)
227
+
228
+ elif command == 'file':
229
+ files = checker.check_file_exists(sys.argv[2])
230
+ if files:
231
+ print("\n".join(files))
232
+ sys.exit(1)
233
+ else:
234
+ print("NOT_FOUND")
235
+ sys.exit(0)
236
+
237
+ elif command == 'action':
238
+ if len(sys.argv) < 4:
239
+ print("Usage: check-context.py action <type> <id>")
240
+ sys.exit(1)
241
+ done, data = checker.check_action_done(sys.argv[2], sys.argv[3])
242
+ if done:
243
+ print(f"DONE: {data}")
244
+ sys.exit(1)
245
+ else:
246
+ print("NOT_DONE")
247
+ sys.exit(0)
248
+
249
+ elif command == 'smart':
250
+ if len(sys.argv) < 3:
251
+ print("Usage: check-context.py smart <description> [context]")
252
+ sys.exit(1)
253
+ description = sys.argv[2]
254
+ context = sys.argv[3] if len(sys.argv) > 3 else ""
255
+ result = smart_check(description, context)
256
+ print(json.dumps(result, indent=2))
257
+ sys.exit(1 if result.get("redundant") else 0)
258
+
259
+ else:
260
+ print(f"Unknown command: {command}")
261
+ sys.exit(1)
262
+
263
+ if __name__ == '__main__':
264
+ main()
@@ -174,24 +174,21 @@ Rules:
174
174
  - Same file modification with same content = redundant
175
175
  - Similar but different scope (e.g., different recipients) = NOT redundant
176
176
  - When in doubt, say not redundant (false negatives are cheaper than false positives)"""
177
-
178
- auth_check = subprocess.run(
179
- [str(CLAUDE_CLI), "-p", "Reply with exactly: ok", "--bare", "--output-format", "text", "--model", "haiku"],
180
- capture_output=True, text=True, timeout=15
181
177
  )
182
178
  if auth_check.returncode != 0:
183
179
  # CLI not authenticated, skip gracefully
184
180
  return {"redundant": False, "reason": "CLI not authenticated — skipped analysis", "suggestion": "N/A"}
185
181
 
186
182
  env = os.environ.copy()
183
+ env["NEXO_HEADLESS"] = "1" # Skip stop hook post-mortem
187
184
  env.pop("CLAUDECODE", None)
188
185
  env.pop("CLAUDE_CODE", None)
189
186
 
190
187
  try:
191
188
  result = subprocess.run(
192
- [str(CLAUDE_CLI), "-p", prompt, "--model", "opus", "--output-format", "text", "--bare",
193
- "--allowedTools", "Read,Write,Edit,Glob,Grep"],
194
- capture_output=True, text=True, timeout=60, env=env
189
+ [str(CLAUDE_CLI), "-p", prompt, "--model", "opus", "--output-format", "text",
190
+ "--allowedTools", "Read,Write,Edit,Glob,Grep,Bash,mcp__nexo__*"],
191
+ capture_output=True, text=True, timeout=21600, env=env
195
192
  )
196
193
  if result.returncode == 0:
197
194
  text = result.stdout.strip()