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.
- package/LICENSE +21 -0
- package/README.md +276 -0
- package/dist/crypto.d.ts +43 -0
- package/dist/crypto.js +108 -0
- package/dist/crypto.js.map +1 -0
- package/dist/dashboard.html +635 -0
- package/dist/demo.d.ts +2 -0
- package/dist/demo.js +107 -0
- package/dist/demo.js.map +1 -0
- package/dist/discovery.d.ts +24 -0
- package/dist/discovery.js +119 -0
- package/dist/discovery.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +459 -0
- package/dist/main.js.map +1 -0
- package/dist/peers.d.ts +35 -0
- package/dist/peers.js +227 -0
- package/dist/peers.js.map +1 -0
- package/dist/registry.d.ts +85 -0
- package/dist/registry.js +311 -0
- package/dist/registry.js.map +1 -0
- package/dist/server.d.ts +27 -0
- package/dist/server.js +433 -0
- package/dist/server.js.map +1 -0
- package/dist/terminal.d.ts +17 -0
- package/dist/terminal.js +175 -0
- package/dist/terminal.js.map +1 -0
- package/package.json +51 -0
- package/scripts/install.sh +271 -0
- package/scripts/invoke-mesh.sh +190 -0
- package/scripts/register-agent.sh +89 -0
- package/scripts/uninstall.sh +25 -0
- package/scripts/unregister-agent.sh +23 -0
package/dist/terminal.js
ADDED
|
@@ -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 ""
|