@cryptiklemur/lattice 1.32.0 → 1.32.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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useCallback, memo } from "react";
|
|
2
|
-
import { Plus, CircleDot, Circle, RefreshCw } from "lucide-react";
|
|
2
|
+
import { Plus, CircleDot, Circle, RefreshCw, Loader2 } from "lucide-react";
|
|
3
3
|
import { useWebSocket } from "../../hooks/useWebSocket";
|
|
4
4
|
import { useMesh } from "../../hooks/useMesh";
|
|
5
5
|
import { PairingDialog } from "../mesh/PairingDialog";
|
|
@@ -13,6 +13,7 @@ interface NodeRowProps {
|
|
|
13
13
|
|
|
14
14
|
function NodeRow(props: NodeRowProps) {
|
|
15
15
|
var [confirming, setConfirming] = useState(false);
|
|
16
|
+
var [reconnecting, setReconnecting] = useState(false);
|
|
16
17
|
|
|
17
18
|
function handleUnpair() {
|
|
18
19
|
if (!confirming) {
|
|
@@ -58,14 +59,25 @@ function NodeRow(props: NodeRowProps) {
|
|
|
58
59
|
{!props.node.isLocal && (
|
|
59
60
|
<div className="flex gap-1.5 flex-shrink-0">
|
|
60
61
|
{!props.node.online && (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
reconnecting ? (
|
|
63
|
+
<span className="flex items-center gap-1 text-[11px] text-base-content/40">
|
|
64
|
+
<Loader2 size={10} className="animate-spin" />
|
|
65
|
+
Connecting...
|
|
66
|
+
</span>
|
|
67
|
+
) : (
|
|
68
|
+
<button
|
|
69
|
+
onClick={function () {
|
|
70
|
+
setReconnecting(true);
|
|
71
|
+
props.onReconnect(props.node.id);
|
|
72
|
+
setTimeout(function () { setReconnecting(false); }, 5000);
|
|
73
|
+
}}
|
|
74
|
+
className="btn btn-ghost btn-xs border border-base-content/20 hover:btn-info hover:border-info gap-1"
|
|
75
|
+
title="Attempt to reconnect"
|
|
76
|
+
>
|
|
77
|
+
<RefreshCw size={10} />
|
|
78
|
+
Reconnect
|
|
79
|
+
</button>
|
|
80
|
+
)
|
|
69
81
|
)}
|
|
70
82
|
{confirming ? (
|
|
71
83
|
<>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cryptiklemur/lattice",
|
|
3
|
-
"version": "1.32.
|
|
3
|
+
"version": "1.32.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>",
|
|
@@ -4,7 +4,7 @@ import { sendTo, broadcast } from "../ws/broadcast";
|
|
|
4
4
|
import { loadConfig } from "../config";
|
|
5
5
|
import { loadOrCreateIdentity } from "../identity";
|
|
6
6
|
import { generateInviteCode, parseInviteCode, validatePairingToken, consumePairingToken } from "../mesh/pairing";
|
|
7
|
-
import { addPeer, removePeer, loadPeers } from "../mesh/peers";
|
|
7
|
+
import { addPeer, removePeer, loadPeers, getPeer } from "../mesh/peers";
|
|
8
8
|
import { getConnectedPeerIds, connectToPeer, reconnectPeer } from "../mesh/connector";
|
|
9
9
|
import type { PeerInfo } from "@lattice/shared";
|
|
10
10
|
import { networkInterfaces } from "node:os";
|
|
@@ -172,6 +172,20 @@ registerHandler("mesh", function (clientId: string, message: ClientMessage) {
|
|
|
172
172
|
if ((message as any).type === "mesh:hello") {
|
|
173
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 }> };
|
|
174
174
|
|
|
175
|
+
var knownPeer = hello.nodeId ? getPeer(hello.nodeId) : undefined;
|
|
176
|
+
|
|
177
|
+
if (knownPeer) {
|
|
178
|
+
var identity = loadOrCreateIdentity();
|
|
179
|
+
sendTo(clientId, {
|
|
180
|
+
type: "mesh:hello" as any,
|
|
181
|
+
nodeId: identity.id,
|
|
182
|
+
name: loadConfig().name,
|
|
183
|
+
projects: [],
|
|
184
|
+
});
|
|
185
|
+
broadcast({ type: "mesh:nodes", nodes: buildNodesMessage() });
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
175
189
|
if (!hello.token || !validatePairingToken(hello.token)) {
|
|
176
190
|
sendTo(clientId, { type: "mesh:hello_rejected" as any, error: "Invalid or expired invite code" });
|
|
177
191
|
return;
|
|
@@ -193,10 +207,10 @@ registerHandler("mesh", function (clientId: string, message: ClientMessage) {
|
|
|
193
207
|
connectToPeer(peer.id, peerAddresses[0]);
|
|
194
208
|
}
|
|
195
209
|
|
|
196
|
-
var
|
|
210
|
+
var identity2 = loadOrCreateIdentity();
|
|
197
211
|
sendTo(clientId, {
|
|
198
212
|
type: "mesh:hello" as any,
|
|
199
|
-
nodeId:
|
|
213
|
+
nodeId: identity2.id,
|
|
200
214
|
name: loadConfig().name,
|
|
201
215
|
projects: [],
|
|
202
216
|
});
|