navada-edge-cli 3.3.0 → 3.4.1

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.
@@ -0,0 +1,139 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const ui = require('../ui');
6
+ const config = require('../config');
7
+ const { getConversationHistory, clearHistory, addToHistory, sessionState } = require('../agent');
8
+
9
+ const CONV_DIR = path.join(config.CONFIG_DIR, 'conversations');
10
+
11
+ function ensureDir() {
12
+ if (!fs.existsSync(CONV_DIR)) fs.mkdirSync(CONV_DIR, { recursive: true });
13
+ }
14
+
15
+ function slugify(name) {
16
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 60);
17
+ }
18
+
19
+ function listSaved() {
20
+ ensureDir();
21
+ const files = fs.readdirSync(CONV_DIR).filter(f => f.endsWith('.json'));
22
+ return files.map(f => {
23
+ try {
24
+ const data = JSON.parse(fs.readFileSync(path.join(CONV_DIR, f), 'utf-8'));
25
+ return {
26
+ file: f,
27
+ name: data.name || f.replace('.json', ''),
28
+ messages: data.messages?.length || 0,
29
+ provider: data.provider || 'unknown',
30
+ saved: data.savedAt || '',
31
+ };
32
+ } catch {
33
+ return { file: f, name: f.replace('.json', ''), messages: 0, provider: '?', saved: '' };
34
+ }
35
+ }).sort((a, b) => b.saved.localeCompare(a.saved));
36
+ }
37
+
38
+ module.exports = function(reg) {
39
+
40
+ reg('save', 'Save current conversation', (args) => {
41
+ const history = getConversationHistory();
42
+ if (history.length === 0) {
43
+ console.log(ui.warn('No conversation to save.'));
44
+ return;
45
+ }
46
+
47
+ const name = args.join(' ') || `session-${new Date().toISOString().slice(0, 16).replace(/[T:]/g, '-')}`;
48
+ const slug = slugify(name);
49
+ ensureDir();
50
+
51
+ const data = {
52
+ name,
53
+ provider: sessionState.provider,
54
+ model: sessionState.model,
55
+ messages: history,
56
+ messageCount: history.length,
57
+ tokens: sessionState.tokens,
58
+ savedAt: new Date().toISOString(),
59
+ };
60
+
61
+ const filePath = path.join(CONV_DIR, `${slug}.json`);
62
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
63
+ console.log(ui.success(`Conversation saved: ${name}`));
64
+ console.log(ui.label('Messages', String(history.length)));
65
+ console.log(ui.label('File', filePath));
66
+ console.log(ui.dim('Load it later: /load ' + slug));
67
+ }, { category: 'AI' });
68
+
69
+ reg('load', 'Load a saved conversation', (args) => {
70
+ const name = args.join(' ');
71
+ if (!name) {
72
+ console.log(ui.dim('Usage: /load <name>'));
73
+ console.log(ui.dim('List saved: /conversations'));
74
+ return;
75
+ }
76
+
77
+ ensureDir();
78
+ const slug = slugify(name);
79
+ const filePath = path.join(CONV_DIR, `${slug}.json`);
80
+
81
+ if (!fs.existsSync(filePath)) {
82
+ // Try partial match
83
+ const files = fs.readdirSync(CONV_DIR).filter(f => f.includes(slug) && f.endsWith('.json'));
84
+ if (files.length === 0) {
85
+ console.log(ui.error(`No saved conversation matching: ${name}`));
86
+ console.log(ui.dim('List saved: /conversations'));
87
+ return;
88
+ }
89
+ // Use first match
90
+ const matchPath = path.join(CONV_DIR, files[0]);
91
+ return loadConversation(matchPath);
92
+ }
93
+
94
+ loadConversation(filePath);
95
+ }, { category: 'AI' });
96
+
97
+ reg('conversations', 'List saved conversations', () => {
98
+ const saved = listSaved();
99
+ console.log(ui.header('SAVED CONVERSATIONS'));
100
+
101
+ if (saved.length === 0) {
102
+ console.log(ui.dim('No saved conversations yet.'));
103
+ console.log(ui.dim('Save one: /save my-project-chat'));
104
+ return;
105
+ }
106
+
107
+ for (const s of saved) {
108
+ const date = s.saved ? s.saved.slice(0, 10) : '?';
109
+ console.log(ui.label(
110
+ s.name.slice(0, 28).padEnd(28),
111
+ `${s.messages} msgs ${s.provider} ${date}`
112
+ ));
113
+ }
114
+
115
+ console.log('');
116
+ console.log(ui.dim(`${saved.length} conversations saved`));
117
+ console.log(ui.dim('Load: /load <name> | Delete: /conversations rm <name>'));
118
+ }, { category: 'AI', aliases: ['convos'], subs: ['rm'] });
119
+
120
+ function loadConversation(filePath) {
121
+ try {
122
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
123
+ clearHistory();
124
+
125
+ for (const msg of data.messages || []) {
126
+ addToHistory(msg.role, msg.content);
127
+ }
128
+
129
+ console.log(ui.success(`Loaded: ${data.name}`));
130
+ console.log(ui.label('Messages', String(data.messages?.length || 0)));
131
+ console.log(ui.label('Provider', data.provider || 'unknown'));
132
+ console.log(ui.label('Saved', data.savedAt?.slice(0, 16) || '?'));
133
+ console.log('');
134
+ console.log(ui.dim('Conversation context restored. Continue chatting.'));
135
+ } catch (e) {
136
+ console.log(ui.error(`Failed to load: ${e.message}`));
137
+ }
138
+ }
139
+ };
@@ -6,7 +6,7 @@ const { register } = require('../registry');
6
6
  const moduleNames = [
7
7
  'network', 'mcp', 'lucas', 'docker', 'database', 'cloudflare',
8
8
  'ai', 'azure', 'agents', 'tasks', 'keys', 'setup', 'system',
9
- 'learn', 'sandbox', 'nvidia', 'edge',
9
+ 'learn', 'sandbox', 'nvidia', 'edge', 'conversations',
10
10
  ];
11
11
 
12
12
  function loadAll() {
@@ -71,6 +71,7 @@ module.exports = function(reg) {
71
71
  console.log(ui.dim('Accepts:'));
72
72
  console.log(ui.dim(' sk-ant-... Anthropic (full agent + tool use)'));
73
73
  console.log(ui.dim(' sk-... OpenAI (GPT-4o)'));
74
+ console.log(ui.dim(' AIza... Google Gemini (gemini-2.0-flash — FREE)'));
74
75
  console.log(ui.dim(' nvapi-... NVIDIA (Llama, Mistral, DeepSeek — FREE)'));
75
76
  console.log(ui.dim(' nv_edge_... NAVADA Edge (MCP + Dashboard)'));
76
77
  console.log(ui.dim(' hf_... HuggingFace (Qwen Coder — FREE)'));
@@ -82,6 +83,10 @@ module.exports = function(reg) {
82
83
  if (key.startsWith('sk-ant')) {
83
84
  config.set('anthropicKey', key);
84
85
  console.log(ui.success('Anthropic key saved — full agent mode with tool use enabled'));
86
+ } else if (key.startsWith('AIza')) {
87
+ config.set('geminiKey', key);
88
+ console.log(ui.success('Google Gemini key saved — gemini-2.0-flash enabled (FREE)'));
89
+ console.log(ui.dim('/model gemini to use | Get key: aistudio.google.com'));
85
90
  } else if (key.startsWith('nvapi-')) {
86
91
  config.set('nvidiaKey', key);
87
92
  console.log(ui.success('NVIDIA key saved — Llama, Mistral, DeepSeek, Gemma enabled'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "navada-edge-cli",
3
- "version": "3.3.0",
3
+ "version": "3.4.1",
4
4
  "description": "Interactive CLI for the NAVADA Edge Network — explore nodes, agents, Cloudflare, AI, Docker, and MCP from your terminal",
5
5
  "main": "lib/cli.js",
6
6
  "bin": {
@@ -58,7 +58,7 @@
58
58
  "lib/",
59
59
  "README.md",
60
60
  "LICENSE",
61
- "network.svg",
61
+ "architecture.svg",
62
62
  "Dockerfile",
63
63
  "docker-compose.yml"
64
64
  ]
package/network.svg DELETED
@@ -1,207 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 720" font-family="'SF Mono','Cascadia Code','Courier New',monospace">
2
- <defs>
3
- <style>
4
- .bg { fill: #050505; }
5
- .card { fill: #0a0a0a; stroke: #1a1a1a; stroke-width: 1; }
6
- .card-hdr { fill: #0f0f0f; }
7
- .t-title { fill: #fff; font-size: 20px; font-weight: 700; letter-spacing: 3px; }
8
- .t-sub { fill: #555; font-size: 10px; letter-spacing: 1.5px; }
9
- .t-label { fill: #555; font-size: 8px; letter-spacing: 1px; text-transform: uppercase; }
10
- .t-name { fill: #fff; font-size: 11px; font-weight: 600; }
11
- .t-role { fill: #666; font-size: 9px; }
12
- .t-svc { fill: #bbb; font-size: 9px; }
13
- .t-port { fill: #555; font-size: 9px; }
14
- .t-ip { fill: #444; font-size: 8px; }
15
- .t-count { fill: #555; font-size: 8px; }
16
- .t-pill { fill: #e0e0e0; font-size: 10px; }
17
- .t-pill-sub { fill: #555; font-size: 8px; }
18
- .t-footer { fill: #333; font-size: 9px; letter-spacing: 0.5px; }
19
- .dot-on { fill: #22c55e; }
20
- .dot-off { fill: #444; }
21
- .line-v { stroke: #1a1a1a; stroke-width: 1; }
22
- .line-accent { stroke: #fff; stroke-width: 2; }
23
- .line-dim { stroke: #333; stroke-width: 2; }
24
- .line-dark { stroke: #222; stroke-width: 2; }
25
- .badge { fill: none; stroke: #222; stroke-width: 1; }
26
- .badge-text { fill: #666; font-size: 7px; letter-spacing: 0.5px; }
27
- .pill-box { fill: none; stroke: #1a1a1a; stroke-width: 1; }
28
- .mesh-bar { fill: #080808; stroke: #1a1a1a; stroke-width: 1; }
29
- .arrow { fill: #222; }
30
- </style>
31
- </defs>
32
-
33
- <!-- Background -->
34
- <rect width="900" height="720" class="bg"/>
35
-
36
- <!-- Title -->
37
- <text x="450" y="36" text-anchor="middle" class="t-title">NAVADA EDGE NETWORK</text>
38
- <text x="450" y="52" text-anchor="middle" class="t-sub">Distributed AI Infrastructure</text>
39
-
40
- <!-- Mesh Bar -->
41
- <rect x="40" y="68" width="820" height="36" rx="0" class="mesh-bar"/>
42
- <text x="140" y="82" class="t-label">VPN</text>
43
- <text x="140" y="95" class="t-svc">Tailscale WireGuard</text>
44
- <text x="370" y="82" class="t-label">TUNNEL</text>
45
- <text x="370" y="95" class="t-svc">Cloudflare *.navada-edge-server.uk</text>
46
- <text x="680" y="82" class="t-label">REGISTRY</text>
47
- <text x="680" y="95" class="t-svc">Private Docker :5000</text>
48
-
49
- <!-- Arrow -->
50
- <line x1="450" y1="104" x2="450" y2="118" class="line-v"/>
51
- <polygon points="447,118 453,118 450,124" class="arrow"/>
52
-
53
- <!-- ==================== 4 NODES ==================== -->
54
- <text x="48" y="140" class="t-label">NODES</text>
55
-
56
- <!-- ASUS -->
57
- <rect x="40" y="148" width="200" height="184" class="card"/>
58
- <rect x="40" y="148" width="200" height="26" class="card-hdr"/>
59
- <rect x="40" y="148" width="3" height="26" class="line-accent" style="stroke:none;fill:#fff"/>
60
- <circle cx="228" cy="161" r="3" class="dot-on"/>
61
- <text x="52" y="163" class="t-name">ASUS Zenbook</text>
62
- <text x="52" y="172" class="t-role">Production Engine</text>
63
- <text x="210" y="172" text-anchor="end" class="t-ip">7 containers</text>
64
- <text x="52" y="192" class="t-svc">MCP Server</text><text x="228" y="192" text-anchor="end" class="t-port">:8811</text>
65
- <line x1="52" y1="197" x2="228" y2="197" style="stroke:#111;stroke-width:0.5"/>
66
- <text x="52" y="209" class="t-svc">Command Dashboard</text><text x="228" y="209" text-anchor="end" class="t-port">:7900</text>
67
- <line x1="52" y1="214" x2="228" y2="214" style="stroke:#111;stroke-width:0.5"/>
68
- <text x="52" y="226" class="t-svc">Docker Registry</text><text x="228" y="226" text-anchor="end" class="t-port">:5000</text>
69
- <line x1="52" y1="231" x2="228" y2="231" style="stroke:#111;stroke-width:0.5"/>
70
- <text x="52" y="243" class="t-svc">OpenCode</text><text x="228" y="243" text-anchor="end" class="t-port">:3200</text>
71
- <line x1="52" y1="248" x2="228" y2="248" style="stroke:#111;stroke-width:0.5"/>
72
- <text x="52" y="260" class="t-svc">Portainer Agent</text><text x="228" y="260" text-anchor="end" class="t-port">:9001</text>
73
- <line x1="52" y1="265" x2="228" y2="265" style="stroke:#111;stroke-width:0.5"/>
74
- <text x="52" y="277" class="t-svc">Builder + Sandbox</text><text x="228" y="277" text-anchor="end" class="t-port">:4000 :3100</text>
75
-
76
- <!-- EC2 -->
77
- <rect x="250" y="148" width="200" height="184" class="card"/>
78
- <rect x="250" y="148" width="200" height="26" class="card-hdr"/>
79
- <rect x="250" y="148" width="3" height="26" style="fill:#666"/>
80
- <circle cx="438" cy="161" r="3" class="dot-on"/>
81
- <text x="262" y="163" class="t-name">AWS EC2</text>
82
- <text x="262" y="172" class="t-role">Monitoring + Bots</text>
83
- <text x="420" y="172" text-anchor="end" class="t-ip">8 containers</text>
84
- <text x="262" y="192" class="t-svc">Telegram Bot (Claude)</text><text x="438" y="192" text-anchor="end" class="t-port">:3456</text>
85
- <line x1="262" y1="197" x2="438" y2="197" style="stroke:#111;stroke-width:0.5"/>
86
- <text x="262" y="209" class="t-svc">Lucas CTO MCP</text><text x="438" y="209" text-anchor="end" class="t-port">:8820</text>
87
- <line x1="262" y1="214" x2="438" y2="214" style="stroke:#111;stroke-width:0.5"/>
88
- <text x="262" y="226" class="t-svc">Health Monitor</text><text x="438" y="226" text-anchor="end" class="t-port">24/7</text>
89
- <line x1="262" y1="231" x2="438" y2="231" style="stroke:#111;stroke-width:0.5"/>
90
- <text x="262" y="243" class="t-svc">OpenCode + Dashboard</text><text x="438" y="243" text-anchor="end" class="t-port">:3200 :9090</text>
91
- <line x1="262" y1="248" x2="438" y2="248" style="stroke:#111;stroke-width:0.5"/>
92
- <text x="262" y="260" class="t-svc">WorldMonitor + E2E</text><text x="438" y="260" text-anchor="end" class="t-port">:4000</text>
93
- <line x1="262" y1="265" x2="438" y2="265" style="stroke:#111;stroke-width:0.5"/>
94
- <text x="262" y="277" class="t-svc">Portainer Agent</text><text x="438" y="277" text-anchor="end" class="t-port">:9001</text>
95
-
96
- <!-- Oracle -->
97
- <rect x="460" y="148" width="200" height="184" class="card"/>
98
- <rect x="460" y="148" width="200" height="26" class="card-hdr"/>
99
- <rect x="460" y="148" width="3" height="26" style="fill:#444"/>
100
- <circle cx="648" cy="161" r="3" class="dot-on"/>
101
- <text x="472" y="163" class="t-name">Oracle Cloud</text>
102
- <text x="472" y="172" class="t-role">Docker Infrastructure</text>
103
- <text x="630" y="172" text-anchor="end" class="t-ip">8 containers</text>
104
- <text x="472" y="192" class="t-svc">Portainer</text><text x="648" y="192" text-anchor="end" class="t-port">:9000</text>
105
- <line x1="472" y1="197" x2="648" y2="197" style="stroke:#111;stroke-width:0.5"/>
106
- <text x="472" y="209" class="t-svc">Cloudflare Tunnel</text><text x="648" y="209" text-anchor="end" class="t-port">origin</text>
107
- <line x1="472" y1="214" x2="648" y2="214" style="stroke:#111;stroke-width:0.5"/>
108
- <text x="472" y="226" class="t-svc">Grafana + Prometheus</text><text x="648" y="226" text-anchor="end" class="t-port">:3000 :9090</text>
109
- <line x1="472" y1="231" x2="648" y2="231" style="stroke:#111;stroke-width:0.5"/>
110
- <text x="472" y="243" class="t-svc">Uptime Kuma</text><text x="648" y="243" text-anchor="end" class="t-port">:3001</text>
111
- <line x1="472" y1="248" x2="648" y2="248" style="stroke:#111;stroke-width:0.5"/>
112
- <text x="472" y="260" class="t-svc">CloudBeaver</text><text x="648" y="260" text-anchor="end" class="t-port">:8978</text>
113
- <line x1="472" y1="265" x2="648" y2="265" style="stroke:#111;stroke-width:0.5"/>
114
- <text x="472" y="277" class="t-svc">Nginx Proxy</text><text x="648" y="277" text-anchor="end" class="t-port">:80/443</text>
115
-
116
- <!-- HP -->
117
- <rect x="670" y="148" width="190" height="108" class="card"/>
118
- <rect x="670" y="148" width="190" height="26" class="card-hdr"/>
119
- <rect x="670" y="148" width="3" height="26" style="fill:#333"/>
120
- <circle cx="848" cy="161" r="3" class="dot-on"/>
121
- <text x="682" y="163" class="t-name">HP EliteBook</text>
122
- <text x="682" y="172" class="t-role">Database Node</text>
123
- <text x="838" y="172" text-anchor="end" class="t-ip">2 containers</text>
124
- <text x="682" y="192" class="t-svc">PostgreSQL 17</text><text x="848" y="192" text-anchor="end" class="t-port">:5433</text>
125
- <line x1="682" y1="197" x2="848" y2="197" style="stroke:#111;stroke-width:0.5"/>
126
- <text x="682" y="209" class="t-svc">OpenCode</text><text x="848" y="209" text-anchor="end" class="t-port">:3200</text>
127
- <line x1="682" y1="214" x2="848" y2="214" style="stroke:#111;stroke-width:0.5"/>
128
- <text x="682" y="226" class="t-svc">Portainer Agent</text><text x="848" y="226" text-anchor="end" class="t-port">:9001</text>
129
-
130
- <!-- ==================== CLOUD ==================== -->
131
- <text x="48" y="352" class="t-label">CLOUD SERVICES</text>
132
-
133
- <!-- Cloudflare -->
134
- <rect x="40" y="360" width="280" height="120" class="card"/>
135
- <rect x="40" y="360" width="280" height="24" class="card-hdr"/>
136
- <text x="52" y="375" class="t-name">Cloudflare</text>
137
- <text x="160" y="375" class="t-role">CDN + Storage + AI</text>
138
- <rect x="280" y="364" width="32" height="14" class="badge"/><text x="296" y="374" text-anchor="middle" class="badge-text">EDGE</text>
139
- <text x="52" y="398" class="t-svc">R2 Object Storage</text>
140
- <text x="52" y="412" class="t-svc">Flux Image Gen (FREE)</text>
141
- <text x="52" y="426" class="t-svc">Stream Video CDN</text>
142
- <text x="52" y="440" class="t-svc">Tunnel (11 subdomains)</text>
143
- <text x="52" y="454" class="t-svc">DNS + WAF Trace</text>
144
- <text x="308" y="398" text-anchor="end" class="t-port">navada-assets</text>
145
- <text x="308" y="412" text-anchor="end" class="t-port">Workers AI</text>
146
- <text x="308" y="426" text-anchor="end" class="t-port">HLS</text>
147
- <text x="308" y="440" text-anchor="end" class="t-port">*.navada-edge-server.uk</text>
148
-
149
- <!-- AI Services -->
150
- <rect x="330" y="360" width="280" height="120" class="card"/>
151
- <rect x="330" y="360" width="280" height="24" class="card-hdr"/>
152
- <text x="342" y="375" class="t-name">AI Services</text>
153
- <text x="440" y="375" class="t-role">Inference + Generation</text>
154
- <rect x="570" y="364" width="32" height="14" class="badge"/><text x="586" y="374" text-anchor="middle" class="badge-text">API</text>
155
- <text x="342" y="398" class="t-svc">YOLO v8 Detection</text><text x="598" y="398" text-anchor="end" class="t-port">ASUS :8765</text>
156
- <text x="342" y="412" class="t-svc">Qwen Coder 32B</text><text x="598" y="412" text-anchor="end" class="t-port">FREE (HuggingFace)</text>
157
- <text x="342" y="426" class="t-svc">GPT-4o / DALL-E 3</text><text x="598" y="426" text-anchor="end" class="t-port">OpenAI</text>
158
- <text x="342" y="440" class="t-svc">Claude Sonnet 4</text><text x="598" y="440" text-anchor="end" class="t-port">Anthropic</text>
159
- <text x="342" y="454" class="t-svc">Flux (FREE)</text><text x="598" y="454" text-anchor="end" class="t-port">Cloudflare Workers</text>
160
-
161
- <!-- Azure -->
162
- <rect x="620" y="360" width="240" height="60" class="card"/>
163
- <rect x="620" y="360" width="240" height="24" class="card-hdr"/>
164
- <text x="632" y="375" class="t-name">Azure</text>
165
- <text x="700" y="375" class="t-role">Automation</text>
166
- <rect x="822" y="364" width="30" height="14" class="badge"/><text x="837" y="374" text-anchor="middle" class="badge-text">UK</text>
167
- <text x="632" y="398" class="t-svc">n8n Workflows (Container Apps)</text>
168
-
169
- <!-- ==================== AGENTS ==================== -->
170
- <text x="48" y="502" class="t-label">AGENTS</text>
171
-
172
- <rect x="40" y="510" width="410" height="56" class="card"/>
173
- <rect x="40" y="510" width="410" height="24" class="card-hdr"/>
174
- <text x="52" y="525" class="t-name">Lucas CTO</text>
175
- <text x="160" y="525" class="t-role">EC2 :8820 — 8 tools</text>
176
- <text x="52" y="548" class="t-svc">bash ssh docker_exec deploy read_file write_file list_files network_status</text>
177
-
178
- <rect x="460" y="510" width="400" height="56" class="card"/>
179
- <rect x="460" y="510" width="400" height="24" class="card-hdr"/>
180
- <text x="472" y="525" class="t-name">Claude CoS</text>
181
- <text x="580" y="525" class="t-role">EC2 :3456 — Chief of Staff</text>
182
- <text x="472" y="548" class="t-svc">email image_gen SMS voice R2 research automation cost_tracking</text>
183
-
184
- <!-- ==================== ACCESS ==================== -->
185
- <text x="48" y="590" class="t-label">ACCESS THE NETWORK</text>
186
-
187
- <rect x="40" y="598" width="820" height="52" class="card"/>
188
- <rect x="80" y="610" width="150" height="28" class="pill-box"/>
189
- <text x="155" y="625" text-anchor="middle" class="t-pill">SDK</text>
190
- <text x="155" y="634" text-anchor="middle" class="t-pill-sub">npm i navada-edge-sdk</text>
191
-
192
- <rect x="250" y="610" width="150" height="28" class="pill-box"/>
193
- <text x="325" y="625" text-anchor="middle" class="t-pill">CLI</text>
194
- <text x="325" y="634" text-anchor="middle" class="t-pill-sub">npm i -g navada-edge-cli</text>
195
-
196
- <rect x="420" y="610" width="150" height="28" class="pill-box"/>
197
- <text x="495" y="625" text-anchor="middle" class="t-pill">MCP</text>
198
- <text x="495" y="634" text-anchor="middle" class="t-pill-sub">POST /mcp (JSON-RPC)</text>
199
-
200
- <rect x="590" y="610" width="150" height="28" class="pill-box"/>
201
- <text x="665" y="625" text-anchor="middle" class="t-pill">Docker</text>
202
- <text x="665" y="634" text-anchor="middle" class="t-pill-sub">docker pull navada-edge-cli</text>
203
-
204
- <!-- Footer -->
205
- <rect x="40" y="664" width="820" height="30" class="card"/>
206
- <text x="450" y="684" text-anchor="middle" class="t-footer">NAVADA EDGE NETWORK — 4 Nodes | 25 Containers | 100% Docker | 2 AI Agents | 5 AI Models | MIT Open Source</text>
207
- </svg>