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.
- package/.claude-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/src/server.py +3 -0
- package/src/tools_sessions.py +6 -1
- package/src/dashboard/static/favicon 2.svg +0 -32
- package/src/dashboard/static/nexo-logo 2.png +0 -0
- package/src/dashboard/static/nexo-logo 2.svg +0 -40
- package/src/dashboard/static/style 2.css +0 -2458
- package/src/dashboard/templates/adaptive 2.html +0 -118
- package/src/dashboard/templates/artifacts 2.html +0 -133
- package/src/dashboard/templates/backups 2.html +0 -136
- package/src/dashboard/templates/base 2.html +0 -417
- package/src/dashboard/templates/calendar 2.html +0 -591
- package/src/dashboard/templates/chat 2.html +0 -356
- package/src/dashboard/templates/claims 2.html +0 -259
- package/src/dashboard/templates/cortex 2.html +0 -321
- package/src/dashboard/templates/credentials 2.html +0 -128
- package/src/dashboard/templates/crons 2.html +0 -370
- package/src/dashboard/templates/dashboard 2.html +0 -494
- package/src/dashboard/templates/dreams 2.html +0 -252
- package/src/dashboard/templates/email 2.html +0 -160
- package/src/dashboard/templates/evolution 2.html +0 -189
- package/src/dashboard/templates/feed 2.html +0 -249
- package/src/dashboard/templates/followup_health 2.html +0 -170
- package/src/dashboard/templates/graph 2.html +0 -201
- package/src/dashboard/templates/guard 2.html +0 -259
- package/src/dashboard/templates/inbox 2.html +0 -251
- package/src/dashboard/templates/memory 2.html +0 -420
- package/src/dashboard/templates/operations 2.html +0 -608
- package/src/dashboard/templates/plugins 2.html +0 -185
- package/src/dashboard/templates/protocol 2.html +0 -199
- package/src/dashboard/templates/rules 2.html +0 -246
- package/src/dashboard/templates/sentiment 2.html +0 -247
- package/src/dashboard/templates/sessions 2.html +0 -218
- package/src/dashboard/templates/skills 2.html +0 -329
- package/src/dashboard/templates/somatic 2.html +0 -73
- package/src/dashboard/templates/triggers 2.html +0 -133
- package/src/dashboard/templates/trust 2.html +0 -360
- package/src/db/__init__ 2.py +0 -259
- package/src/db/_core 2.py +0 -437
- package/src/db/_credentials 2.py +0 -124
- package/src/db/_episodic 2.py +0 -762
- package/src/db/_evolution 2.py +0 -54
- package/src/db/_fts 2.py +0 -406
- package/src/db/_goal_profiles 2.py +0 -376
- package/src/db/_hot_context 2.py +0 -660
- package/src/db/_outcomes 2.py +0 -800
- package/src/db/_personal_scripts 2.py +0 -582
- package/src/db/_sessions 2.py +0 -330
- package/src/db/_tasks 2.py +0 -91
- package/src/db/_watchers 2.py +0 -173
- package/src/doctor/formatters 2.py +0 -52
- package/src/doctor/models 2.py +0 -69
- package/src/doctor/planes 2.py +0 -87
- package/src/doctor/providers/__init__ 2.py +0 -1
- package/src/doctor/providers/deep 2.py +0 -367
- package/src/evolution_cycle 2.py +0 -519
- 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 -158
- package/src/hooks/daily-briefing-check 2.sh +0 -33
- package/src/hooks/heartbeat-enforcement 2.py +0 -90
- package/src/hooks/heartbeat-posttool 2.sh +0 -18
- package/src/hooks/inbox-hook 2.sh +0 -76
- package/src/hooks/post-compact 2.sh +0 -152
- package/src/hooks/pre-compact 2.sh +0 -169
- package/src/hooks/protocol-guardrail 2.sh +0 -10
- package/src/hooks/protocol-pretool-guardrail 2.sh +0 -9
- package/src/hooks/session-stop 2.sh +0 -52
- package/src/kg_populate 2.py +0 -292
- package/src/maintenance 2.py +0 -53
- package/src/memory_backends 2.py +0 -71
- package/src/migrate_embeddings 2.py +0 -124
- package/src/nexo_sdk 2.py +0 -103
- package/src/observability 2.py +0 -199
- package/src/plugin_loader 2.py +0 -217
- package/src/plugins/__init__ 2.py +0 -0
- package/src/plugins/artifact_registry 2.py +0 -450
- package/src/plugins/backup 2.py +0 -127
- package/src/plugins/claims_tools 2.py +0 -119
- package/src/plugins/cognitive_memory 2.py +0 -609
- package/src/plugins/core_rules 2.py +0 -252
- package/src/plugins/cortex 2.py +0 -1155
- package/src/plugins/entities 2.py +0 -67
- package/src/plugins/episodic_memory 2.py +0 -560
- package/src/plugins/evolution 2.py +0 -167
- package/src/plugins/goal_engine 2.py +0 -142
- package/src/plugins/guard 2.py +0 -862
- package/src/plugins/impact 2.py +0 -29
- package/src/plugins/knowledge_graph_tools 2.py +0 -137
- package/src/plugins/media_memory_tools 2.py +0 -98
- package/src/plugins/memory_export 2.py +0 -196
- package/src/plugins/outcomes 2.py +0 -130
- package/src/plugins/personal_scripts 2.py +0 -117
- package/src/plugins/preferences 2.py +0 -47
- package/src/plugins/protocol 2.py +0 -1449
- package/src/plugins/simple_api 2.py +0 -106
- package/src/plugins/skills 2.py +0 -341
- package/src/plugins/state_watchers 2.py +0 -79
- package/src/plugins/update 2.py +0 -986
- package/src/plugins/user_state_tools 2.py +0 -43
- package/src/plugins/workflow 2.py +0 -588
- package/src/protocol_settings 2.py +0 -59
- package/src/public_contribution 2.py +0 -466
- package/src/public_evolution_queue 2.py +0 -241
- package/src/requirements 2.txt +0 -14
- package/src/retroactive_learnings 2.py +0 -373
- 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/runtime_power 2.py +0 -874
- package/src/script_registry 2.py +0 -1559
- package/src/scripts/check-context 2.py +0 -272
- package/src/scripts/deep-sleep/apply_findings 2.py +0 -2327
- package/src/scripts/deep-sleep/collect 2.py +0 -928
- package/src/scripts/deep-sleep/extract 2.py +0 -330
- package/src/scripts/deep-sleep/extract-prompt 2.md +0 -285
- package/src/scripts/deep-sleep/synthesize 2.py +0 -312
- package/src/scripts/deep-sleep/synthesize-prompt 2.md +0 -336
- package/src/scripts/nexo-agent-run 2.py +0 -75
- 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 -300
- package/src/scripts/nexo-cognitive-decay 2.py +0 -257
- package/src/scripts/nexo-cortex-cycle 2.py +0 -293
- package/src/scripts/nexo-cron-wrapper 2.sh +0 -53
- package/src/scripts/nexo-daily-self-audit 2.py +0 -2161
- package/src/scripts/nexo-dashboard 2.sh +0 -29
- package/src/scripts/nexo-deep-sleep 2.sh +0 -86
- package/src/scripts/nexo-evolution-run 2.py +0 -1664
- package/src/scripts/nexo-followup-hygiene 2.py +0 -139
- package/src/scripts/nexo-hook-record 2.py +0 -42
- package/src/scripts/nexo-immune 2.py +0 -936
- package/src/scripts/nexo-impact-scorer 2.py +0 -117
- 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 -401
- package/src/scripts/nexo-learning-validator 2.py +0 -266
- package/src/scripts/nexo-migrate 2.py +0 -260
- package/src/scripts/nexo-outcome-checker 2.py +0 -127
- package/src/scripts/nexo-postmortem-consolidator 2.py +0 -456
- package/src/scripts/nexo-pre-commit 2.py +0 -120
- package/src/scripts/nexo-prevent-sleep 2.sh +0 -35
- package/src/scripts/nexo-proactive-dashboard 2.py +0 -354
- package/src/scripts/nexo-reflection 2.py +0 -256
- package/src/scripts/nexo-runtime-preflight 2.py +0 -274
- package/src/scripts/nexo-sleep 2.py +0 -631
- package/src/scripts/nexo-snapshot-restore 2.sh +0 -35
- package/src/scripts/nexo-sync-clients 2.py +0 -16
- package/src/scripts/nexo-synthesis 2.py +0 -475
- package/src/scripts/nexo-tcc-approve 2.sh +0 -79
- package/src/scripts/nexo-update 2.sh +0 -306
- package/src/scripts/nexo-watchdog 2.sh +0 -1207
- package/src/scripts/nexo-watchdog-smoke 2.py +0 -119
- package/src/scripts/rehydrate_learnings_from_archive 2.py +0 -245
- package/src/server 2.py +0 -1296
- package/src/skills/run-nexo-audit-phase/guide 2.md +0 -43
- package/src/skills/run-nexo-audit-phase/skill 2.json +0 -59
- package/src/skills/run-nexo-core-fix-cycle/guide 2.md +0 -17
- package/src/skills/run-nexo-core-fix-cycle/script 2.py +0 -276
- package/src/skills/run-nexo-core-fix-cycle/skill 2.json +0 -58
- package/src/skills/run-release-final-audit/guide 2.md +0 -16
- package/src/skills/run-release-final-audit/script 2.py +0 -259
- package/src/skills/run-release-final-audit/skill 2.json +0 -77
- package/src/skills/run-runtime-doctor/guide 2.md +0 -12
- package/src/skills/run-runtime-doctor/script 2.py +0 -21
- package/src/skills/run-runtime-doctor/skill 2.json +0 -25
- package/src/skills_runtime 2.py +0 -932
- package/src/state_watchers_runtime 2.py +0 -475
- package/src/storage_router 2.py +0 -32
- package/src/system_catalog 2.py +0 -786
- package/src/tools_coordination 2.py +0 -103
- package/src/tools_credentials 2.py +0 -68
- package/src/tools_drive 2.py +0 -487
- package/src/tools_hot_context 2.py +0 -163
- package/src/tools_learnings 2.py +0 -612
- package/src/tools_menu 2.py +0 -229
- package/src/tools_reminders 2.py +0 -88
- package/src/tools_reminders_crud 2.py +0 -363
- package/src/tools_sessions 2.py +0 -1054
- package/src/tools_system_catalog 2.py +0 -19
- package/src/tools_task_history 2.py +0 -57
- package/src/tools_transcripts 2.py +0 -98
- package/src/transcript_utils 2.py +0 -412
- package/src/user_context 2.py +0 -46
- package/src/user_data_portability 2.py +0 -328
- package/src/user_state_model 2.py +0 -170
- package/templates/CLAUDE.md 2.template +0 -108
- package/templates/CODEX.AGENTS.md 2.template +0 -66
- package/templates/launchagents/README 2.md +0 -132
- package/templates/launchagents/com.nexo.auto-close-sessions 2.plist +0 -39
- package/templates/launchagents/com.nexo.catchup 2.plist +0 -39
- package/templates/launchagents/com.nexo.cognitive-decay 2.plist +0 -40
- package/templates/launchagents/com.nexo.dashboard 2.plist +0 -43
- package/templates/launchagents/com.nexo.deep-sleep 2.plist +0 -43
- package/templates/launchagents/com.nexo.evolution 2.plist +0 -44
- package/templates/launchagents/com.nexo.followup-hygiene 2.plist +0 -45
- package/templates/launchagents/com.nexo.immune 2.plist +0 -41
- package/templates/launchagents/com.nexo.postmortem 2.plist +0 -45
- package/templates/launchagents/com.nexo.self-audit 2.plist +0 -47
- package/templates/launchagents/com.nexo.synthesis 2.plist +0 -45
- package/templates/launchagents/com.nexo.watchdog 2.plist +0 -37
- package/templates/nexo_helper 2.py +0 -301
- package/templates/openclaw 2.json +0 -13
- package/templates/plugin-template 2.py +0 -40
- package/templates/script-template 2.py +0 -59
- package/templates/script-template 2.sh +0 -13
- package/templates/skill-script-template 2.py +0 -48
- package/templates/skill-template 2.md +0 -33
|
@@ -1,417 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en" class="h-full">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>{% block title %}NEXO Brain{% endblock %} — Dashboard</title>
|
|
7
|
-
<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
|
|
8
|
-
<script src="https://cdn.tailwindcss.com"></script>
|
|
9
|
-
<script>
|
|
10
|
-
tailwind.config = {
|
|
11
|
-
theme: {
|
|
12
|
-
extend: {
|
|
13
|
-
fontFamily: {
|
|
14
|
-
display: ['Space Grotesk', 'system-ui', 'sans-serif'],
|
|
15
|
-
mono: ['JetBrains Mono', 'monospace'],
|
|
16
|
-
},
|
|
17
|
-
colors: {
|
|
18
|
-
nexo: {
|
|
19
|
-
50: '#f3f0ff', 100: '#e9e3ff', 200: '#d4c9ff',
|
|
20
|
-
300: '#b49dff', 400: '#9061ff', 500: '#7C3AED',
|
|
21
|
-
600: '#6d28d9', 700: '#5b21b6', 800: '#4c1d95', 900: '#2e1065',
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
animation: {
|
|
25
|
-
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
|
|
26
|
-
'fade-in': 'fadeIn 0.3s ease-out',
|
|
27
|
-
'slide-in': 'slideIn 0.3s ease-out',
|
|
28
|
-
},
|
|
29
|
-
keyframes: {
|
|
30
|
-
fadeIn: { '0%': { opacity: '0' }, '100%': { opacity: '1' } },
|
|
31
|
-
slideIn: { '0%': { opacity: '0', transform: 'translateY(8px)' }, '100%': { opacity: '1', transform: 'translateY(0)' } },
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
</script>
|
|
37
|
-
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
38
|
-
<style>
|
|
39
|
-
/* Scrollbar */
|
|
40
|
-
::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
41
|
-
::-webkit-scrollbar-track { background: transparent; }
|
|
42
|
-
::-webkit-scrollbar-thumb { background: #334155; border-radius: 3px; }
|
|
43
|
-
::-webkit-scrollbar-thumb:hover { background: #475569; }
|
|
44
|
-
|
|
45
|
-
/* Sidebar group toggle */
|
|
46
|
-
.nav-group-items { max-height: 0; overflow: hidden; transition: max-height 0.25s ease-out; }
|
|
47
|
-
.nav-group.open .nav-group-items { max-height: 500px; }
|
|
48
|
-
.nav-group .chevron { transition: transform 0.2s; }
|
|
49
|
-
.nav-group.open .chevron { transform: rotate(90deg); }
|
|
50
|
-
|
|
51
|
-
/* Active nav item */
|
|
52
|
-
.nav-item.active { background: rgba(124, 58, 237, 0.12); color: #a78bfa; border-left: 2px solid #7C3AED; }
|
|
53
|
-
.nav-item { border-left: 2px solid transparent; }
|
|
54
|
-
.nav-item:hover:not(.active) { background: rgba(51, 65, 85, 0.3); }
|
|
55
|
-
|
|
56
|
-
/* Card hover */
|
|
57
|
-
.card { transition: border-color 0.2s, box-shadow 0.2s; }
|
|
58
|
-
.card:hover { border-color: rgba(124, 58, 237, 0.3); box-shadow: 0 0 20px rgba(124, 58, 237, 0.08); }
|
|
59
|
-
|
|
60
|
-
/* Glow dot */
|
|
61
|
-
@keyframes glow { 0%, 100% { box-shadow: 0 0 4px currentColor; } 50% { box-shadow: 0 0 12px currentColor; } }
|
|
62
|
-
.glow-dot { animation: glow 2s ease-in-out infinite; }
|
|
63
|
-
|
|
64
|
-
/* Chat styles */
|
|
65
|
-
.chat-bubble { animation: slideIn 0.3s ease-out; }
|
|
66
|
-
</style>
|
|
67
|
-
{% block head %}{% endblock %}
|
|
68
|
-
</head>
|
|
69
|
-
<body class="h-full bg-gray-950 text-slate-200 antialiased font-display">
|
|
70
|
-
|
|
71
|
-
<!-- Sidebar -->
|
|
72
|
-
<aside id="sidebar" class="fixed left-0 top-0 bottom-0 w-56 bg-slate-900/95 backdrop-blur border-r border-slate-800/80 flex flex-col z-50 overflow-hidden">
|
|
73
|
-
<!-- Logo -->
|
|
74
|
-
<a href="/" class="flex items-center gap-2.5 px-4 py-3.5 border-b border-slate-800/50 hover:bg-slate-800/30 transition-colors">
|
|
75
|
-
<img src="/static/nexo-logo.png" alt="NEXO" class="w-7 h-7">
|
|
76
|
-
<span class="text-sm font-display font-semibold text-slate-100 tracking-tight">NEXO Brain</span>
|
|
77
|
-
<span class="ml-auto text-[10px] font-mono text-slate-600">v2.0</span>
|
|
78
|
-
</a>
|
|
79
|
-
|
|
80
|
-
<!-- Navigation -->
|
|
81
|
-
<nav class="flex-1 overflow-y-auto py-2 px-2 space-y-0.5" id="main-nav">
|
|
82
|
-
|
|
83
|
-
<!-- OVERVIEW -->
|
|
84
|
-
<div class="nav-group open" data-group="overview">
|
|
85
|
-
<button class="w-full flex items-center gap-2 px-2 py-1.5 text-[10px] uppercase tracking-widest text-slate-500 font-semibold hover:text-slate-400" onclick="toggleGroup(this)">
|
|
86
|
-
<svg class="w-3 h-3 chevron" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
|
|
87
|
-
Overview
|
|
88
|
-
</button>
|
|
89
|
-
<div class="nav-group-items">
|
|
90
|
-
<a href="/" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="dashboard">
|
|
91
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/></svg>
|
|
92
|
-
Cognitive Pulse
|
|
93
|
-
</a>
|
|
94
|
-
<a href="/feed" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="feed">
|
|
95
|
-
<svg class="w-4 h-4 flex-shrink-0" 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>
|
|
96
|
-
Activity Feed
|
|
97
|
-
</a>
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
<!-- OPERATIONS -->
|
|
102
|
-
<div class="nav-group open" data-group="operations">
|
|
103
|
-
<button class="w-full flex items-center gap-2 px-2 py-1.5 text-[10px] uppercase tracking-widest text-slate-500 font-semibold hover:text-slate-400" onclick="toggleGroup(this)">
|
|
104
|
-
<svg class="w-3 h-3 chevron" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
|
|
105
|
-
Operations
|
|
106
|
-
</button>
|
|
107
|
-
<div class="nav-group-items">
|
|
108
|
-
<a href="/crons" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="crons">
|
|
109
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
|
110
|
-
Crons Control
|
|
111
|
-
</a>
|
|
112
|
-
<a href="/ops" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="ops">
|
|
113
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
|
|
114
|
-
Ops Center
|
|
115
|
-
</a>
|
|
116
|
-
<a href="/calendar" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="calendar">
|
|
117
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
|
118
|
-
Calendar
|
|
119
|
-
</a>
|
|
120
|
-
</div>
|
|
121
|
-
</div>
|
|
122
|
-
|
|
123
|
-
<!-- INTELLIGENCE -->
|
|
124
|
-
<div class="nav-group open" data-group="intelligence">
|
|
125
|
-
<button class="w-full flex items-center gap-2 px-2 py-1.5 text-[10px] uppercase tracking-widest text-slate-500 font-semibold hover:text-slate-400" onclick="toggleGroup(this)">
|
|
126
|
-
<svg class="w-3 h-3 chevron" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
|
|
127
|
-
Intelligence
|
|
128
|
-
</button>
|
|
129
|
-
<div class="nav-group-items">
|
|
130
|
-
<a href="/chat" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="chat">
|
|
131
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"/></svg>
|
|
132
|
-
NEXO Chat
|
|
133
|
-
<span class="ml-auto px-1.5 py-0.5 text-[9px] font-bold uppercase bg-nexo-500/20 text-nexo-400 rounded">new</span>
|
|
134
|
-
</a>
|
|
135
|
-
<a href="/memory" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="memory">
|
|
136
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/></svg>
|
|
137
|
-
Memory Flow
|
|
138
|
-
</a>
|
|
139
|
-
<a href="/dreams" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="dreams">
|
|
140
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg>
|
|
141
|
-
Dream Journal
|
|
142
|
-
</a>
|
|
143
|
-
<a href="/skills" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="skills">
|
|
144
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"/></svg>
|
|
145
|
-
Skills Lab
|
|
146
|
-
</a>
|
|
147
|
-
<a href="/trust" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="trust">
|
|
148
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
|
|
149
|
-
Trust Deep-Dive
|
|
150
|
-
</a>
|
|
151
|
-
</div>
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
|
-
<!-- SECURITY -->
|
|
155
|
-
<div class="nav-group" data-group="security">
|
|
156
|
-
<button class="w-full flex items-center gap-2 px-2 py-1.5 text-[10px] uppercase tracking-widest text-slate-500 font-semibold hover:text-slate-400" onclick="toggleGroup(this)">
|
|
157
|
-
<svg class="w-3 h-3 chevron" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
|
|
158
|
-
Security
|
|
159
|
-
</button>
|
|
160
|
-
<div class="nav-group-items">
|
|
161
|
-
<a href="/guard" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="guard">
|
|
162
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
|
163
|
-
Guard Heatmap
|
|
164
|
-
</a>
|
|
165
|
-
<a href="/protocol" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="protocol">
|
|
166
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6M7 4h10a2 2 0 012 2v12a2 2 0 01-2 2H7a2 2 0 01-2-2V6a2 2 0 012-2z"/></svg>
|
|
167
|
-
Protocol Explainability
|
|
168
|
-
</a>
|
|
169
|
-
<a href="/cortex" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="cortex">
|
|
170
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/></svg>
|
|
171
|
-
Cortex Monitor
|
|
172
|
-
</a>
|
|
173
|
-
<a href="/rules" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="rules">
|
|
174
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"/></svg>
|
|
175
|
-
Core Rules
|
|
176
|
-
</a>
|
|
177
|
-
<a href="/plugins" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="plugins">
|
|
178
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M11 4a2 2 0 114 0v1a1 1 0 001 1h3a1 1 0 011 1v3a1 1 0 01-1 1h-1a2 2 0 100 4h1a1 1 0 011 1v3a1 1 0 01-1 1h-3a1 1 0 01-1-1v-1a2 2 0 10-4 0v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-3a1 1 0 00-1-1H4a2 2 0 110-4h1a1 1 0 001-1V7a1 1 0 011-1h3a1 1 0 001-1V4z"/></svg>
|
|
179
|
-
Plugins
|
|
180
|
-
</a>
|
|
181
|
-
</div>
|
|
182
|
-
</div>
|
|
183
|
-
|
|
184
|
-
<!-- ADVANCED -->
|
|
185
|
-
<div class="nav-group" data-group="advanced">
|
|
186
|
-
<button class="w-full flex items-center gap-2 px-2 py-1.5 text-[10px] uppercase tracking-widest text-slate-500 font-semibold hover:text-slate-400" onclick="toggleGroup(this)">
|
|
187
|
-
<svg class="w-3 h-3 chevron" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
|
|
188
|
-
Advanced
|
|
189
|
-
</button>
|
|
190
|
-
<div class="nav-group-items">
|
|
191
|
-
<a href="/evolution" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="evolution">
|
|
192
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>
|
|
193
|
-
Evolution
|
|
194
|
-
</a>
|
|
195
|
-
<a href="/claims" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="claims">
|
|
196
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/></svg>
|
|
197
|
-
Claims Network
|
|
198
|
-
</a>
|
|
199
|
-
<a href="/sentiment" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="sentiment">
|
|
200
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/></svg>
|
|
201
|
-
Sentiment
|
|
202
|
-
</a>
|
|
203
|
-
<a href="/sessions" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="sessions">
|
|
204
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5M7.188 2.239l.777 2.897M5.136 7.965l-2.898-.777M13.95 4.05l-2.122 2.122m-5.657 5.656l-2.12 2.122"/></svg>
|
|
205
|
-
Sessions
|
|
206
|
-
</a>
|
|
207
|
-
<a href="/triggers" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="triggers">
|
|
208
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/></svg>
|
|
209
|
-
Triggers
|
|
210
|
-
</a>
|
|
211
|
-
<a href="/artifacts" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="artifacts">
|
|
212
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"/></svg>
|
|
213
|
-
Artifacts
|
|
214
|
-
</a>
|
|
215
|
-
</div>
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
<!-- SYSTEM -->
|
|
219
|
-
<div class="nav-group" data-group="system">
|
|
220
|
-
<button class="w-full flex items-center gap-2 px-2 py-1.5 text-[10px] uppercase tracking-widest text-slate-500 font-semibold hover:text-slate-400" onclick="toggleGroup(this)">
|
|
221
|
-
<svg class="w-3 h-3 chevron" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
|
|
222
|
-
System
|
|
223
|
-
</button>
|
|
224
|
-
<div class="nav-group-items">
|
|
225
|
-
<a href="/inbox" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="inbox">
|
|
226
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
|
|
227
|
-
Inbox
|
|
228
|
-
</a>
|
|
229
|
-
<a href="/email" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="email">
|
|
230
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"/></svg>
|
|
231
|
-
Email Monitor
|
|
232
|
-
</a>
|
|
233
|
-
<a href="/credentials" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="credentials">
|
|
234
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/></svg>
|
|
235
|
-
Credentials
|
|
236
|
-
</a>
|
|
237
|
-
<a href="/backups" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="backups">
|
|
238
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"/></svg>
|
|
239
|
-
Backups
|
|
240
|
-
</a>
|
|
241
|
-
<a href="/followup-health" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="followup-health">
|
|
242
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/></svg>
|
|
243
|
-
Followup Health
|
|
244
|
-
</a>
|
|
245
|
-
</div>
|
|
246
|
-
</div>
|
|
247
|
-
|
|
248
|
-
<!-- Knowledge (from existing) -->
|
|
249
|
-
<div class="nav-group" data-group="knowledge">
|
|
250
|
-
<button class="w-full flex items-center gap-2 px-2 py-1.5 text-[10px] uppercase tracking-widest text-slate-500 font-semibold hover:text-slate-400" onclick="toggleGroup(this)">
|
|
251
|
-
<svg class="w-3 h-3 chevron" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"/></svg>
|
|
252
|
-
Knowledge
|
|
253
|
-
</button>
|
|
254
|
-
<div class="nav-group-items">
|
|
255
|
-
<a href="/graph" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="graph">
|
|
256
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/></svg>
|
|
257
|
-
Knowledge Graph
|
|
258
|
-
</a>
|
|
259
|
-
<a href="/somatic" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="somatic">
|
|
260
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/></svg>
|
|
261
|
-
Somatic Markers
|
|
262
|
-
</a>
|
|
263
|
-
<a href="/adaptive" class="nav-item flex items-center gap-2.5 px-3 py-1.5 rounded-md text-xs text-slate-400 transition-colors" data-page="adaptive">
|
|
264
|
-
<svg class="w-4 h-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"/></svg>
|
|
265
|
-
Adaptive Mode
|
|
266
|
-
</a>
|
|
267
|
-
</div>
|
|
268
|
-
</div>
|
|
269
|
-
</nav>
|
|
270
|
-
|
|
271
|
-
<!-- Sidebar footer -->
|
|
272
|
-
<div class="border-t border-slate-800/50 p-3">
|
|
273
|
-
<div class="flex items-center justify-between">
|
|
274
|
-
<div class="flex items-center gap-2">
|
|
275
|
-
<div class="w-2 h-2 rounded-full glow-dot" id="system-status-dot" style="color: #10B981; background: #10B981;"></div>
|
|
276
|
-
<span class="text-[10px] text-slate-500 uppercase tracking-wider">System</span>
|
|
277
|
-
</div>
|
|
278
|
-
<span class="text-xs font-mono text-slate-500" id="sidebar-clock">--:--</span>
|
|
279
|
-
</div>
|
|
280
|
-
<div class="mt-2 flex items-center justify-between">
|
|
281
|
-
<span class="text-[10px] text-slate-500">Trust</span>
|
|
282
|
-
<span class="text-xs font-mono font-medium text-nexo-400" id="sidebar-trust-value">--</span>
|
|
283
|
-
</div>
|
|
284
|
-
</div>
|
|
285
|
-
</aside>
|
|
286
|
-
|
|
287
|
-
<!-- Main content -->
|
|
288
|
-
<main class="ml-56 min-h-screen bg-gray-950">
|
|
289
|
-
<!-- Top bar -->
|
|
290
|
-
<header class="h-12 border-b border-slate-800/50 flex items-center justify-between px-6 sticky top-0 bg-gray-950/95 backdrop-blur-md z-40">
|
|
291
|
-
<div class="flex items-center gap-3">
|
|
292
|
-
<h1 class="text-sm font-display font-semibold text-slate-100">{% block page_title %}Dashboard{% endblock %}</h1>
|
|
293
|
-
{% block page_subtitle %}{% endblock %}
|
|
294
|
-
</div>
|
|
295
|
-
<div class="flex items-center gap-2">
|
|
296
|
-
{% block header_actions %}{% endblock %}
|
|
297
|
-
<div class="w-px h-4 bg-slate-700 mx-1"></div>
|
|
298
|
-
<span class="text-xs text-slate-500 font-mono tabular-nums" id="current-time">--:--:--</span>
|
|
299
|
-
</div>
|
|
300
|
-
</header>
|
|
301
|
-
|
|
302
|
-
<!-- Page content -->
|
|
303
|
-
<div class="p-5 animate-fade-in">
|
|
304
|
-
{% block content %}{% endblock %}
|
|
305
|
-
</div>
|
|
306
|
-
</main>
|
|
307
|
-
|
|
308
|
-
<!-- Toast -->
|
|
309
|
-
<div id="toast" class="hidden fixed bottom-4 right-4 z-[60] bg-slate-800 border border-slate-700 rounded-lg px-4 py-2.5 text-sm text-slate-200 shadow-xl flex items-center gap-2 animate-slide-in">
|
|
310
|
-
<span id="toast-msg"></span>
|
|
311
|
-
</div>
|
|
312
|
-
|
|
313
|
-
<script>
|
|
314
|
-
// -----------------------------------------------------------------------
|
|
315
|
-
// Global utilities
|
|
316
|
-
// -----------------------------------------------------------------------
|
|
317
|
-
function escapeHtml(str) {
|
|
318
|
-
const div = document.createElement('div');
|
|
319
|
-
div.textContent = str || '';
|
|
320
|
-
return div.innerHTML;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
function showToast(msg, duration = 2500) {
|
|
324
|
-
const t = document.getElementById('toast');
|
|
325
|
-
document.getElementById('toast-msg').textContent = msg;
|
|
326
|
-
t.classList.remove('hidden');
|
|
327
|
-
t.classList.add('flex');
|
|
328
|
-
clearTimeout(t._timer);
|
|
329
|
-
t._timer = setTimeout(() => { t.classList.add('hidden'); t.classList.remove('flex'); }, duration);
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
async function fetchJSON(url) {
|
|
333
|
-
try {
|
|
334
|
-
const res = await fetch(url);
|
|
335
|
-
if (!res.ok) { let d = `HTTP ${res.status}`; try { const b = await res.json(); d = b.error || b.detail || d; } catch {} throw new Error(d); }
|
|
336
|
-
return await res.json();
|
|
337
|
-
} catch (err) { console.error(`fetchJSON(${url}):`, err); return null; }
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
function relativeTime(dateStr) {
|
|
341
|
-
if (!dateStr) return '--';
|
|
342
|
-
const d = new Date(dateStr);
|
|
343
|
-
const now = new Date();
|
|
344
|
-
const diff = Math.floor((now - d) / 1000);
|
|
345
|
-
if (diff < 60) return 'just now';
|
|
346
|
-
if (diff < 3600) return Math.floor(diff / 60) + 'm ago';
|
|
347
|
-
if (diff < 86400) return Math.floor(diff / 3600) + 'h ago';
|
|
348
|
-
return Math.floor(diff / 86400) + 'd ago';
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function relativeDate(dateStr) {
|
|
352
|
-
if (!dateStr) return 'no date';
|
|
353
|
-
const d = new Date(dateStr + 'T00:00:00');
|
|
354
|
-
const now = new Date(); now.setHours(0, 0, 0, 0);
|
|
355
|
-
const diff = Math.round((d - now) / 86400000);
|
|
356
|
-
if (diff < -1) return Math.abs(diff) + 'd overdue';
|
|
357
|
-
if (diff === -1) return 'yesterday';
|
|
358
|
-
if (diff === 0) return 'today';
|
|
359
|
-
if (diff === 1) return 'tomorrow';
|
|
360
|
-
return d.toLocaleDateString('en', { month: 'short', day: 'numeric' });
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
function formatNumber(n) {
|
|
364
|
-
if (n === null || n === undefined) return '--';
|
|
365
|
-
return n.toLocaleString();
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// -----------------------------------------------------------------------
|
|
369
|
-
// Clock
|
|
370
|
-
// -----------------------------------------------------------------------
|
|
371
|
-
function updateClock() {
|
|
372
|
-
const now = new Date();
|
|
373
|
-
const timeStr = now.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
374
|
-
document.getElementById('current-time').textContent = timeStr;
|
|
375
|
-
document.getElementById('sidebar-clock').textContent = now.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
|
|
376
|
-
}
|
|
377
|
-
updateClock();
|
|
378
|
-
setInterval(updateClock, 1000);
|
|
379
|
-
|
|
380
|
-
// -----------------------------------------------------------------------
|
|
381
|
-
// Navigation
|
|
382
|
-
// -----------------------------------------------------------------------
|
|
383
|
-
function toggleGroup(btn) {
|
|
384
|
-
btn.closest('.nav-group').classList.toggle('open');
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// Highlight active nav item
|
|
388
|
-
(function() {
|
|
389
|
-
const path = window.location.pathname;
|
|
390
|
-
document.querySelectorAll('.nav-item').forEach(item => {
|
|
391
|
-
const href = item.getAttribute('href');
|
|
392
|
-
if (href === path || (path === '/' && href === '/')) {
|
|
393
|
-
item.classList.add('active');
|
|
394
|
-
// Open parent group
|
|
395
|
-
const group = item.closest('.nav-group');
|
|
396
|
-
if (group) group.classList.add('open');
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
})();
|
|
400
|
-
|
|
401
|
-
// -----------------------------------------------------------------------
|
|
402
|
-
// Sidebar trust score (global, updates on all pages)
|
|
403
|
-
// -----------------------------------------------------------------------
|
|
404
|
-
async function updateSidebarTrust() {
|
|
405
|
-
const data = await fetchJSON('/api/trust');
|
|
406
|
-
if (data) {
|
|
407
|
-
const score = data.current_score ?? 0;
|
|
408
|
-
document.getElementById('sidebar-trust-value').textContent = score.toFixed(1);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
updateSidebarTrust();
|
|
412
|
-
setInterval(updateSidebarTrust, 120000);
|
|
413
|
-
</script>
|
|
414
|
-
|
|
415
|
-
{% block scripts %}{% endblock %}
|
|
416
|
-
</body>
|
|
417
|
-
</html>
|