nexo-brain 5.3.15 → 5.3.16
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/bin/nexo-brain.js +28 -9
- package/package.json +1 -1
- package/src/client_preferences.py +26 -2
- 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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.16",
|
|
4
4
|
"description": "Local cognitive runtime for Claude Code \u2014 persistent memory, overnight learning, doctor diagnostics, personal scripts, recovery-aware jobs, startup preflight, and optional dashboard/power helper.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "NEXO Brain",
|
package/bin/nexo-brain.js
CHANGED
|
@@ -1765,12 +1765,21 @@ async function main() {
|
|
|
1765
1765
|
const templatesDest = path.join(NEXO_HOME, "templates");
|
|
1766
1766
|
if (fs.existsSync(templatesSrc)) {
|
|
1767
1767
|
fs.mkdirSync(templatesDest, { recursive: true });
|
|
1768
|
-
|
|
1768
|
+
for (const f of fs.readdirSync(templatesSrc)) {
|
|
1769
1769
|
const src = path.join(templatesSrc, f);
|
|
1770
|
-
|
|
1771
|
-
|
|
1770
|
+
const dest = path.join(templatesDest, f);
|
|
1771
|
+
if (fs.statSync(src).isFile()) {
|
|
1772
|
+
fs.copyFileSync(src, dest);
|
|
1773
|
+
} else if (fs.statSync(src).isDirectory()) {
|
|
1774
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
1775
|
+
for (const sf of fs.readdirSync(src)) {
|
|
1776
|
+
const ssrc = path.join(src, sf);
|
|
1777
|
+
if (fs.statSync(ssrc).isFile()) {
|
|
1778
|
+
fs.copyFileSync(ssrc, path.join(dest, sf));
|
|
1779
|
+
}
|
|
1780
|
+
}
|
|
1772
1781
|
}
|
|
1773
|
-
}
|
|
1782
|
+
}
|
|
1774
1783
|
}
|
|
1775
1784
|
|
|
1776
1785
|
logMacPermissionsNotice(NEXO_HOME, syncPython);
|
|
@@ -2434,13 +2443,23 @@ async function main() {
|
|
|
2434
2443
|
const templatesDest = path.join(NEXO_HOME, "templates");
|
|
2435
2444
|
fs.mkdirSync(templatesDest, { recursive: true });
|
|
2436
2445
|
if (fs.existsSync(templateDir)) {
|
|
2437
|
-
|
|
2446
|
+
// Copy all template files (not just a hardcoded subset)
|
|
2447
|
+
for (const f of fs.readdirSync(templateDir)) {
|
|
2438
2448
|
const src = path.join(templateDir, f);
|
|
2439
|
-
|
|
2440
|
-
|
|
2449
|
+
const dest = path.join(templatesDest, f);
|
|
2450
|
+
if (fs.statSync(src).isFile()) {
|
|
2451
|
+
fs.copyFileSync(src, dest);
|
|
2452
|
+
} else if (fs.statSync(src).isDirectory()) {
|
|
2453
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
2454
|
+
for (const sf of fs.readdirSync(src)) {
|
|
2455
|
+
const ssrc = path.join(src, sf);
|
|
2456
|
+
if (fs.statSync(ssrc).isFile()) {
|
|
2457
|
+
fs.copyFileSync(ssrc, path.join(dest, sf));
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2441
2460
|
}
|
|
2442
|
-
}
|
|
2443
|
-
log("
|
|
2461
|
+
}
|
|
2462
|
+
log(" All templates installed.");
|
|
2444
2463
|
}
|
|
2445
2464
|
|
|
2446
2465
|
// Hooks directory
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nexo-brain",
|
|
3
|
-
"version": "5.3.
|
|
3
|
+
"version": "5.3.16",
|
|
4
4
|
"mcpName": "io.github.wazionapps/nexo",
|
|
5
5
|
"description": "NEXO Brain — Shared brain for AI agents. Persistent memory, semantic RAG, natural forgetting, metacognitive guard, trust scoring, 150+ MCP tools. Works with Claude Code, Codex, Claude Desktop & any MCP client. 100% local, free.",
|
|
6
6
|
"homepage": "https://nexo-brain.com",
|
|
@@ -474,11 +474,35 @@ def _claude_desktop_config_path(home: Path) -> Path:
|
|
|
474
474
|
return home / ".config" / "Claude" / "claude_desktop_config.json"
|
|
475
475
|
|
|
476
476
|
|
|
477
|
+
def _which_with_nvm(name: str, home: Path | None = None) -> str:
|
|
478
|
+
"""Like shutil.which but also searches nvm and ~/.nexo/bin."""
|
|
479
|
+
found = shutil.which(name)
|
|
480
|
+
if found:
|
|
481
|
+
return found
|
|
482
|
+
home = home or _user_home()
|
|
483
|
+
# Check ~/.nexo/bin
|
|
484
|
+
candidate = home / ".nexo" / "bin" / name
|
|
485
|
+
if candidate.exists():
|
|
486
|
+
return str(candidate)
|
|
487
|
+
# Check nvm node bins
|
|
488
|
+
nvm_dir = home / ".nvm" / "versions" / "node"
|
|
489
|
+
if nvm_dir.is_dir():
|
|
490
|
+
try:
|
|
491
|
+
versions = sorted(nvm_dir.iterdir(), key=lambda p: p.stat().st_mtime, reverse=True)
|
|
492
|
+
for v in versions:
|
|
493
|
+
candidate = v / "bin" / name
|
|
494
|
+
if candidate.exists():
|
|
495
|
+
return str(candidate)
|
|
496
|
+
except OSError:
|
|
497
|
+
pass
|
|
498
|
+
return ""
|
|
499
|
+
|
|
500
|
+
|
|
477
501
|
def detect_installed_clients(user_home: str | os.PathLike[str] | None = None) -> dict[str, dict]:
|
|
478
502
|
home = Path(user_home).expanduser() if user_home else _user_home()
|
|
479
503
|
|
|
480
|
-
claude_bin = os.environ.get("CLAUDE_BIN", "").strip() or
|
|
481
|
-
codex_bin = os.environ.get("CODEX_BIN", "").strip() or
|
|
504
|
+
claude_bin = os.environ.get("CLAUDE_BIN", "").strip() or _which_with_nvm("claude", home)
|
|
505
|
+
codex_bin = os.environ.get("CODEX_BIN", "").strip() or _which_with_nvm("codex", home)
|
|
482
506
|
|
|
483
507
|
if sys.platform == "darwin":
|
|
484
508
|
desktop_app = next(
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="fg" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse">
|
|
4
|
-
<stop offset="0%" stop-color="#7C3AED"/>
|
|
5
|
-
<stop offset="100%" stop-color="#EC4899"/>
|
|
6
|
-
</linearGradient>
|
|
7
|
-
<linearGradient id="fgf" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse">
|
|
8
|
-
<stop offset="0%" stop-color="#7C3AED" stop-opacity="0.3"/>
|
|
9
|
-
<stop offset="100%" stop-color="#EC4899" stop-opacity="0.3"/>
|
|
10
|
-
</linearGradient>
|
|
11
|
-
</defs>
|
|
12
|
-
|
|
13
|
-
<!-- Background -->
|
|
14
|
-
<rect width="32" height="32" rx="7" fill="#0F0A1A"/>
|
|
15
|
-
|
|
16
|
-
<!-- Subtle neural lines -->
|
|
17
|
-
<line x1="8" y1="8" x2="24" y2="8" stroke="url(#fgf)" stroke-width="0.8"/>
|
|
18
|
-
<line x1="8" y1="24" x2="24" y2="24" stroke="url(#fgf)" stroke-width="0.8"/>
|
|
19
|
-
<line x1="8" y1="8" x2="24" y2="24" stroke="url(#fgf)" stroke-width="0.6"/>
|
|
20
|
-
|
|
21
|
-
<!-- N strokes -->
|
|
22
|
-
<line x1="8" y1="8" x2="8" y2="24" stroke="url(#fg)" stroke-width="3.5" stroke-linecap="round"/>
|
|
23
|
-
<line x1="8" y1="8" x2="24" y2="24" stroke="url(#fg)" stroke-width="3.5" stroke-linecap="round"/>
|
|
24
|
-
<line x1="24" y1="8" x2="24" y2="24" stroke="url(#fg)" stroke-width="3.5" stroke-linecap="round"/>
|
|
25
|
-
|
|
26
|
-
<!-- Nodes -->
|
|
27
|
-
<circle cx="8" cy="8" r="2.5" fill="url(#fg)"/>
|
|
28
|
-
<circle cx="24" cy="8" r="2.5" fill="url(#fg)"/>
|
|
29
|
-
<circle cx="8" cy="24" r="2.5" fill="url(#fg)"/>
|
|
30
|
-
<circle cx="24" cy="24" r="2.5" fill="url(#fg)"/>
|
|
31
|
-
<circle cx="16" cy="16" r="2" fill="#EC4899"/>
|
|
32
|
-
</svg>
|
|
Binary file
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
|
|
2
|
-
<defs>
|
|
3
|
-
<linearGradient id="grad" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse">
|
|
4
|
-
<stop offset="0%" stop-color="#7C3AED"/>
|
|
5
|
-
<stop offset="100%" stop-color="#EC4899"/>
|
|
6
|
-
</linearGradient>
|
|
7
|
-
<linearGradient id="gradFade" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse">
|
|
8
|
-
<stop offset="0%" stop-color="#7C3AED" stop-opacity="0.35"/>
|
|
9
|
-
<stop offset="100%" stop-color="#EC4899" stop-opacity="0.35"/>
|
|
10
|
-
</linearGradient>
|
|
11
|
-
</defs>
|
|
12
|
-
|
|
13
|
-
<!-- Dark background -->
|
|
14
|
-
<rect width="32" height="32" rx="7" fill="#0F0A1A"/>
|
|
15
|
-
|
|
16
|
-
<!-- Neural connection lines (subtle — behind the N strokes) -->
|
|
17
|
-
<line x1="7" y1="8" x2="25" y2="8" stroke="url(#gradFade)" stroke-width="0.7"/>
|
|
18
|
-
<line x1="7" y1="24" x2="25" y2="24" stroke="url(#gradFade)" stroke-width="0.7"/>
|
|
19
|
-
<line x1="7" y1="8" x2="25" y2="24" stroke="url(#gradFade)" stroke-width="0.5"/>
|
|
20
|
-
|
|
21
|
-
<!-- N — left vertical -->
|
|
22
|
-
<line x1="7" y1="8" x2="7" y2="24" stroke="url(#grad)" stroke-width="3" stroke-linecap="round"/>
|
|
23
|
-
<!-- N — diagonal crossbar -->
|
|
24
|
-
<line x1="7" y1="8" x2="25" y2="24" stroke="url(#grad)" stroke-width="3" stroke-linecap="round"/>
|
|
25
|
-
<!-- N — right vertical -->
|
|
26
|
-
<line x1="25" y1="8" x2="25" y2="24" stroke="url(#grad)" stroke-width="3" stroke-linecap="round"/>
|
|
27
|
-
|
|
28
|
-
<!-- Synaptic nodes at stroke endpoints -->
|
|
29
|
-
<circle cx="7" cy="8" r="2.3" fill="url(#grad)"/>
|
|
30
|
-
<circle cx="25" cy="8" r="2.3" fill="url(#grad)"/>
|
|
31
|
-
<circle cx="7" cy="24" r="2.3" fill="url(#grad)"/>
|
|
32
|
-
<circle cx="25" cy="24" r="2.3" fill="url(#grad)"/>
|
|
33
|
-
|
|
34
|
-
<!-- Centre node on diagonal midpoint -->
|
|
35
|
-
<circle cx="16" cy="16" r="2" fill="#EC4899"/>
|
|
36
|
-
|
|
37
|
-
<!-- Tiny satellite dots -->
|
|
38
|
-
<circle cx="16" cy="8" r="1.1" fill="#A78BFA" fill-opacity="0.6"/>
|
|
39
|
-
<circle cx="16" cy="24" r="1.1" fill="#F472B6" fill-opacity="0.6"/>
|
|
40
|
-
</svg>
|