@cryptiklemur/lattice 1.30.1 → 1.31.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.
|
@@ -39,11 +39,18 @@ function NodeRow(props: NodeRowProps) {
|
|
|
39
39
|
</span>
|
|
40
40
|
)}
|
|
41
41
|
</div>
|
|
42
|
-
<div className="text-[11px] text-base-content/40
|
|
43
|
-
{props.node.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
)
|
|
42
|
+
<div className="text-[11px] text-base-content/40">
|
|
43
|
+
{(props.node.addresses && props.node.addresses.length > 0
|
|
44
|
+
? props.node.addresses
|
|
45
|
+
: [props.node.address + (props.node.port ? ":" + props.node.port : "")]
|
|
46
|
+
).map(function (addr, i) {
|
|
47
|
+
return (
|
|
48
|
+
<span key={addr} className="mr-2">
|
|
49
|
+
{i > 0 && <span className="text-base-content/20 mr-2">/</span>}
|
|
50
|
+
{addr}
|
|
51
|
+
</span>
|
|
52
|
+
);
|
|
53
|
+
})}
|
|
47
54
|
</div>
|
|
48
55
|
</div>
|
|
49
56
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cryptiklemur/lattice",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.31.1",
|
|
4
4
|
"description": "Multi-machine agentic dashboard for Claude Code. Monitor sessions, manage MCP servers and skills, orchestrate across mesh-networked nodes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Aaron Scherer <me@aaronscherer.me>",
|
|
@@ -5,6 +5,7 @@ import { loadConfig } from "../config";
|
|
|
5
5
|
import { loadOrCreateIdentity } from "../identity";
|
|
6
6
|
import { generateInviteCode, parseInviteCode, validatePairingToken, consumePairingToken } from "../mesh/pairing";
|
|
7
7
|
import { addPeer, removePeer, loadPeers } from "../mesh/peers";
|
|
8
|
+
import { getConnectedPeerIds, connectToPeer } from "../mesh/connector";
|
|
8
9
|
import type { PeerInfo } from "@lattice/shared";
|
|
9
10
|
import { networkInterfaces } from "node:os";
|
|
10
11
|
|
|
@@ -33,11 +34,14 @@ export function buildNodesMessage(): NodeInfo[] {
|
|
|
33
34
|
var peers = loadPeers();
|
|
34
35
|
var config = loadConfig();
|
|
35
36
|
var identity = loadOrCreateIdentity();
|
|
37
|
+
var connectedIds = new Set(getConnectedPeerIds());
|
|
38
|
+
var localAddrs = getAllAddresses().map(function (a) { return a.address + ":" + config.port; });
|
|
36
39
|
|
|
37
40
|
var local: NodeInfo = {
|
|
38
41
|
id: identity.id,
|
|
39
42
|
name: config.name,
|
|
40
|
-
address: "localhost",
|
|
43
|
+
address: localAddrs[0] ?? "localhost:" + config.port,
|
|
44
|
+
addresses: localAddrs.length > 0 ? localAddrs : ["localhost:" + config.port],
|
|
41
45
|
port: config.port,
|
|
42
46
|
online: true,
|
|
43
47
|
isLocal: true,
|
|
@@ -51,8 +55,9 @@ export function buildNodesMessage(): NodeInfo[] {
|
|
|
51
55
|
id: peer.id,
|
|
52
56
|
name: peer.name,
|
|
53
57
|
address: peer.addresses[0] ?? "",
|
|
58
|
+
addresses: peer.addresses,
|
|
54
59
|
port: 0,
|
|
55
|
-
online:
|
|
60
|
+
online: connectedIds.has(peer.id),
|
|
56
61
|
isLocal: false,
|
|
57
62
|
projects: [],
|
|
58
63
|
};
|
|
@@ -101,11 +106,14 @@ registerHandler("mesh", function (clientId: string, message: ClientMessage) {
|
|
|
101
106
|
|
|
102
107
|
pairWs.addEventListener("open", function () {
|
|
103
108
|
var identity = loadOrCreateIdentity();
|
|
109
|
+
var pairConfig = loadConfig();
|
|
104
110
|
pairWs.send(JSON.stringify({
|
|
105
111
|
type: "mesh:hello",
|
|
106
112
|
nodeId: identity.id,
|
|
107
|
-
name:
|
|
113
|
+
name: pairConfig.name,
|
|
108
114
|
token: parsed!.token,
|
|
115
|
+
port: pairConfig.port,
|
|
116
|
+
addresses: getAllAddresses().map(function (a) { return a.address + ":" + pairConfig.port; }),
|
|
109
117
|
projects: [],
|
|
110
118
|
}));
|
|
111
119
|
});
|
|
@@ -123,20 +131,24 @@ registerHandler("mesh", function (clientId: string, message: ClientMessage) {
|
|
|
123
131
|
|
|
124
132
|
if (data.type === "mesh:hello" && data.nodeId && data.name) {
|
|
125
133
|
clearTimeout(pairTimeout);
|
|
134
|
+
var peerAddr = parsed!.address + ":" + parsed!.port;
|
|
126
135
|
var peer: PeerInfo = {
|
|
127
136
|
id: data.nodeId,
|
|
128
137
|
name: data.name,
|
|
129
|
-
addresses: [
|
|
138
|
+
addresses: [peerAddr],
|
|
130
139
|
publicKey: "",
|
|
131
140
|
pairedAt: Date.now(),
|
|
132
141
|
};
|
|
133
142
|
addPeer(peer);
|
|
134
143
|
pairWs.close();
|
|
135
144
|
|
|
145
|
+
connectToPeer(peer.id, peerAddr);
|
|
146
|
+
|
|
136
147
|
var nodeInfo: NodeInfo = {
|
|
137
148
|
id: peer.id,
|
|
138
149
|
name: peer.name,
|
|
139
|
-
address:
|
|
150
|
+
address: peerAddr,
|
|
151
|
+
addresses: [peerAddr],
|
|
140
152
|
port: parsed!.port,
|
|
141
153
|
online: true,
|
|
142
154
|
isLocal: false,
|
|
@@ -158,7 +170,7 @@ registerHandler("mesh", function (clientId: string, message: ClientMessage) {
|
|
|
158
170
|
}
|
|
159
171
|
|
|
160
172
|
if ((message as any).type === "mesh:hello") {
|
|
161
|
-
var hello = message as any as { type: "mesh:hello"; nodeId: string; name: string; token?: string; projects: Array<{ slug: string; title: string }> };
|
|
173
|
+
var hello = message as any as { type: "mesh:hello"; nodeId: string; name: string; token?: string; port?: number; addresses?: string[]; projects: Array<{ slug: string; title: string }> };
|
|
162
174
|
|
|
163
175
|
if (!hello.token || !validatePairingToken(hello.token)) {
|
|
164
176
|
sendTo(clientId, { type: "mesh:hello_rejected" as any, error: "Invalid or expired invite code" });
|
|
@@ -166,15 +178,21 @@ registerHandler("mesh", function (clientId: string, message: ClientMessage) {
|
|
|
166
178
|
}
|
|
167
179
|
consumePairingToken(hello.token);
|
|
168
180
|
|
|
181
|
+
var peerAddresses = hello.addresses ?? [];
|
|
182
|
+
|
|
169
183
|
var peer: PeerInfo = {
|
|
170
184
|
id: hello.nodeId,
|
|
171
185
|
name: hello.name,
|
|
172
|
-
addresses:
|
|
186
|
+
addresses: peerAddresses,
|
|
173
187
|
publicKey: "",
|
|
174
188
|
pairedAt: Date.now(),
|
|
175
189
|
};
|
|
176
190
|
addPeer(peer);
|
|
177
191
|
|
|
192
|
+
if (peerAddresses.length > 0) {
|
|
193
|
+
connectToPeer(peer.id, peerAddresses[0]);
|
|
194
|
+
}
|
|
195
|
+
|
|
178
196
|
var identity = loadOrCreateIdentity();
|
|
179
197
|
sendTo(clientId, {
|
|
180
198
|
type: "mesh:hello" as any,
|
|
@@ -66,9 +66,10 @@ export function connectToPeer(nodeId: string, address: string): void {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
var config = loadConfig();
|
|
69
|
-
var port = config.port;
|
|
70
69
|
var protocol = config.tls ? "wss" : "ws";
|
|
71
|
-
var url =
|
|
70
|
+
var url = address.includes(":")
|
|
71
|
+
? protocol + "://" + address + "/ws"
|
|
72
|
+
: protocol + "://" + address + ":" + config.port + "/ws";
|
|
72
73
|
|
|
73
74
|
var conn: PeerConnection = {
|
|
74
75
|
nodeId: nodeId,
|