meshsig 0.5.0

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,175 @@
1
+ // ============================================================================
2
+ // MeshSig — Terminal Live Display
3
+ // Beautiful real-time visualization of the mesh in your terminal.
4
+ // ============================================================================
5
+ const BOLD = '\x1b[1m';
6
+ const DIM = '\x1b[2m';
7
+ const RESET = '\x1b[0m';
8
+ const GREEN = '\x1b[32m';
9
+ const CYAN = '\x1b[36m';
10
+ const YELLOW = '\x1b[33m';
11
+ const MAGENTA = '\x1b[35m';
12
+ const RED = '\x1b[31m';
13
+ const BLUE = '\x1b[34m';
14
+ const WHITE = '\x1b[37m';
15
+ const BG_BLACK = '\x1b[40m';
16
+ export class TerminalDisplay {
17
+ agents = new Map();
18
+ connectionCount = 0;
19
+ messageCount = 0;
20
+ eventLog = [];
21
+ maxLogLines = 15;
22
+ refreshInterval = null;
23
+ startTime = Date.now();
24
+ start() {
25
+ // Refresh display every 2 seconds
26
+ this.refreshInterval = setInterval(() => this.render(), 2000);
27
+ }
28
+ stop() {
29
+ if (this.refreshInterval)
30
+ clearInterval(this.refreshInterval);
31
+ }
32
+ handleEvent(event) {
33
+ const d = event.data;
34
+ switch (event.type) {
35
+ case 'agent:register': {
36
+ this.agents.set(d.did, {
37
+ did: d.did,
38
+ name: d.name,
39
+ capabilities: (d.capabilities || []).map((c) => c.type),
40
+ connections: new Set(),
41
+ messagesSent: 0,
42
+ messagesReceived: 0,
43
+ lastActive: new Date(),
44
+ });
45
+ this.addLog(`${GREEN}●${RESET} ${BOLD}${d.name}${RESET} joined the mesh ${DIM}— ${(d.capabilities || []).map((c) => c.type).join(', ')}${RESET}`);
46
+ this.render();
47
+ break;
48
+ }
49
+ case 'connection:established': {
50
+ this.connectionCount++;
51
+ const a = this.agents.get(d.agentA.did);
52
+ const b = this.agents.get(d.agentB.did);
53
+ if (a)
54
+ a.connections.add(d.agentB.did);
55
+ if (b)
56
+ b.connections.add(d.agentA.did);
57
+ this.addLog(`${CYAN}◆${RESET} ${BOLD}${d.agentA.name}${RESET} ${DIM}↔${RESET} ${BOLD}${d.agentB.name}${RESET} ${DIM}— verified handshake${RESET}`);
58
+ this.render();
59
+ break;
60
+ }
61
+ case 'message:sent': {
62
+ this.messageCount++;
63
+ const from = this.agents.get(d.from.did);
64
+ const to = this.agents.get(d.to.did);
65
+ if (from) {
66
+ from.messagesSent++;
67
+ from.lastActive = new Date();
68
+ }
69
+ if (to) {
70
+ to.messagesReceived++;
71
+ to.lastActive = new Date();
72
+ }
73
+ const verified = d.verified ? `${GREEN}✓${RESET}` : `${RED}✗${RESET}`;
74
+ this.addLog(`${YELLOW}▸${RESET} ${BOLD}${d.from.name}${RESET} → ${BOLD}${d.to.name}${RESET} ${verified} ${DIM}"${d.preview.slice(0, 55)}"${RESET}`);
75
+ this.render();
76
+ break;
77
+ }
78
+ case 'handshake:verify': {
79
+ this.addLog(`${MAGENTA}⚡${RESET} ${DIM}Handshake:${RESET} ${d.fromName} ${DIM}↔${RESET} ${d.toName} ${GREEN}identity verified${RESET}`);
80
+ this.render();
81
+ break;
82
+ }
83
+ case 'discovery:query': {
84
+ this.addLog(`${BLUE}🔍${RESET} ${DIM}Discovery:${RESET} "${d.capability}" ${DIM}→ found ${d.results} agent(s)${RESET}`);
85
+ break;
86
+ }
87
+ case 'agent:heartbeat': break; // silent
88
+ }
89
+ }
90
+ addLog(line) {
91
+ this.eventLog.unshift(line);
92
+ if (this.eventLog.length > this.maxLogLines) {
93
+ this.eventLog.length = this.maxLogLines;
94
+ }
95
+ }
96
+ render() {
97
+ const agentList = [...this.agents.values()];
98
+ const uptime = Math.floor((Date.now() - this.startTime) / 1000);
99
+ const mins = Math.floor(uptime / 60);
100
+ const secs = uptime % 60;
101
+ // Build the network graph ASCII
102
+ let graph = this.buildGraph(agentList);
103
+ const output = [
104
+ '',
105
+ ` ${MAGENTA}${BOLD}MeshSig${RESET} ${DIM}— live network${RESET}`,
106
+ ` ${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`,
107
+ '',
108
+ ` ${WHITE}${BOLD}${agentList.length}${RESET} ${DIM}agents${RESET} ${CYAN}${BOLD}${this.connectionCount}${RESET} ${DIM}links${RESET} ${YELLOW}${BOLD}${this.messageCount}${RESET} ${DIM}messages${RESET} ${DIM}uptime ${mins}m${secs}s${RESET}`,
109
+ '',
110
+ graph,
111
+ '',
112
+ ` ${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}`,
113
+ ` ${DIM}LIVE EVENTS${RESET}`,
114
+ '',
115
+ ...this.eventLog.map(l => ` ${l}`),
116
+ '',
117
+ ` ${DIM}Dashboard: ${CYAN}http://localhost:4888${RESET}`,
118
+ ];
119
+ // Clear screen and draw
120
+ process.stdout.write('\x1b[2J\x1b[H');
121
+ console.log(output.join('\n'));
122
+ }
123
+ buildGraph(agents) {
124
+ if (agents.length === 0)
125
+ return ` ${DIM}(empty mesh — register agents to see the network)${RESET}`;
126
+ const lines = [];
127
+ // Draw agents as a network diagram
128
+ const width = 64;
129
+ const positions = this.calculatePositions(agents, width);
130
+ // Draw connections first
131
+ const connLines = [];
132
+ for (const agent of agents) {
133
+ for (const peerDid of agent.connections) {
134
+ const peer = this.agents.get(peerDid);
135
+ if (!peer)
136
+ continue;
137
+ const posA = positions.get(agent.did);
138
+ const posB = positions.get(peer.did);
139
+ if (posA && posB && posA.row < posB.row) {
140
+ connLines.push(` ${DIM} ${agent.name.padEnd(8)} ──── ${peer.name}${RESET}`);
141
+ }
142
+ }
143
+ }
144
+ // Draw agent boxes
145
+ for (const agent of agents) {
146
+ const caps = agent.capabilities.slice(0, 2).join(', ');
147
+ const connCount = agent.connections.size;
148
+ const msgCount = agent.messagesSent + agent.messagesReceived;
149
+ const isRecent = (Date.now() - agent.lastActive.getTime()) < 5000;
150
+ const pulse = isRecent ? `${GREEN}●${RESET}` : `${DIM}○${RESET}`;
151
+ const color = isRecent ? BOLD : DIM;
152
+ lines.push(` ${pulse} ${color}${agent.name.padEnd(10)}${RESET} ${DIM}${caps.padEnd(30)}${RESET} ${CYAN}${connCount}${RESET}${DIM} links${RESET} ${YELLOW}${msgCount}${RESET}${DIM} msgs${RESET}`);
153
+ }
154
+ // Add connection summary
155
+ if (connLines.length > 0) {
156
+ lines.push('');
157
+ lines.push(` ${DIM}CONNECTIONS${RESET}`);
158
+ for (const cl of connLines.slice(0, 8)) {
159
+ lines.push(cl);
160
+ }
161
+ if (connLines.length > 8) {
162
+ lines.push(` ${DIM} ... and ${connLines.length - 8} more${RESET}`);
163
+ }
164
+ }
165
+ return lines.join('\n');
166
+ }
167
+ calculatePositions(agents, width) {
168
+ const positions = new Map();
169
+ agents.forEach((agent, i) => {
170
+ positions.set(agent.did, { row: i, col: 0 });
171
+ });
172
+ return positions;
173
+ }
174
+ }
175
+ //# sourceMappingURL=terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "meshsig",
3
+ "version": "0.5.0",
4
+ "description": "Cryptographic security layer for AI agents. Ed25519 identity, signed messages, trust scoring.",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "meshsig": "dist/main.js"
9
+ },
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "ai-agents", "cryptography", "ed25519", "digital-signatures",
13
+ "identity", "did", "security", "trust", "openclaw", "mesh",
14
+ "agent-security", "w3c-did", "audit", "compliance"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/carlostroy/meshsig.git"
19
+ },
20
+ "homepage": "https://meshsig.ai",
21
+ "author": "MeshSig",
22
+ "files": [
23
+ "dist/",
24
+ "scripts/",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsc && cp src/dashboard.html dist/",
30
+ "start": "node dist/main.js",
31
+ "demo": "node dist/main.js start --demo",
32
+ "prepublishOnly": "npm run build",
33
+ "test": "tsc && node --test dist/**/*.test.js"
34
+ },
35
+ "dependencies": {
36
+ "@noble/ed25519": "^2.1.0",
37
+ "@noble/hashes": "^1.4.0",
38
+ "bs58": "^6.0.0",
39
+ "better-sqlite3": "^11.0.0",
40
+ "ws": "^8.16.0"
41
+ },
42
+ "devDependencies": {
43
+ "typescript": "^5.4.0",
44
+ "@types/node": "^20.0.0",
45
+ "@types/better-sqlite3": "^7.6.0",
46
+ "@types/ws": "^8.5.0"
47
+ },
48
+ "engines": {
49
+ "node": ">=18.0.0"
50
+ }
51
+ }
@@ -0,0 +1,271 @@
1
+ #!/bin/bash
2
+ # ==============================================================================
3
+ # MeshSig Install — Secures OpenClaw agent communication
4
+ #
5
+ # Registers ALL agents found in /root/clients/ with cryptographic identity.
6
+ # Installs signing layer on agents that have invoke-team skill.
7
+ # Auto-detects capabilities from agent names.
8
+ #
9
+ # Usage: bash install.sh
10
+ # ==============================================================================
11
+
12
+ set -e
13
+
14
+ MESH_URL="${MESHSIG_URL:-http://127.0.0.1:4888}"
15
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
16
+ IDENTITY_DIR="/opt/meshsig/identities"
17
+
18
+ C='\033[36m' # cyan
19
+ G='\033[32m' # green
20
+ M='\033[35m' # magenta
21
+ D='\033[2m' # dim
22
+ B='\033[1m' # bold
23
+ Y='\033[33m' # yellow
24
+ R='\033[0m' # reset
25
+
26
+ echo ""
27
+ echo -e "${C}"
28
+ echo -e " ███╗ ███╗███████╗███████╗██╗ ██╗███████╗██╗ ██████╗"
29
+ echo -e " ████╗ ████║██╔════╝██╔════╝██║ ██║██╔════╝██║██╔════╝"
30
+ echo -e " ██╔████╔██║█████╗ ███████╗███████║███████╗██║██║ ███╗"
31
+ echo -e " ██║╚██╔╝██║██╔══╝ ╚════██║██╔══██║╚════██║██║██║ ██║"
32
+ echo -e " ██║ ╚═╝ ██║███████╗███████║██║ ██║███████║██║╚██████╔╝"
33
+ echo -e " ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═════╝"
34
+ echo -e "${R}"
35
+ echo -e " ${M}◈${R} ${B}Securing Agent Network${R}"
36
+ echo -e ""
37
+ echo -e " ${D}─────────────────────────────────────────────────────────${R}"
38
+ echo ""
39
+
40
+ # Check MeshSig is running
41
+ if ! curl -s "$MESH_URL/health" > /dev/null 2>&1; then
42
+ echo -e " ${Y}▲${R} MeshSig not running at $MESH_URL"
43
+ echo -e " ${D} Start: cd /opt/meshsig && node dist/main.js start --port 4888 &${R}"
44
+ exit 1
45
+ fi
46
+ echo -e " ${G}⬢${R} ${D}CORE${R} MeshSig online at ${C}$MESH_URL${R}"
47
+
48
+ # Find OpenClaw clients
49
+ CLIENT_DIR="/root/clients"
50
+ if [ ! -d "$CLIENT_DIR" ]; then
51
+ echo -e " ${Y}▲${R} No OpenClaw clients found at $CLIENT_DIR"
52
+ exit 1
53
+ fi
54
+
55
+ # Find ALL agents
56
+ ALL_AGENTS=()
57
+ for d in "$CLIENT_DIR"/agent-*/; do
58
+ [ -d "$d" ] || continue
59
+ ALL_AGENTS+=("$(basename "$d")")
60
+ done
61
+
62
+ if [ ${#ALL_AGENTS[@]} -eq 0 ]; then
63
+ echo -e " ${Y}▲${R} No agents found in $CLIENT_DIR"
64
+ exit 1
65
+ fi
66
+
67
+ echo -e " ${G}⬢${R} ${D}AGENTS${R} ${#ALL_AGENTS[@]} agent(s) found"
68
+
69
+ # Find agents with invoke-team skill (for signing layer)
70
+ AGENTS_WITH_SKILL=()
71
+ for agent_name in "${ALL_AGENTS[@]}"; do
72
+ skill_dir="$CLIENT_DIR/$agent_name/.openclaw/workspace/skills/invoke-team"
73
+ if [ -d "$skill_dir" ]; then
74
+ AGENTS_WITH_SKILL+=("$agent_name")
75
+ fi
76
+ done
77
+
78
+ if [ ${#AGENTS_WITH_SKILL[@]} -gt 0 ]; then
79
+ echo -e " ${G}⬢${R} ${D}SKILLS${R} ${#AGENTS_WITH_SKILL[@]} agent(s) with delegation skill"
80
+ fi
81
+
82
+ # Create identity directory
83
+ mkdir -p "$IDENTITY_DIR"
84
+
85
+ # Detect capabilities from agent name
86
+ detect_caps() {
87
+ local name="$1"
88
+ case "$name" in
89
+ *gestor*|*gerente*|*manager*|*coo*|*ceo*)
90
+ echo '[{"type":"management","confidence":0.95},{"type":"delegation","confidence":0.9}]' ;;
91
+ *atendente*|*suporte*|*support*)
92
+ echo '[{"type":"customer-support","confidence":0.92}]' ;;
93
+ *sdr*|*vendas*|*sales*|*benicio*)
94
+ echo '[{"type":"sales","confidence":0.9},{"type":"sdr","confidence":0.88}]' ;;
95
+ *copy*|*redator*|*writer*|*content*)
96
+ echo '[{"type":"copywriting","confidence":0.93}]' ;;
97
+ *social*|*marketing*|*instagram*)
98
+ echo '[{"type":"social-media","confidence":0.91}]' ;;
99
+ *analista*|*analytics*|*dados*|*data*)
100
+ echo '[{"type":"analytics","confidence":0.87}]' ;;
101
+ *dev*|*code*|*programador*)
102
+ echo '[{"type":"coding","confidence":0.9}]' ;;
103
+ *)
104
+ echo '[{"type":"general","confidence":0.8}]' ;;
105
+ esac
106
+ }
107
+
108
+ # Extract display name from client name
109
+ extract_name() {
110
+ local raw="$1"
111
+ # Remove "agent-" prefix, take first part before "---"
112
+ local name=$(echo "$raw" | sed 's/^agent-//' | cut -d'-' -f1)
113
+ # Capitalize first letter
114
+ echo "$name" | sed 's/./\U&/'
115
+ }
116
+
117
+ # Register ALL agents
118
+ echo ""
119
+ echo -e " ${D}────────── ${R}${B}IDENTITY REGISTRATION${R} ${D}──────────${R}"
120
+ echo ""
121
+
122
+ MANAGER_AGENTS=()
123
+ for agent_name in "${ALL_AGENTS[@]}"; do
124
+ identity_file="$IDENTITY_DIR/$agent_name.json"
125
+ display_name=$(extract_name "$agent_name")
126
+ caps=$(detect_caps "$agent_name")
127
+
128
+ # Track managers for connection step
129
+ if [[ "$agent_name" == *"gestor"* || "$agent_name" == *"gerente"* || "$agent_name" == *"manager"* || "$agent_name" == *"coo"* ]]; then
130
+ MANAGER_AGENTS+=("$agent_name")
131
+ fi
132
+
133
+ if [ -f "$identity_file" ]; then
134
+ echo -e " ${D}◇${R} ${D}$display_name${R} — ${D}already registered${R}"
135
+ else
136
+ result=$(curl -s -X POST "$MESH_URL/agents/register" \
137
+ -H "Content-Type: application/json" \
138
+ -d "{\"name\":\"$display_name\",\"capabilities\":$caps}")
139
+
140
+ echo "$result" | python3 -c "
141
+ import sys, json
142
+ data = json.load(sys.stdin)
143
+ identity = data.get('identity', {})
144
+ record = data.get('record', {})
145
+ out = {
146
+ 'did': identity.get('did',''),
147
+ 'privateKey': identity.get('privateKey',''),
148
+ 'publicKey': identity.get('publicKey',''),
149
+ 'displayName': record.get('displayName', ''),
150
+ 'clientName': '$agent_name'
151
+ }
152
+ with open('$identity_file', 'w') as f:
153
+ json.dump(out, f, indent=2)
154
+ print(f\" \033[36m◆\033[0m \033[1m{out['displayName']} registered — {out['did'][:40]}...\")
155
+ " 2>/dev/null
156
+ fi
157
+ done
158
+
159
+ # Create connections — managers connect to everyone
160
+ echo ""
161
+ echo -e " ${D}────────── ${R}${B}VERIFIED CONNECTIONS${R} ${D}───────────${R}"
162
+ echo ""
163
+
164
+ create_connection() {
165
+ local from_name="$1"
166
+ local to_name="$2"
167
+ local from_file="$IDENTITY_DIR/$from_name.json"
168
+ local to_file="$IDENTITY_DIR/$to_name.json"
169
+
170
+ [ -f "$from_file" ] && [ -f "$to_file" ] || return
171
+
172
+ local from_did=$(python3 -c "import json; print(json.load(open('$from_file'))['did'])" 2>/dev/null)
173
+ local to_did=$(python3 -c "import json; print(json.load(open('$to_file'))['did'])" 2>/dev/null)
174
+ local from_key=$(python3 -c "import json; print(json.load(open('$from_file'))['privateKey'])" 2>/dev/null)
175
+ local to_key=$(python3 -c "import json; print(json.load(open('$to_file'))['privateKey'])" 2>/dev/null)
176
+ local from_display=$(python3 -c "import json; print(json.load(open('$from_file'))['displayName'])" 2>/dev/null)
177
+ local to_display=$(python3 -c "import json; print(json.load(open('$to_file'))['displayName'])" 2>/dev/null)
178
+
179
+ curl -s -X POST "$MESH_URL/handshake" \
180
+ -H "Content-Type: application/json" \
181
+ -d "{\"fromDid\":\"$from_did\",\"toDid\":\"$to_did\",\"privateKeyA\":\"$from_key\",\"privateKeyB\":\"$to_key\",\"permissions\":[\"send:request\",\"execute:task\"]}" > /dev/null 2>&1
182
+
183
+ echo -e " ${G}⟷${R} ${B}$from_display${R} ${D}↔${R} ${B}$to_display${R} ${D}— Ed25519 handshake verified${R}"
184
+ }
185
+
186
+ # Connect managers to all other agents
187
+ for manager in "${MANAGER_AGENTS[@]}"; do
188
+ for agent in "${ALL_AGENTS[@]}"; do
189
+ [ "$manager" == "$agent" ] && continue
190
+ create_connection "$manager" "$agent"
191
+ done
192
+ done
193
+
194
+ # If no managers found, connect all agents in a mesh
195
+ if [ ${#MANAGER_AGENTS[@]} -eq 0 ] && [ ${#ALL_AGENTS[@]} -gt 1 ]; then
196
+ echo -e " ${D}No manager detected — creating full mesh${R}"
197
+ for ((i=0; i<${#ALL_AGENTS[@]}; i++)); do
198
+ for ((j=i+1; j<${#ALL_AGENTS[@]}; j++)); do
199
+ create_connection "${ALL_AGENTS[$i]}" "${ALL_AGENTS[$j]}"
200
+ done
201
+ done
202
+ fi
203
+
204
+ # Install invoke-mesh.sh ONLY on agents with invoke-team skill
205
+ if [ ${#AGENTS_WITH_SKILL[@]} -gt 0 ]; then
206
+ echo ""
207
+ echo -e " ${D}────────── ${R}${B}SECURITY LAYER INSTALL${R} ${D}─────────${R}"
208
+ echo ""
209
+
210
+ for agent_name in "${AGENTS_WITH_SKILL[@]}"; do
211
+ skill_dir="$CLIENT_DIR/$agent_name/.openclaw/workspace/skills/invoke-team"
212
+ original="$skill_dir/invoke.sh"
213
+ backup="$skill_dir/invoke.sh.original"
214
+
215
+ if [ -f "$original" ] && [ ! -f "$backup" ]; then
216
+ cp "$original" "$backup"
217
+ echo -e " ${D}↳${R} ${D}Backed up original invoke.sh${R}"
218
+ fi
219
+
220
+ cp "$SCRIPT_DIR/invoke-mesh.sh" "$skill_dir/invoke-mesh.sh"
221
+ chmod +x "$skill_dir/invoke-mesh.sh"
222
+
223
+ cat > "$original" << 'WRAPPER'
224
+ #!/bin/bash
225
+ # Original invoke.sh replaced by MeshSig secure invoke.
226
+ # Every delegation is now cryptographically signed and verified.
227
+ # Original backed up at invoke.sh.original
228
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
229
+ exec bash "$SCRIPT_DIR/invoke-mesh.sh" "$@"
230
+ WRAPPER
231
+ chmod +x "$original"
232
+
233
+ skill_md="$skill_dir/SKILL.md"
234
+ if ! grep -q "MeshSig" "$skill_md" 2>/dev/null; then
235
+ cat >> "$skill_md" << 'SKILLAPPEND'
236
+
237
+ ## Security (MeshSig)
238
+
239
+ All delegations through this skill are automatically:
240
+ - **Signed** with the sender's Ed25519 cryptographic key
241
+ - **Verified** by MeshSig before delivery
242
+ - **Logged** with tamper-proof audit trail
243
+ - **Trust-scored** — successful interactions build trust over time
244
+
245
+ Dashboard: http://localhost:4888
246
+ SKILLAPPEND
247
+ fi
248
+
249
+ echo -e " ${G}⬢${R} ${B}$agent_name${R} ${D}— secured with MeshSig${R}"
250
+ done
251
+ fi
252
+
253
+ # Final stats
254
+ echo ""
255
+ STATS=$(curl -s "$MESH_URL/stats")
256
+ AGENTS=$(echo "$STATS" | python3 -c "import sys,json; print(json.load(sys.stdin)['agents'])" 2>/dev/null)
257
+ CONNS=$(echo "$STATS" | python3 -c "import sys,json; print(json.load(sys.stdin)['connections'])" 2>/dev/null)
258
+
259
+ echo -e " ${D}─────────────────────────────────────────────────────────${R}"
260
+ echo ""
261
+ echo -e " ${G}${B}✓ MESHSIG ACTIVE${R}"
262
+ echo ""
263
+ echo -e " ${D}AGENTS${R} ${C}${B}$AGENTS${R} ${D}registered with Ed25519 identity${R}"
264
+ echo -e " ${D}CONNECTIONS${R} ${C}${B}$CONNS${R} ${D}verified handshakes${R}"
265
+ echo -e " ${D}DASHBOARD${R} ${C}http://localhost:4888${R}"
266
+ echo ""
267
+ echo -e " ${D}Every agent-to-agent delegation is now${R}"
268
+ echo -e " ${D}cryptographically signed and verified.${R}"
269
+ echo ""
270
+ echo -e " ${D}─────────────────────────────────────────────────────────${R}"
271
+ echo ""