nexo-brain 5.3.13 → 5.3.15

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 (230) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/bin/nexo-brain.js +52 -1
  3. package/package.json +1 -1
  4. package/src/crons/sync.py +18 -4
  5. package/src/dashboard/static/favicon 2.svg +32 -0
  6. package/src/dashboard/static/nexo-logo 2.png +0 -0
  7. package/src/dashboard/static/nexo-logo 2.svg +40 -0
  8. package/src/dashboard/static/style 2.css +2458 -0
  9. package/src/dashboard/templates/adaptive 2.html +118 -0
  10. package/src/dashboard/templates/artifacts 2.html +133 -0
  11. package/src/dashboard/templates/backups 2.html +136 -0
  12. package/src/dashboard/templates/base 2.html +417 -0
  13. package/src/dashboard/templates/calendar 2.html +591 -0
  14. package/src/dashboard/templates/chat 2.html +356 -0
  15. package/src/dashboard/templates/claims 2.html +259 -0
  16. package/src/dashboard/templates/cortex 2.html +321 -0
  17. package/src/dashboard/templates/credentials 2.html +128 -0
  18. package/src/dashboard/templates/crons 2.html +370 -0
  19. package/src/dashboard/templates/dashboard 2.html +494 -0
  20. package/src/dashboard/templates/dreams 2.html +252 -0
  21. package/src/dashboard/templates/email 2.html +160 -0
  22. package/src/dashboard/templates/evolution 2.html +189 -0
  23. package/src/dashboard/templates/feed 2.html +249 -0
  24. package/src/dashboard/templates/followup_health 2.html +170 -0
  25. package/src/dashboard/templates/graph 2.html +201 -0
  26. package/src/dashboard/templates/guard 2.html +259 -0
  27. package/src/dashboard/templates/inbox 2.html +251 -0
  28. package/src/dashboard/templates/memory 2.html +420 -0
  29. package/src/dashboard/templates/operations 2.html +608 -0
  30. package/src/dashboard/templates/plugins 2.html +185 -0
  31. package/src/dashboard/templates/protocol 2.html +199 -0
  32. package/src/dashboard/templates/rules 2.html +246 -0
  33. package/src/dashboard/templates/sentiment 2.html +247 -0
  34. package/src/dashboard/templates/sessions 2.html +218 -0
  35. package/src/dashboard/templates/skills 2.html +329 -0
  36. package/src/dashboard/templates/somatic 2.html +73 -0
  37. package/src/dashboard/templates/triggers 2.html +133 -0
  38. package/src/dashboard/templates/trust 2.html +360 -0
  39. package/src/db/__init__ 2.py +259 -0
  40. package/src/db/_core 2.py +437 -0
  41. package/src/db/_credentials 2.py +124 -0
  42. package/src/db/_entities.py +1 -1
  43. package/src/db/_episodic 2.py +762 -0
  44. package/src/db/_evolution 2.py +54 -0
  45. package/src/db/_fts 2.py +406 -0
  46. package/src/db/_goal_profiles 2.py +376 -0
  47. package/src/db/_hot_context 2.py +660 -0
  48. package/src/db/_outcomes 2.py +800 -0
  49. package/src/db/_personal_scripts 2.py +582 -0
  50. package/src/db/_sessions 2.py +330 -0
  51. package/src/db/_tasks 2.py +91 -0
  52. package/src/db/_watchers 2.py +173 -0
  53. package/src/doctor/formatters 2.py +52 -0
  54. package/src/doctor/models 2.py +69 -0
  55. package/src/doctor/planes 2.py +87 -0
  56. package/src/doctor/providers/__init__ 2.py +1 -0
  57. package/src/doctor/providers/deep 2.py +367 -0
  58. package/src/evolution_cycle 2.py +519 -0
  59. package/src/hooks/auto_capture 2.py +208 -0
  60. package/src/hooks/caffeinate-guard 2.sh +8 -0
  61. package/src/hooks/capture-session 2.sh +21 -0
  62. package/src/hooks/capture-tool-logs 2.sh +158 -0
  63. package/src/hooks/daily-briefing-check 2.sh +33 -0
  64. package/src/hooks/heartbeat-enforcement 2.py +90 -0
  65. package/src/hooks/heartbeat-posttool 2.sh +18 -0
  66. package/src/hooks/inbox-hook 2.sh +76 -0
  67. package/src/hooks/post-compact 2.sh +152 -0
  68. package/src/hooks/pre-compact 2.sh +169 -0
  69. package/src/hooks/protocol-guardrail 2.sh +10 -0
  70. package/src/hooks/protocol-pretool-guardrail 2.sh +9 -0
  71. package/src/hooks/session-stop 2.sh +52 -0
  72. package/src/kg_populate 2.py +292 -0
  73. package/src/maintenance 2.py +53 -0
  74. package/src/memory_backends 2.py +71 -0
  75. package/src/migrate_embeddings 2.py +124 -0
  76. package/src/nexo_sdk 2.py +103 -0
  77. package/src/observability 2.py +199 -0
  78. package/src/plugin_loader 2.py +217 -0
  79. package/src/plugins/__init__ 2.py +0 -0
  80. package/src/plugins/agents.py +10 -3
  81. package/src/plugins/artifact_registry 2.py +450 -0
  82. package/src/plugins/backup 2.py +127 -0
  83. package/src/plugins/claims_tools 2.py +119 -0
  84. package/src/plugins/cognitive_memory 2.py +609 -0
  85. package/src/plugins/core_rules 2.py +252 -0
  86. package/src/plugins/cortex 2.py +1155 -0
  87. package/src/plugins/entities 2.py +67 -0
  88. package/src/plugins/episodic_memory 2.py +560 -0
  89. package/src/plugins/evolution 2.py +167 -0
  90. package/src/plugins/goal_engine 2.py +142 -0
  91. package/src/plugins/guard 2.py +862 -0
  92. package/src/plugins/impact 2.py +29 -0
  93. package/src/plugins/knowledge_graph_tools 2.py +137 -0
  94. package/src/plugins/media_memory_tools 2.py +98 -0
  95. package/src/plugins/memory_export 2.py +196 -0
  96. package/src/plugins/outcomes 2.py +130 -0
  97. package/src/plugins/personal_scripts 2.py +117 -0
  98. package/src/plugins/preferences 2.py +47 -0
  99. package/src/plugins/protocol 2.py +1449 -0
  100. package/src/plugins/schedule.py +2 -1
  101. package/src/plugins/simple_api 2.py +106 -0
  102. package/src/plugins/skills 2.py +341 -0
  103. package/src/plugins/state_watchers 2.py +79 -0
  104. package/src/plugins/update 2.py +986 -0
  105. package/src/plugins/user_state_tools 2.py +43 -0
  106. package/src/plugins/workflow 2.py +588 -0
  107. package/src/protocol_settings 2.py +59 -0
  108. package/src/public_contribution 2.py +466 -0
  109. package/src/public_evolution_queue 2.py +241 -0
  110. package/src/requirements 2.txt +14 -0
  111. package/src/requirements.txt +1 -1
  112. package/src/retroactive_learnings 2.py +373 -0
  113. package/src/rules/__init__ 2.py +0 -0
  114. package/src/rules/core-rules 2.json +331 -0
  115. package/src/rules/migrate 2.py +207 -0
  116. package/src/runtime_power 2.py +874 -0
  117. package/src/runtime_power.py +18 -1
  118. package/src/script_registry 2.py +1559 -0
  119. package/src/scripts/check-context 2.py +272 -0
  120. package/src/scripts/deep-sleep/apply_findings 2.py +2327 -0
  121. package/src/scripts/deep-sleep/collect 2.py +928 -0
  122. package/src/scripts/deep-sleep/extract 2.py +330 -0
  123. package/src/scripts/deep-sleep/extract-prompt 2.md +285 -0
  124. package/src/scripts/deep-sleep/synthesize 2.py +312 -0
  125. package/src/scripts/deep-sleep/synthesize-prompt 2.md +336 -0
  126. package/src/scripts/nexo-agent-run 2.py +75 -0
  127. package/src/scripts/nexo-auto-update 2.py +6 -0
  128. package/src/scripts/nexo-backup 2.sh +25 -0
  129. package/src/scripts/nexo-brain-activation 2.sh +140 -0
  130. package/src/scripts/nexo-catchup 2.py +300 -0
  131. package/src/scripts/nexo-cognitive-decay 2.py +257 -0
  132. package/src/scripts/nexo-cortex-cycle 2.py +293 -0
  133. package/src/scripts/nexo-cron-wrapper 2.sh +53 -0
  134. package/src/scripts/nexo-cron-wrapper.sh +7 -0
  135. package/src/scripts/nexo-daily-self-audit 2.py +2161 -0
  136. package/src/scripts/nexo-dashboard 2.sh +29 -0
  137. package/src/scripts/nexo-deep-sleep 2.sh +86 -0
  138. package/src/scripts/nexo-evolution-run 2.py +1664 -0
  139. package/src/scripts/nexo-followup-hygiene 2.py +139 -0
  140. package/src/scripts/nexo-hook-record 2.py +42 -0
  141. package/src/scripts/nexo-immune 2.py +936 -0
  142. package/src/scripts/nexo-impact-scorer 2.py +117 -0
  143. package/src/scripts/nexo-inbox-hook 2.sh +74 -0
  144. package/src/scripts/nexo-install 2.py +6 -0
  145. package/src/scripts/nexo-learning-housekeep 2.py +401 -0
  146. package/src/scripts/nexo-learning-validator 2.py +266 -0
  147. package/src/scripts/nexo-migrate 2.py +260 -0
  148. package/src/scripts/nexo-outcome-checker 2.py +127 -0
  149. package/src/scripts/nexo-postmortem-consolidator 2.py +456 -0
  150. package/src/scripts/nexo-pre-commit 2.py +120 -0
  151. package/src/scripts/nexo-prevent-sleep 2.sh +35 -0
  152. package/src/scripts/nexo-proactive-dashboard 2.py +354 -0
  153. package/src/scripts/nexo-reflection 2.py +256 -0
  154. package/src/scripts/nexo-runtime-preflight 2.py +274 -0
  155. package/src/scripts/nexo-sleep 2.py +631 -0
  156. package/src/scripts/nexo-snapshot-restore 2.sh +35 -0
  157. package/src/scripts/nexo-sync-clients 2.py +16 -0
  158. package/src/scripts/nexo-synthesis 2.py +475 -0
  159. package/src/scripts/nexo-tcc-approve 2.sh +79 -0
  160. package/src/scripts/nexo-update 2.sh +306 -0
  161. package/src/scripts/nexo-watchdog 2.sh +1207 -0
  162. package/src/scripts/nexo-watchdog-smoke 2.py +119 -0
  163. package/src/scripts/rehydrate_learnings_from_archive 2.py +245 -0
  164. package/src/server 2.py +1296 -0
  165. package/src/skills/run-nexo-audit-phase/guide 2.md +43 -0
  166. package/src/skills/run-nexo-audit-phase/skill 2.json +59 -0
  167. package/src/skills/run-nexo-core-fix-cycle/guide 2.md +17 -0
  168. package/src/skills/run-nexo-core-fix-cycle/script 2.py +276 -0
  169. package/src/skills/run-nexo-core-fix-cycle/skill 2.json +58 -0
  170. package/src/skills/run-release-final-audit/guide 2.md +16 -0
  171. package/src/skills/run-release-final-audit/script 2.py +259 -0
  172. package/src/skills/run-release-final-audit/skill 2.json +77 -0
  173. package/src/skills/run-runtime-doctor/guide 2.md +12 -0
  174. package/src/skills/run-runtime-doctor/script 2.py +21 -0
  175. package/src/skills/run-runtime-doctor/skill 2.json +25 -0
  176. package/src/skills_runtime 2.py +932 -0
  177. package/src/state_watchers_runtime 2.py +475 -0
  178. package/src/storage_router 2.py +32 -0
  179. package/src/system_catalog 2.py +786 -0
  180. package/src/tools_coordination 2.py +103 -0
  181. package/src/tools_credentials 2.py +68 -0
  182. package/src/tools_drive 2.py +487 -0
  183. package/src/tools_hot_context 2.py +163 -0
  184. package/src/tools_learnings 2.py +612 -0
  185. package/src/tools_menu 2.py +229 -0
  186. package/src/tools_reminders 2.py +88 -0
  187. package/src/tools_reminders_crud 2.py +363 -0
  188. package/src/tools_sessions 2.py +1054 -0
  189. package/src/tools_system_catalog 2.py +19 -0
  190. package/src/tools_task_history 2.py +57 -0
  191. package/src/tools_transcripts 2.py +98 -0
  192. package/src/transcript_utils 2.py +412 -0
  193. package/src/user_context 2.py +46 -0
  194. package/src/user_data_portability 2.py +328 -0
  195. package/src/user_state_model 2.py +170 -0
  196. package/templates/CLAUDE.md 2.template +108 -0
  197. package/templates/CODEX.AGENTS.md 2.template +66 -0
  198. package/templates/launchagents/README 2.md +132 -0
  199. package/templates/launchagents/com.nexo.auto-close-sessions 2.plist +39 -0
  200. package/templates/launchagents/com.nexo.auto-close-sessions.plist +1 -1
  201. package/templates/launchagents/com.nexo.catchup 2.plist +39 -0
  202. package/templates/launchagents/com.nexo.catchup.plist +1 -1
  203. package/templates/launchagents/com.nexo.cognitive-decay 2.plist +40 -0
  204. package/templates/launchagents/com.nexo.dashboard 2.plist +43 -0
  205. package/templates/launchagents/com.nexo.dashboard.plist +1 -1
  206. package/templates/launchagents/com.nexo.deep-sleep 2.plist +43 -0
  207. package/templates/launchagents/com.nexo.deep-sleep.plist +1 -1
  208. package/templates/launchagents/com.nexo.evolution 2.plist +44 -0
  209. package/templates/launchagents/com.nexo.evolution.plist +1 -1
  210. package/templates/launchagents/com.nexo.followup-hygiene 2.plist +45 -0
  211. package/templates/launchagents/com.nexo.followup-hygiene.plist +1 -1
  212. package/templates/launchagents/com.nexo.immune 2.plist +41 -0
  213. package/templates/launchagents/com.nexo.immune.plist +1 -1
  214. package/templates/launchagents/com.nexo.postmortem 2.plist +45 -0
  215. package/templates/launchagents/com.nexo.postmortem.plist +1 -1
  216. package/templates/launchagents/com.nexo.self-audit 2.plist +47 -0
  217. package/templates/launchagents/com.nexo.self-audit.plist +1 -1
  218. package/templates/launchagents/com.nexo.synthesis 2.plist +45 -0
  219. package/templates/launchagents/com.nexo.synthesis.plist +1 -1
  220. package/templates/launchagents/com.nexo.watchdog 2.plist +37 -0
  221. package/templates/launchagents/com.nexo.watchdog.plist +1 -1
  222. package/templates/nexo_helper 2.py +301 -0
  223. package/templates/openclaw 2.json +13 -0
  224. package/templates/plugin-template 2.py +40 -0
  225. package/templates/script-template 2.py +59 -0
  226. package/templates/script-template 2.sh +13 -0
  227. package/templates/script-template.py +5 -4
  228. package/templates/skill-script-template 2.py +48 -0
  229. package/templates/skill-script-template.py +2 -1
  230. package/templates/skill-template 2.md +33 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexo-brain",
3
- "version": "5.3.13",
3
+ "version": "5.3.15",
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
@@ -177,6 +177,54 @@ function getCoreRuntimePackages() {
177
177
  return ["db", "cognitive", "doctor"];
178
178
  }
179
179
 
180
+ function resolveLaunchAgentPath(home) {
181
+ const parts = ["/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/bin",
182
+ path.join(home, ".local/bin"), path.join(home, ".nexo/bin")];
183
+ // Detect nvm node
184
+ const nvmDir = path.join(home, ".nvm/versions/node");
185
+ try {
186
+ const versions = fs.readdirSync(nvmDir)
187
+ .map(v => ({ name: v, mtime: fs.statSync(path.join(nvmDir, v)).mtimeMs }))
188
+ .sort((a, b) => b.mtime - a.mtime);
189
+ for (const v of versions) {
190
+ const nodeBin = path.join(nvmDir, v.name, "bin");
191
+ if (fs.existsSync(path.join(nodeBin, "node"))) {
192
+ parts.unshift(nodeBin);
193
+ break;
194
+ }
195
+ }
196
+ } catch { /* nvm not installed — skip */ }
197
+ return parts.join(":");
198
+ }
199
+
200
+ function setupKeychainPassFile(nexoHome) {
201
+ if (process.platform !== "darwin") return;
202
+ const configDir = path.join(nexoHome, "config");
203
+ const passFile = path.join(configDir, ".keychain-pass");
204
+ if (fs.existsSync(passFile)) return; // already set up
205
+ fs.mkdirSync(configDir, { recursive: true });
206
+ log("");
207
+ log("macOS Keychain setup for headless automation:");
208
+ log(" Claude Code stores auth in the login Keychain, which auto-locks.");
209
+ log(" Background jobs need to unlock it. Enter your macOS login password");
210
+ log(" (stored locally in ~/.nexo/config/.keychain-pass, chmod 600).");
211
+ log("");
212
+ return new Promise((resolve) => {
213
+ const rl = require("readline").createInterface({ input: process.stdin, output: process.stdout });
214
+ rl.question(" macOS login password (or Enter to skip): ", (answer) => {
215
+ rl.close();
216
+ if (answer && answer.trim()) {
217
+ fs.writeFileSync(passFile, answer.trim(), { mode: 0o600 });
218
+ log(" Keychain password saved. Background jobs will auto-unlock.");
219
+ } else {
220
+ log(" Skipped. Background jobs may fail with 'Not logged in' if Keychain locks.");
221
+ log(" Run: echo 'YOUR_PASSWORD' > ~/.nexo/config/.keychain-pass && chmod 600 ~/.nexo/config/.keychain-pass");
222
+ }
223
+ resolve();
224
+ });
225
+ });
226
+ }
227
+
180
228
  function isProtectedMacPath(candidate) {
181
229
  if (process.platform !== "darwin" || !candidate) return false;
182
230
  const homeDir = require("os").homedir();
@@ -1250,7 +1298,7 @@ function installAllProcesses(platform, pythonPath, nexoHome, schedule, launchAge
1250
1298
  <key>NEXO_CODE</key>
1251
1299
  <string>${nexoCode}</string>
1252
1300
  <key>PATH</key>
1253
- <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
1301
+ <string>${resolveLaunchAgentPath(home)}</string>
1254
1302
  </dict>
1255
1303
  </dict>
1256
1304
  </plist>`;
@@ -2965,6 +3013,9 @@ ${doScan ? `- Stack: ${Object.keys(profileData.code.languages || {}).slice(0, 5)
2965
3013
  // Note: prevent-sleep and tcc-approve are now part of ALL_PROCESSES
2966
3014
  // and installed by installAllProcesses() above. No separate caffeinate block needed.
2967
3015
 
3016
+ // Step 7b: macOS Keychain setup for headless automation
3017
+ await setupKeychainPassFile(NEXO_HOME);
3018
+
2968
3019
  // Step 8: Create shell alias and add runtime CLI to PATH
2969
3020
  log("Creating shell alias...");
2970
3021
  const aliasName = operatorName.toLowerCase();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexo-brain",
3
- "version": "5.3.13",
3
+ "version": "5.3.15",
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",
package/src/crons/sync.py CHANGED
@@ -32,6 +32,23 @@ if str(_runtime_root) not in sys.path:
32
32
  sys.path.insert(0, str(_runtime_root))
33
33
 
34
34
  from cron_recovery import resolve_declared_schedule, should_run_at_load
35
+ try:
36
+ from runtime_power import resolve_launchagent_path
37
+ except ImportError:
38
+ def resolve_launchagent_path() -> str:
39
+ """Fallback when runtime_power is not importable."""
40
+ home = Path.home()
41
+ parts = ["/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/bin",
42
+ str(home / ".local/bin"), str(home / ".nexo/bin")]
43
+ nvm_dir = home / ".nvm/versions/node"
44
+ if nvm_dir.is_dir():
45
+ versions = sorted(nvm_dir.iterdir(), key=lambda p: p.stat().st_mtime, reverse=True)
46
+ for v in versions:
47
+ node_bin = v / "bin"
48
+ if (node_bin / "node").exists():
49
+ parts.insert(0, str(node_bin))
50
+ break
51
+ return ":".join(parts)
35
52
 
36
53
  NEXO_HOME = Path(os.environ.get("NEXO_HOME", str(Path.home() / ".nexo")))
37
54
  SOURCE_ROOT = Path(os.environ.get("NEXO_CODE", str(Path(__file__).resolve().parent.parent)))
@@ -221,10 +238,7 @@ def build_plist(cron: dict) -> dict:
221
238
  "StandardOutPath": str(LOG_DIR / f"{cron_id}-stdout.log"),
222
239
  "StandardErrorPath": str(LOG_DIR / f"{cron_id}-stderr.log"),
223
240
  "EnvironmentVariables": {
224
- "PATH": "/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin:"
225
- + str(Path.home() / ".local" / "bin") + ":"
226
- + str(Path.home() / ".nvm/versions/node/v22.14.0/bin") + ":"
227
- + "/Library/Frameworks/Python.framework/Versions/3.12/bin",
241
+ "PATH": resolve_launchagent_path(),
228
242
  "HOME": str(Path.home()),
229
243
  "NEXO_HOME": str(NEXO_HOME),
230
244
  "NEXO_CODE": str(RUNTIME_ROOT),
@@ -0,0 +1,32 @@
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>
@@ -0,0 +1,40 @@
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>