nexo-brain 5.3.26 → 5.3.27

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 (211) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/package.json +1 -1
  3. package/src/server.py +3 -0
  4. package/src/tools_sessions.py +6 -1
  5. package/src/dashboard/static/favicon 2.svg +0 -32
  6. package/src/dashboard/static/nexo-logo 2.png +0 -0
  7. package/src/dashboard/static/nexo-logo 2.svg +0 -40
  8. package/src/dashboard/static/style 2.css +0 -2458
  9. package/src/dashboard/templates/adaptive 2.html +0 -118
  10. package/src/dashboard/templates/artifacts 2.html +0 -133
  11. package/src/dashboard/templates/backups 2.html +0 -136
  12. package/src/dashboard/templates/base 2.html +0 -417
  13. package/src/dashboard/templates/calendar 2.html +0 -591
  14. package/src/dashboard/templates/chat 2.html +0 -356
  15. package/src/dashboard/templates/claims 2.html +0 -259
  16. package/src/dashboard/templates/cortex 2.html +0 -321
  17. package/src/dashboard/templates/credentials 2.html +0 -128
  18. package/src/dashboard/templates/crons 2.html +0 -370
  19. package/src/dashboard/templates/dashboard 2.html +0 -494
  20. package/src/dashboard/templates/dreams 2.html +0 -252
  21. package/src/dashboard/templates/email 2.html +0 -160
  22. package/src/dashboard/templates/evolution 2.html +0 -189
  23. package/src/dashboard/templates/feed 2.html +0 -249
  24. package/src/dashboard/templates/followup_health 2.html +0 -170
  25. package/src/dashboard/templates/graph 2.html +0 -201
  26. package/src/dashboard/templates/guard 2.html +0 -259
  27. package/src/dashboard/templates/inbox 2.html +0 -251
  28. package/src/dashboard/templates/memory 2.html +0 -420
  29. package/src/dashboard/templates/operations 2.html +0 -608
  30. package/src/dashboard/templates/plugins 2.html +0 -185
  31. package/src/dashboard/templates/protocol 2.html +0 -199
  32. package/src/dashboard/templates/rules 2.html +0 -246
  33. package/src/dashboard/templates/sentiment 2.html +0 -247
  34. package/src/dashboard/templates/sessions 2.html +0 -218
  35. package/src/dashboard/templates/skills 2.html +0 -329
  36. package/src/dashboard/templates/somatic 2.html +0 -73
  37. package/src/dashboard/templates/triggers 2.html +0 -133
  38. package/src/dashboard/templates/trust 2.html +0 -360
  39. package/src/db/__init__ 2.py +0 -259
  40. package/src/db/_core 2.py +0 -437
  41. package/src/db/_credentials 2.py +0 -124
  42. package/src/db/_episodic 2.py +0 -762
  43. package/src/db/_evolution 2.py +0 -54
  44. package/src/db/_fts 2.py +0 -406
  45. package/src/db/_goal_profiles 2.py +0 -376
  46. package/src/db/_hot_context 2.py +0 -660
  47. package/src/db/_outcomes 2.py +0 -800
  48. package/src/db/_personal_scripts 2.py +0 -582
  49. package/src/db/_sessions 2.py +0 -330
  50. package/src/db/_tasks 2.py +0 -91
  51. package/src/db/_watchers 2.py +0 -173
  52. package/src/doctor/formatters 2.py +0 -52
  53. package/src/doctor/models 2.py +0 -69
  54. package/src/doctor/planes 2.py +0 -87
  55. package/src/doctor/providers/__init__ 2.py +0 -1
  56. package/src/doctor/providers/deep 2.py +0 -367
  57. package/src/evolution_cycle 2.py +0 -519
  58. package/src/hooks/auto_capture 2.py +0 -208
  59. package/src/hooks/caffeinate-guard 2.sh +0 -8
  60. package/src/hooks/capture-session 2.sh +0 -21
  61. package/src/hooks/capture-tool-logs 2.sh +0 -158
  62. package/src/hooks/daily-briefing-check 2.sh +0 -33
  63. package/src/hooks/heartbeat-enforcement 2.py +0 -90
  64. package/src/hooks/heartbeat-posttool 2.sh +0 -18
  65. package/src/hooks/inbox-hook 2.sh +0 -76
  66. package/src/hooks/post-compact 2.sh +0 -152
  67. package/src/hooks/pre-compact 2.sh +0 -169
  68. package/src/hooks/protocol-guardrail 2.sh +0 -10
  69. package/src/hooks/protocol-pretool-guardrail 2.sh +0 -9
  70. package/src/hooks/session-stop 2.sh +0 -52
  71. package/src/kg_populate 2.py +0 -292
  72. package/src/maintenance 2.py +0 -53
  73. package/src/memory_backends 2.py +0 -71
  74. package/src/migrate_embeddings 2.py +0 -124
  75. package/src/nexo_sdk 2.py +0 -103
  76. package/src/observability 2.py +0 -199
  77. package/src/plugin_loader 2.py +0 -217
  78. package/src/plugins/__init__ 2.py +0 -0
  79. package/src/plugins/artifact_registry 2.py +0 -450
  80. package/src/plugins/backup 2.py +0 -127
  81. package/src/plugins/claims_tools 2.py +0 -119
  82. package/src/plugins/cognitive_memory 2.py +0 -609
  83. package/src/plugins/core_rules 2.py +0 -252
  84. package/src/plugins/cortex 2.py +0 -1155
  85. package/src/plugins/entities 2.py +0 -67
  86. package/src/plugins/episodic_memory 2.py +0 -560
  87. package/src/plugins/evolution 2.py +0 -167
  88. package/src/plugins/goal_engine 2.py +0 -142
  89. package/src/plugins/guard 2.py +0 -862
  90. package/src/plugins/impact 2.py +0 -29
  91. package/src/plugins/knowledge_graph_tools 2.py +0 -137
  92. package/src/plugins/media_memory_tools 2.py +0 -98
  93. package/src/plugins/memory_export 2.py +0 -196
  94. package/src/plugins/outcomes 2.py +0 -130
  95. package/src/plugins/personal_scripts 2.py +0 -117
  96. package/src/plugins/preferences 2.py +0 -47
  97. package/src/plugins/protocol 2.py +0 -1449
  98. package/src/plugins/simple_api 2.py +0 -106
  99. package/src/plugins/skills 2.py +0 -341
  100. package/src/plugins/state_watchers 2.py +0 -79
  101. package/src/plugins/update 2.py +0 -986
  102. package/src/plugins/user_state_tools 2.py +0 -43
  103. package/src/plugins/workflow 2.py +0 -588
  104. package/src/protocol_settings 2.py +0 -59
  105. package/src/public_contribution 2.py +0 -466
  106. package/src/public_evolution_queue 2.py +0 -241
  107. package/src/requirements 2.txt +0 -14
  108. package/src/retroactive_learnings 2.py +0 -373
  109. package/src/rules/__init__ 2.py +0 -0
  110. package/src/rules/core-rules 2.json +0 -331
  111. package/src/rules/migrate 2.py +0 -207
  112. package/src/runtime_power 2.py +0 -874
  113. package/src/script_registry 2.py +0 -1559
  114. package/src/scripts/check-context 2.py +0 -272
  115. package/src/scripts/deep-sleep/apply_findings 2.py +0 -2327
  116. package/src/scripts/deep-sleep/collect 2.py +0 -928
  117. package/src/scripts/deep-sleep/extract 2.py +0 -330
  118. package/src/scripts/deep-sleep/extract-prompt 2.md +0 -285
  119. package/src/scripts/deep-sleep/synthesize 2.py +0 -312
  120. package/src/scripts/deep-sleep/synthesize-prompt 2.md +0 -336
  121. package/src/scripts/nexo-agent-run 2.py +0 -75
  122. package/src/scripts/nexo-auto-update 2.py +0 -6
  123. package/src/scripts/nexo-backup 2.sh +0 -25
  124. package/src/scripts/nexo-brain-activation 2.sh +0 -140
  125. package/src/scripts/nexo-catchup 2.py +0 -300
  126. package/src/scripts/nexo-cognitive-decay 2.py +0 -257
  127. package/src/scripts/nexo-cortex-cycle 2.py +0 -293
  128. package/src/scripts/nexo-cron-wrapper 2.sh +0 -53
  129. package/src/scripts/nexo-daily-self-audit 2.py +0 -2161
  130. package/src/scripts/nexo-dashboard 2.sh +0 -29
  131. package/src/scripts/nexo-deep-sleep 2.sh +0 -86
  132. package/src/scripts/nexo-evolution-run 2.py +0 -1664
  133. package/src/scripts/nexo-followup-hygiene 2.py +0 -139
  134. package/src/scripts/nexo-hook-record 2.py +0 -42
  135. package/src/scripts/nexo-immune 2.py +0 -936
  136. package/src/scripts/nexo-impact-scorer 2.py +0 -117
  137. package/src/scripts/nexo-inbox-hook 2.sh +0 -74
  138. package/src/scripts/nexo-install 2.py +0 -6
  139. package/src/scripts/nexo-learning-housekeep 2.py +0 -401
  140. package/src/scripts/nexo-learning-validator 2.py +0 -266
  141. package/src/scripts/nexo-migrate 2.py +0 -260
  142. package/src/scripts/nexo-outcome-checker 2.py +0 -127
  143. package/src/scripts/nexo-postmortem-consolidator 2.py +0 -456
  144. package/src/scripts/nexo-pre-commit 2.py +0 -120
  145. package/src/scripts/nexo-prevent-sleep 2.sh +0 -35
  146. package/src/scripts/nexo-proactive-dashboard 2.py +0 -354
  147. package/src/scripts/nexo-reflection 2.py +0 -256
  148. package/src/scripts/nexo-runtime-preflight 2.py +0 -274
  149. package/src/scripts/nexo-sleep 2.py +0 -631
  150. package/src/scripts/nexo-snapshot-restore 2.sh +0 -35
  151. package/src/scripts/nexo-sync-clients 2.py +0 -16
  152. package/src/scripts/nexo-synthesis 2.py +0 -475
  153. package/src/scripts/nexo-tcc-approve 2.sh +0 -79
  154. package/src/scripts/nexo-update 2.sh +0 -306
  155. package/src/scripts/nexo-watchdog 2.sh +0 -1207
  156. package/src/scripts/nexo-watchdog-smoke 2.py +0 -119
  157. package/src/scripts/rehydrate_learnings_from_archive 2.py +0 -245
  158. package/src/server 2.py +0 -1296
  159. package/src/skills/run-nexo-audit-phase/guide 2.md +0 -43
  160. package/src/skills/run-nexo-audit-phase/skill 2.json +0 -59
  161. package/src/skills/run-nexo-core-fix-cycle/guide 2.md +0 -17
  162. package/src/skills/run-nexo-core-fix-cycle/script 2.py +0 -276
  163. package/src/skills/run-nexo-core-fix-cycle/skill 2.json +0 -58
  164. package/src/skills/run-release-final-audit/guide 2.md +0 -16
  165. package/src/skills/run-release-final-audit/script 2.py +0 -259
  166. package/src/skills/run-release-final-audit/skill 2.json +0 -77
  167. package/src/skills/run-runtime-doctor/guide 2.md +0 -12
  168. package/src/skills/run-runtime-doctor/script 2.py +0 -21
  169. package/src/skills/run-runtime-doctor/skill 2.json +0 -25
  170. package/src/skills_runtime 2.py +0 -932
  171. package/src/state_watchers_runtime 2.py +0 -475
  172. package/src/storage_router 2.py +0 -32
  173. package/src/system_catalog 2.py +0 -786
  174. package/src/tools_coordination 2.py +0 -103
  175. package/src/tools_credentials 2.py +0 -68
  176. package/src/tools_drive 2.py +0 -487
  177. package/src/tools_hot_context 2.py +0 -163
  178. package/src/tools_learnings 2.py +0 -612
  179. package/src/tools_menu 2.py +0 -229
  180. package/src/tools_reminders 2.py +0 -88
  181. package/src/tools_reminders_crud 2.py +0 -363
  182. package/src/tools_sessions 2.py +0 -1054
  183. package/src/tools_system_catalog 2.py +0 -19
  184. package/src/tools_task_history 2.py +0 -57
  185. package/src/tools_transcripts 2.py +0 -98
  186. package/src/transcript_utils 2.py +0 -412
  187. package/src/user_context 2.py +0 -46
  188. package/src/user_data_portability 2.py +0 -328
  189. package/src/user_state_model 2.py +0 -170
  190. package/templates/CLAUDE.md 2.template +0 -108
  191. package/templates/CODEX.AGENTS.md 2.template +0 -66
  192. package/templates/launchagents/README 2.md +0 -132
  193. package/templates/launchagents/com.nexo.auto-close-sessions 2.plist +0 -39
  194. package/templates/launchagents/com.nexo.catchup 2.plist +0 -39
  195. package/templates/launchagents/com.nexo.cognitive-decay 2.plist +0 -40
  196. package/templates/launchagents/com.nexo.dashboard 2.plist +0 -43
  197. package/templates/launchagents/com.nexo.deep-sleep 2.plist +0 -43
  198. package/templates/launchagents/com.nexo.evolution 2.plist +0 -44
  199. package/templates/launchagents/com.nexo.followup-hygiene 2.plist +0 -45
  200. package/templates/launchagents/com.nexo.immune 2.plist +0 -41
  201. package/templates/launchagents/com.nexo.postmortem 2.plist +0 -45
  202. package/templates/launchagents/com.nexo.self-audit 2.plist +0 -47
  203. package/templates/launchagents/com.nexo.synthesis 2.plist +0 -45
  204. package/templates/launchagents/com.nexo.watchdog 2.plist +0 -37
  205. package/templates/nexo_helper 2.py +0 -301
  206. package/templates/openclaw 2.json +0 -13
  207. package/templates/plugin-template 2.py +0 -40
  208. package/templates/script-template 2.py +0 -59
  209. package/templates/script-template 2.sh +0 -13
  210. package/templates/skill-script-template 2.py +0 -48
  211. package/templates/skill-template 2.md +0 -33
@@ -1,360 +0,0 @@
1
- {% extends "base.html" %}
2
-
3
- {% block title %}Trust Deep-Dive{% endblock %}
4
- {% block page_title %}Trust Deep-Dive{% endblock %}
5
-
6
- {% block head %}
7
- <style>
8
- .gauge-ring {
9
- transition: stroke-dashoffset 1.2s cubic-bezier(0.22, 1, 0.36, 1);
10
- }
11
- .score-value {
12
- transition: all 0.8s ease;
13
- }
14
- @keyframes pulseGlow {
15
- 0%, 100% { filter: drop-shadow(0 0 8px rgba(124, 58, 237, 0.3)); }
16
- 50% { filter: drop-shadow(0 0 20px rgba(124, 58, 237, 0.6)); }
17
- }
18
- .gauge-container {
19
- animation: pulseGlow 3s ease-in-out infinite;
20
- }
21
- .event-card {
22
- transition: all 0.2s ease;
23
- animation: slideIn 0.3s ease-out forwards;
24
- opacity: 0;
25
- }
26
- .event-card:hover {
27
- border-color: rgba(124, 58, 237, 0.3);
28
- transform: translateX(2px);
29
- }
30
- .chart-container {
31
- position: relative;
32
- }
33
- .delta-positive { color: #34d399; }
34
- .delta-negative { color: #f87171; }
35
- .delta-badge-positive { background: rgba(52, 211, 153, 0.1); border-color: rgba(52, 211, 153, 0.2); color: #34d399; }
36
- .delta-badge-negative { background: rgba(248, 113, 113, 0.1); border-color: rgba(248, 113, 113, 0.2); color: #f87171; }
37
- @keyframes slideIn {
38
- from { opacity: 0; transform: translateX(-8px); }
39
- to { opacity: 1; transform: translateX(0); }
40
- }
41
- .filter-btn.active {
42
- background: rgba(124, 58, 237, 0.2);
43
- color: #a78bfa;
44
- border-color: rgba(124, 58, 237, 0.3);
45
- }
46
- </style>
47
- {% endblock %}
48
-
49
- {% block header_actions %}
50
- <div class="flex items-center gap-1">
51
- <button class="filter-btn active text-[10px] px-2 py-1 rounded border border-slate-700 text-slate-400 hover:text-slate-200 transition-colors" data-filter="all" onclick="setFilter('all')">All</button>
52
- <button class="filter-btn text-[10px] px-2 py-1 rounded border border-slate-700 text-slate-400 hover:text-slate-200 transition-colors" data-filter="positive" onclick="setFilter('positive')">Positive</button>
53
- <button class="filter-btn text-[10px] px-2 py-1 rounded border border-slate-700 text-slate-400 hover:text-slate-200 transition-colors" data-filter="negative" onclick="setFilter('negative')">Negative</button>
54
- </div>
55
- {% endblock %}
56
-
57
- {% block content %}
58
- <!-- Gauge + Stats Row -->
59
- <div class="grid grid-cols-1 lg:grid-cols-3 gap-5 mb-6">
60
- <!-- Trust Gauge -->
61
- <div class="bg-slate-900/50 border border-slate-800/50 rounded-xl p-6 flex flex-col items-center justify-center">
62
- <div class="text-xs uppercase tracking-wider text-slate-500 font-semibold mb-4">Current Trust Score</div>
63
- <div class="gauge-container relative" style="width: 200px; height: 200px;">
64
- <svg viewBox="0 0 200 200" class="w-full h-full">
65
- <!-- Background ring -->
66
- <circle cx="100" cy="100" r="85" fill="none" stroke="rgba(51,65,85,0.3)" stroke-width="10"
67
- stroke-dasharray="534" stroke-dashoffset="0" stroke-linecap="round"
68
- transform="rotate(-90 100 100)"/>
69
- <!-- Score ring -->
70
- <circle id="gauge-ring" cx="100" cy="100" r="85" fill="none" stroke="url(#gaugeGradient)" stroke-width="10"
71
- stroke-dasharray="534" stroke-dashoffset="534" stroke-linecap="round"
72
- transform="rotate(-90 100 100)" class="gauge-ring"/>
73
- <!-- Gradient -->
74
- <defs>
75
- <linearGradient id="gaugeGradient" x1="0%" y1="0%" x2="100%" y2="100%">
76
- <stop offset="0%" stop-color="#7C3AED"/>
77
- <stop offset="50%" stop-color="#a78bfa"/>
78
- <stop offset="100%" stop-color="#34d399"/>
79
- </linearGradient>
80
- </defs>
81
- </svg>
82
- <div class="absolute inset-0 flex flex-col items-center justify-center">
83
- <span id="gauge-score" class="text-5xl font-display font-bold text-white score-value">--</span>
84
- <span class="text-xs text-slate-500 mt-1">/ 100</span>
85
- </div>
86
- </div>
87
- </div>
88
-
89
- <!-- Weekly Stats -->
90
- <div class="bg-slate-900/50 border border-slate-800/50 rounded-xl p-5 flex flex-col justify-center">
91
- <div class="text-xs uppercase tracking-wider text-slate-500 font-semibold mb-4">This Week</div>
92
- <div class="space-y-4">
93
- <div>
94
- <div class="flex items-center justify-between mb-1">
95
- <span class="text-xs text-slate-400">Average Score</span>
96
- <span class="text-sm font-mono font-semibold text-slate-200" id="stat-avg">--</span>
97
- </div>
98
- <div class="h-1 bg-slate-800 rounded-full overflow-hidden">
99
- <div class="h-full bg-violet-500 rounded-full transition-all duration-700" id="stat-avg-bar" style="width:0%"></div>
100
- </div>
101
- </div>
102
- <div class="flex items-center justify-between">
103
- <span class="text-xs text-slate-400">Biggest Gain</span>
104
- <span class="text-sm font-mono font-semibold delta-positive" id="stat-gain">--</span>
105
- </div>
106
- <div class="flex items-center justify-between">
107
- <span class="text-xs text-slate-400">Biggest Drop</span>
108
- <span class="text-sm font-mono font-semibold delta-negative" id="stat-drop">--</span>
109
- </div>
110
- <div class="flex items-center justify-between">
111
- <span class="text-xs text-slate-400">Total Events</span>
112
- <span class="text-sm font-mono font-semibold text-slate-200" id="stat-events">--</span>
113
- </div>
114
- </div>
115
- </div>
116
-
117
- <!-- Score History Chart -->
118
- <div class="bg-slate-900/50 border border-slate-800/50 rounded-xl p-5">
119
- <div class="text-xs uppercase tracking-wider text-slate-500 font-semibold mb-3">Score History</div>
120
- <div class="chart-container" style="height: 180px;">
121
- <canvas id="history-chart" width="400" height="180"></canvas>
122
- </div>
123
- </div>
124
- </div>
125
-
126
- <!-- Event Timeline -->
127
- <div>
128
- <h2 class="text-xs uppercase tracking-wider text-slate-500 font-semibold mb-3 flex items-center gap-2">
129
- <svg class="w-4 h-4 text-violet-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
130
- Trust Events
131
- <span class="text-slate-600 font-mono" id="event-count"></span>
132
- </h2>
133
- <div class="space-y-2" id="event-timeline">
134
- <div class="text-xs text-slate-600 text-center py-8">Loading trust events...</div>
135
- </div>
136
- </div>
137
- {% endblock %}
138
-
139
- {% block scripts %}
140
- <script>
141
- const REFRESH_MS = 60000;
142
- let allEvents = [];
143
- let currentFilter = 'all';
144
-
145
- function setFilter(filter) {
146
- currentFilter = filter;
147
- document.querySelectorAll('.filter-btn').forEach(b => {
148
- b.classList.toggle('active', b.dataset.filter === filter);
149
- });
150
- renderEvents();
151
- }
152
-
153
- function updateGauge(score) {
154
- const ring = document.getElementById('gauge-ring');
155
- const scoreEl = document.getElementById('gauge-score');
156
- const circumference = 534; // 2 * PI * 85
157
- const offset = circumference - (score / 100) * circumference;
158
- ring.style.strokeDashoffset = offset;
159
- scoreEl.textContent = Math.round(score);
160
- }
161
-
162
- function drawChart(history) {
163
- const canvas = document.getElementById('history-chart');
164
- const ctx = canvas.getContext('2d');
165
- const dpr = window.devicePixelRatio || 1;
166
- const rect = canvas.getBoundingClientRect();
167
- canvas.width = rect.width * dpr;
168
- canvas.height = rect.height * dpr;
169
- ctx.scale(dpr, dpr);
170
- const w = rect.width;
171
- const h = rect.height;
172
-
173
- ctx.clearRect(0, 0, w, h);
174
-
175
- if (!history || history.length < 2) {
176
- ctx.fillStyle = '#475569';
177
- ctx.font = '12px "Space Grotesk"';
178
- ctx.textAlign = 'center';
179
- ctx.fillText('Not enough data for chart', w / 2, h / 2);
180
- return;
181
- }
182
-
183
- const scores = history.map(h => h.score);
184
- const minScore = Math.max(0, Math.min(...scores) - 5);
185
- const maxScore = Math.min(100, Math.max(...scores) + 5);
186
- const range = maxScore - minScore || 1;
187
-
188
- const padX = 10, padY = 15;
189
- const chartW = w - padX * 2;
190
- const chartH = h - padY * 2;
191
-
192
- // Grid lines
193
- ctx.strokeStyle = 'rgba(51, 65, 85, 0.3)';
194
- ctx.lineWidth = 1;
195
- for (let i = 0; i <= 4; i++) {
196
- const y = padY + (chartH / 4) * i;
197
- ctx.beginPath();
198
- ctx.moveTo(padX, y);
199
- ctx.lineTo(w - padX, y);
200
- ctx.stroke();
201
- }
202
-
203
- // Gradient fill
204
- const gradient = ctx.createLinearGradient(0, padY, 0, h - padY);
205
- gradient.addColorStop(0, 'rgba(124, 58, 237, 0.15)');
206
- gradient.addColorStop(1, 'rgba(124, 58, 237, 0)');
207
-
208
- // Line path
209
- const points = history.map((item, i) => ({
210
- x: padX + (i / (history.length - 1)) * chartW,
211
- y: padY + chartH - ((item.score - minScore) / range) * chartH
212
- }));
213
-
214
- // Fill area
215
- ctx.beginPath();
216
- ctx.moveTo(points[0].x, h - padY);
217
- points.forEach(p => ctx.lineTo(p.x, p.y));
218
- ctx.lineTo(points[points.length - 1].x, h - padY);
219
- ctx.closePath();
220
- ctx.fillStyle = gradient;
221
- ctx.fill();
222
-
223
- // Line
224
- ctx.beginPath();
225
- ctx.moveTo(points[0].x, points[0].y);
226
- for (let i = 1; i < points.length; i++) {
227
- const prev = points[i - 1];
228
- const curr = points[i];
229
- const cpx = (prev.x + curr.x) / 2;
230
- ctx.bezierCurveTo(cpx, prev.y, cpx, curr.y, curr.x, curr.y);
231
- }
232
- ctx.strokeStyle = '#7C3AED';
233
- ctx.lineWidth = 2;
234
- ctx.stroke();
235
-
236
- // Dots
237
- points.forEach((p, i) => {
238
- if (i === points.length - 1 || history.length <= 20 || i % Math.ceil(history.length / 15) === 0) {
239
- ctx.beginPath();
240
- ctx.arc(p.x, p.y, 3, 0, Math.PI * 2);
241
- ctx.fillStyle = '#7C3AED';
242
- ctx.fill();
243
- ctx.strokeStyle = '#030712';
244
- ctx.lineWidth = 1.5;
245
- ctx.stroke();
246
- }
247
- });
248
-
249
- // Last point highlight
250
- const last = points[points.length - 1];
251
- ctx.beginPath();
252
- ctx.arc(last.x, last.y, 5, 0, Math.PI * 2);
253
- ctx.fillStyle = '#a78bfa';
254
- ctx.fill();
255
- ctx.strokeStyle = '#030712';
256
- ctx.lineWidth = 2;
257
- ctx.stroke();
258
- }
259
-
260
- function renderEvents() {
261
- const container = document.getElementById('event-timeline');
262
- const countEl = document.getElementById('event-count');
263
-
264
- let filtered = allEvents;
265
- if (currentFilter === 'positive') filtered = allEvents.filter(e => (e.delta || 0) > 0);
266
- else if (currentFilter === 'negative') filtered = allEvents.filter(e => (e.delta || 0) < 0);
267
-
268
- countEl.textContent = `(${filtered.length})`;
269
-
270
- if (filtered.length === 0) {
271
- container.innerHTML = '<div class="text-xs text-slate-600 text-center py-8">No events match filter</div>';
272
- return;
273
- }
274
-
275
- container.innerHTML = filtered.slice(0, 50).map((e, idx) => {
276
- const delta = e.delta || 0;
277
- const isPositive = delta >= 0;
278
- const deltaStr = (isPositive ? '+' : '') + delta.toFixed(2);
279
- const badgeClass = isPositive ? 'delta-badge-positive' : 'delta-badge-negative';
280
- const event = e.event || e.description || 'Trust event';
281
- const context = e.context || '';
282
- const when = e.created_at ? relativeTime(e.created_at) : '';
283
- const score = e.score != null ? e.score.toFixed(1) : '';
284
- const delay = Math.min(idx * 0.05, 1);
285
-
286
- return `<div class="event-card flex items-start gap-3 bg-slate-900/50 border border-slate-800/50 rounded-xl p-4" style="animation-delay:${delay}s">
287
- <div class="flex-shrink-0 mt-0.5">
288
- <span class="inline-flex items-center justify-center w-8 h-8 rounded-lg border text-xs font-mono font-bold ${badgeClass}">
289
- ${deltaStr}
290
- </span>
291
- </div>
292
- <div class="flex-1 min-w-0">
293
- <div class="flex items-center gap-2 mb-1">
294
- <span class="text-sm text-slate-200 font-medium">${escapeHtml(event)}</span>
295
- ${score ? `<span class="text-[10px] font-mono text-slate-500 ml-auto flex-shrink-0">${score}</span>` : ''}
296
- </div>
297
- ${context ? `<p class="text-xs text-slate-500 leading-relaxed">${escapeHtml(context)}</p>` : ''}
298
- <span class="text-[10px] text-slate-600 font-mono mt-1 inline-block">${escapeHtml(when)}</span>
299
- </div>
300
- </div>`;
301
- }).join('');
302
- }
303
-
304
- async function loadTrust() {
305
- const [trustData, eventsData] = await Promise.all([
306
- fetchJSON('/api/trust'),
307
- fetchJSON('/api/trust/events?limit=50')
308
- ]);
309
-
310
- if (trustData) {
311
- const score = trustData.current_score != null ? trustData.current_score : 0;
312
- updateGauge(score);
313
-
314
- const history = trustData.history || [];
315
- drawChart(history);
316
-
317
- // Weekly stats
318
- const now = new Date();
319
- const weekAgo = new Date(now - 7 * 86400000);
320
- const weekEvents = history.filter(h => new Date(h.created_at) >= weekAgo);
321
- const weekScores = weekEvents.map(h => h.score).filter(s => s != null);
322
- const weekDeltas = weekEvents.map(h => h.delta).filter(d => d != null);
323
-
324
- if (weekScores.length > 0) {
325
- const avg = weekScores.reduce((a, b) => a + b, 0) / weekScores.length;
326
- document.getElementById('stat-avg').textContent = avg.toFixed(1);
327
- document.getElementById('stat-avg-bar').style.width = avg + '%';
328
- }
329
-
330
- if (weekDeltas.length > 0) {
331
- const maxGain = Math.max(...weekDeltas);
332
- const maxDrop = Math.min(...weekDeltas);
333
- document.getElementById('stat-gain').textContent = maxGain > 0 ? '+' + maxGain.toFixed(2) : '0';
334
- document.getElementById('stat-drop').textContent = maxDrop < 0 ? maxDrop.toFixed(2) : '0';
335
- }
336
-
337
- document.getElementById('stat-events').textContent = formatNumber(history.length);
338
- }
339
-
340
- if (eventsData) {
341
- allEvents = eventsData.events || eventsData || [];
342
- renderEvents();
343
- }
344
- }
345
-
346
- // Handle resize for chart
347
- let resizeTimer;
348
- window.addEventListener('resize', () => {
349
- clearTimeout(resizeTimer);
350
- resizeTimer = setTimeout(() => {
351
- // Re-fetch to redraw chart
352
- loadTrust();
353
- }, 250);
354
- });
355
-
356
- // Init
357
- loadTrust();
358
- setInterval(loadTrust, REFRESH_MS);
359
- </script>
360
- {% endblock %}
@@ -1,259 +0,0 @@
1
- """NEXO DB — Modular SQLite database layer.
2
-
3
- This package replaces the monolithic db.py. All public functions are
4
- re-exported here for full backwards compatibility:
5
- from db import get_db, create_learning, ...
6
-
7
- Important:
8
- `importlib.reload(db)` must also refresh the concrete submodules. The test
9
- suite and several runtime repair flows rely on switching database paths or
10
- runtime roots mid-process. If the package only re-exported functions from
11
- already-imported submodules, those callables would keep pointing at stale
12
- module state (especially old `db._core` connection globals).
13
- """
14
-
15
- from __future__ import annotations
16
-
17
- import importlib
18
- import sys
19
-
20
-
21
- def _load_submodule(name: str):
22
- """Import or reload a db submodule and expose it on the package."""
23
- module = sys.modules.get(name)
24
- if module is None:
25
- return importlib.import_module(name)
26
- return importlib.reload(module)
27
-
28
-
29
- def _module(name: str):
30
- module = sys.modules.get(name)
31
- if module is None:
32
- module = importlib.import_module(name)
33
- return module
34
-
35
-
36
- _core = _load_submodule("db._core")
37
- _fts = _load_submodule("db._fts")
38
- _schema = _load_submodule("db._schema")
39
- _sessions = _load_submodule("db._sessions")
40
- _reminders = _load_submodule("db._reminders")
41
- _learnings = _load_submodule("db._learnings")
42
- _credentials = _load_submodule("db._credentials")
43
- _tasks = _load_submodule("db._tasks")
44
- _entities = _load_submodule("db._entities")
45
- _episodic = _load_submodule("db._episodic")
46
- _evolution = _load_submodule("db._evolution")
47
- _cron_runs = _load_submodule("db._cron_runs")
48
- _protocol = _load_submodule("db._protocol")
49
- _workflow = _load_submodule("db._workflow")
50
- _watchers = _load_submodule("db._watchers")
51
- _personal_scripts = _load_submodule("db._personal_scripts")
52
- _skills = _load_submodule("db._skills")
53
- _hot_context = _load_submodule("db._hot_context")
54
- _drive = _load_submodule("db._drive")
55
- _outcomes = _load_submodule("db._outcomes")
56
- _goal_profiles = _load_submodule("db._goal_profiles")
57
-
58
- # Core: connection, constants, init, utils
59
- from db._core import (
60
- DB_PATH, SESSION_STALE_SECONDS, MESSAGE_TTL_SECONDS, QUESTION_TTL_SECONDS,
61
- get_db, close_db, _get_raw_conn, _SerializedConnection,
62
- _shared_conn, _write_lock,
63
- init_db, _gen_id, now_epoch, local_time_str, _multi_word_like,
64
- )
65
-
66
- # FTS5 search
67
- from db._fts import (
68
- fts_add_dir, fts_remove_dir, fts_list_dirs,
69
- rebuild_fts_index, fts_search, fts_upsert,
70
- )
71
-
72
- # Schema migrations
73
- from db._schema import (
74
- run_migrations, get_schema_version,
75
- )
76
-
77
- # Sessions, file tracking, messages, questions
78
- from db._sessions import (
79
- register_session, update_session, complete_session,
80
- get_active_sessions, clean_stale_sessions, search_sessions,
81
- track_files, untrack_files, get_all_tracked_files,
82
- send_message, get_inbox,
83
- ask_question, answer_question, get_pending_questions, check_answer,
84
- )
85
-
86
- # Reminders and followups
87
- from db._reminders import (
88
- create_reminder, update_reminder, complete_reminder, delete_reminder,
89
- restore_reminder, add_reminder_note, get_reminders, get_reminder, get_reminder_history,
90
- create_followup, update_followup, complete_followup, delete_followup,
91
- restore_followup, add_followup_note, get_followups, get_followup, get_followup_history,
92
- find_similar_followups,
93
- compute_followup_impact, score_followup, score_active_followups,
94
- add_item_history, get_item_history, validate_item_read_token,
95
- )
96
-
97
- # Learnings
98
- from db._learnings import (
99
- create_learning, update_learning, supersede_learning, delete_learning,
100
- search_learnings, list_learnings,
101
- extract_keywords, find_similar_learnings,
102
- )
103
-
104
- # Credentials
105
- from db._credentials import (
106
- create_credential, update_credential, delete_credential,
107
- get_credential, list_credentials,
108
- )
109
-
110
- # Task history
111
- from db._tasks import (
112
- log_task, list_task_history, set_task_frequency,
113
- get_overdue_tasks, get_task_frequencies,
114
- )
115
-
116
- # Entities, preferences, agents
117
- from db._entities import (
118
- create_entity, search_entities, list_entities, update_entity, delete_entity,
119
- set_preference, get_preference, list_preferences, delete_preference,
120
- create_agent, get_agent, list_agents, update_agent, delete_agent,
121
- )
122
-
123
- # Episodic memory
124
- from db._episodic import (
125
- cleanup_old_changes, log_change, search_changes, update_change_commit, auto_resolve_followups,
126
- cleanup_old_decisions, log_decision, update_decision_outcome,
127
- get_memory_review_queue, find_decisions_by_context_ref, search_decisions,
128
- cleanup_old_diaries, write_session_diary,
129
- diary_archive_search, diary_archive_read, diary_archive_stats,
130
- check_session_has_diary,
131
- upsert_diary_draft, get_diary_draft, delete_diary_draft,
132
- save_checkpoint, read_checkpoint, increment_compaction_count,
133
- get_orphan_sessions, read_session_diary,
134
- recall,
135
- )
136
-
137
- # Evolution
138
- from db._evolution import (
139
- insert_evolution_metric, get_latest_metrics,
140
- insert_evolution_log, get_evolution_history, update_evolution_log_status,
141
- )
142
-
143
- # Cron execution history
144
- from db._cron_runs import (
145
- cron_run_start, cron_run_end, cron_runs_recent, cron_runs_summary,
146
- )
147
-
148
- # Protocol discipline runtime
149
- from db._protocol import (
150
- VALID_IMPACT_LEVELS,
151
- VALID_TASK_TYPES,
152
- VALID_CLOSE_OUTCOMES,
153
- create_protocol_task, get_protocol_task, close_protocol_task,
154
- create_protocol_debt, resolve_protocol_debts, list_protocol_debts,
155
- protocol_compliance_summary,
156
- create_cortex_evaluation, get_cortex_evaluation, list_cortex_evaluations,
157
- cortex_evaluation_summary,
158
- latest_cortex_evaluation_for_task, task_has_cortex_evaluation,
159
- override_cortex_evaluation, validate_close_outcome, validate_impact_level, validate_task_type,
160
- )
161
-
162
- # Durable workflow runtime
163
- from db._workflow import (
164
- create_workflow_run, get_workflow_run, list_workflow_runs,
165
- list_workflow_steps, record_workflow_transition,
166
- get_workflow_replay, get_workflow_resume_state,
167
- create_workflow_goal, get_workflow_goal, list_workflow_goals,
168
- update_workflow_goal,
169
- )
170
-
171
- # State watchers
172
- from db._watchers import (
173
- create_state_watcher, get_state_watcher, list_state_watchers,
174
- update_state_watcher, update_state_watcher_result,
175
- )
176
-
177
- # Personal scripts registry
178
- from db._personal_scripts import (
179
- upsert_personal_script, list_personal_scripts, get_personal_script,
180
- delete_missing_personal_scripts, register_personal_script_schedule,
181
- delete_missing_personal_schedules, list_personal_script_schedules,
182
- get_personal_script_schedule, delete_personal_script_schedule,
183
- delete_personal_script,
184
- record_personal_script_run, sync_personal_scripts_registry,
185
- get_personal_script_health_report,
186
- )
187
-
188
- # Skills
189
- from db._skills import (
190
- create_skill, get_skill, list_skills, search_skills,
191
- update_skill, delete_skill,
192
- record_usage as record_skill_usage,
193
- match_skills, merge_skills, get_skill_stats, decay_unused_skills,
194
- get_featured_skills, get_skill_execution_spec, resolve_skill_paths,
195
- validate_skill_params, render_command_template, sync_skill_directories,
196
- import_skill_from_directory, approve_skill, collect_scriptable_skill_candidates,
197
- collect_skill_improvement_candidates, materialize_personal_skill_definition,
198
- get_skill_outcome_evidence, list_skill_outcome_reviews,
199
- get_skill_health_report,
200
- )
201
-
202
- # Drive / Curiosity signals
203
- from db._drive import (
204
- create_drive_signal, reinforce_drive_signal, get_drive_signals,
205
- get_drive_signal, update_drive_signal_status, decay_drive_signals,
206
- find_similar_drive_signal, drive_signal_stats,
207
- )
208
-
209
- # Hot context / recent continuity
210
- from db._hot_context import (
211
- DEFAULT_CONTEXT_TTL_HOURS,
212
- derive_context_key, clamp_ttl_hours,
213
- cleanup_expired_hot_context,
214
- remember_hot_context, record_recent_event, capture_context_event,
215
- get_hot_context, search_hot_context, search_recent_events,
216
- build_pre_action_context, format_pre_action_context_bundle,
217
- resolve_hot_context,
218
- )
219
-
220
- # Outcomes
221
- from db._outcomes import (
222
- VALID_METRIC_SOURCES as OUTCOME_METRIC_SOURCES,
223
- VALID_TARGET_OPERATORS as OUTCOME_TARGET_OPERATORS,
224
- create_outcome, get_outcome, list_outcomes,
225
- cancel_outcome, evaluate_outcome, pending_outcomes_due,
226
- find_pending_outcomes_by_action, set_linked_outcomes_met,
227
- list_outcome_pattern_candidates, capture_outcome_pattern,
228
- )
229
-
230
- # Goal Engine v1
231
- from db._goal_profiles import (
232
- DEFAULT_GOAL_PROFILES,
233
- ensure_default_goal_profiles, get_goal_profile, list_goal_profiles,
234
- upsert_goal_profile, resolve_goal_profile,
235
- )
236
-
237
-
238
- def get_db():
239
- return _module("db._core").get_db()
240
-
241
-
242
- def close_db():
243
- return _module("db._core").close_db()
244
-
245
-
246
- def init_db():
247
- return _module("db._core").init_db()
248
-
249
-
250
- def now_epoch():
251
- return _module("db._core").now_epoch()
252
-
253
-
254
- def run_migrations():
255
- return _module("db._schema").run_migrations()
256
-
257
-
258
- def get_schema_version():
259
- return _module("db._schema").get_schema_version()