@cryptiklemur/lattice 1.40.0 → 1.40.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cryptiklemur/lattice",
|
|
3
|
-
"version": "1.40.
|
|
3
|
+
"version": "1.40.2",
|
|
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>",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { ClientMessage, MeshPairMessage, MeshUnpairMessage, NodeInfo } from "@lattice/shared";
|
|
2
2
|
import { log } from "../logger";
|
|
3
|
+
import { handleProxyRequest, handleProxyResponse } from "../mesh/proxy";
|
|
4
|
+
import type { MeshProxyRequestMessage, MeshProxyResponseMessage } from "@lattice/shared";
|
|
3
5
|
import { registerHandler } from "../ws/router";
|
|
4
6
|
import { sendTo, broadcast } from "../ws/broadcast";
|
|
5
7
|
import { loadConfig } from "../config";
|
|
@@ -7,7 +9,7 @@ import { loadOrCreateIdentity } from "../identity";
|
|
|
7
9
|
import { generateInviteCode, parseInviteCode, validatePairingToken, consumePairingToken } from "../mesh/pairing";
|
|
8
10
|
import { addPeer, removePeer, loadPeers, getPeer } from "../mesh/peers";
|
|
9
11
|
import { getConnectedPeerIds, connectToPeer, reconnectPeer, getPeerConnection, disconnectPeer, getConnectedPeerProjects, registerInboundPeer } from "../mesh/connector";
|
|
10
|
-
import { getClientWebSocket } from "../ws/broadcast";
|
|
12
|
+
import { getClientWebSocket, registerVirtualClient, removeVirtualClient } from "../ws/broadcast";
|
|
11
13
|
import type { PeerInfo } from "@lattice/shared";
|
|
12
14
|
import { networkInterfaces } from "node:os";
|
|
13
15
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -245,9 +247,9 @@ registerHandler("mesh", function (clientId: string, message: ClientMessage) {
|
|
|
245
247
|
}
|
|
246
248
|
|
|
247
249
|
var inboundWs = getClientWebSocket(clientId);
|
|
248
|
-
log.meshHello(" registering inbound connection for %s (ws=%s)", hello.name, !!inboundWs);
|
|
250
|
+
log.meshHello(" registering inbound connection for %s (ws=%s, projects=%d)", hello.name, !!inboundWs, hello.projects?.length ?? 0);
|
|
249
251
|
if (inboundWs) {
|
|
250
|
-
registerInboundPeer(hello.nodeId, inboundWs as any);
|
|
252
|
+
registerInboundPeer(hello.nodeId, inboundWs as any, hello.projects ?? []);
|
|
251
253
|
}
|
|
252
254
|
|
|
253
255
|
var identity = loadOrCreateIdentity();
|
|
@@ -296,6 +298,33 @@ registerHandler("mesh", function (clientId: string, message: ClientMessage) {
|
|
|
296
298
|
return;
|
|
297
299
|
}
|
|
298
300
|
|
|
301
|
+
if ((message as any).type === "mesh:proxy_request") {
|
|
302
|
+
var proxyReq = message as unknown as MeshProxyRequestMessage;
|
|
303
|
+
log.meshProxy("received proxy_request via handler from %s: %s for %s", clientId.slice(0, 8), (proxyReq.payload as any).type, proxyReq.projectSlug);
|
|
304
|
+
|
|
305
|
+
registerVirtualClient("mesh-proxy:" + clientId + ":" + proxyReq.requestId, function (response: object) {
|
|
306
|
+
log.meshProxy(" → sending proxy_response %s back to client %s", (response as any).type, clientId.slice(0, 8));
|
|
307
|
+
sendTo(clientId, {
|
|
308
|
+
type: "mesh:proxy_response",
|
|
309
|
+
projectSlug: proxyReq.projectSlug,
|
|
310
|
+
requestId: proxyReq.requestId,
|
|
311
|
+
payload: response,
|
|
312
|
+
} as any);
|
|
313
|
+
removeVirtualClient("mesh-proxy:" + clientId + ":" + proxyReq.requestId);
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
var { routeMessage: routeMsg } = require("../ws/router") as typeof import("../ws/router");
|
|
317
|
+
routeMsg("mesh-proxy:" + clientId + ":" + proxyReq.requestId, proxyReq.payload);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if ((message as any).type === "mesh:proxy_response") {
|
|
322
|
+
var proxyRes = message as unknown as MeshProxyResponseMessage;
|
|
323
|
+
log.meshProxy("received proxy_response via handler: %s", (proxyRes.payload as any).type);
|
|
324
|
+
handleProxyResponse(proxyRes);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
299
328
|
if (message.type === "mesh:reconnect") {
|
|
300
329
|
var reconnectMsg = message as { type: "mesh:reconnect"; nodeId: string };
|
|
301
330
|
reconnectPeer(reconnectMsg.nodeId);
|
|
@@ -252,7 +252,7 @@ export function getPeerConnection(nodeId: string): WebSocket | undefined {
|
|
|
252
252
|
return conn.ws;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
export function registerInboundPeer(nodeId: string, ws: { send: (data: string) => void; readyState: number }): void {
|
|
255
|
+
export function registerInboundPeer(nodeId: string, ws: { send: (data: string) => void; readyState: number }, peerProjects?: Array<{ slug: string; title: string }>): void {
|
|
256
256
|
var existing = connections.get(nodeId);
|
|
257
257
|
if (existing && !existing.dead && existing.ws.readyState === WebSocket.OPEN) {
|
|
258
258
|
log.meshConnect("inbound peer %s already connected, skipping", nodeId.slice(0, 8));
|
|
@@ -269,15 +269,20 @@ export function registerInboundPeer(nodeId: string, ws: { send: (data: string) =
|
|
|
269
269
|
|
|
270
270
|
circuitBreakers.delete(nodeId);
|
|
271
271
|
|
|
272
|
+
var incomingProjects = peerProjects ?? [];
|
|
272
273
|
var conn: PeerConnection = {
|
|
273
274
|
nodeId: nodeId,
|
|
274
275
|
ws: ws as WebSocket,
|
|
275
276
|
backoffMs: 1000,
|
|
276
277
|
retryTimer: null,
|
|
277
278
|
dead: false,
|
|
278
|
-
projects:
|
|
279
|
+
projects: incomingProjects,
|
|
279
280
|
};
|
|
280
281
|
|
|
282
|
+
if (incomingProjects.length > 0) {
|
|
283
|
+
lastKnownProjects.set(nodeId, incomingProjects);
|
|
284
|
+
}
|
|
285
|
+
|
|
281
286
|
connections.set(nodeId, conn);
|
|
282
287
|
|
|
283
288
|
var peers = loadPeers();
|