squad-openclaw 2026.2.1806 → 2026.2.1809
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/dist/index.js +69 -12
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1041,9 +1041,9 @@ function ensureDevicePaired(keys, operatorToken) {
|
|
|
1041
1041
|
console.log(`[relay-client] Device pairing entry created in paired.json`);
|
|
1042
1042
|
return true;
|
|
1043
1043
|
}
|
|
1044
|
-
function signDeviceIdentity(keys, clientId, clientMode, role, scopes, token) {
|
|
1044
|
+
function signDeviceIdentity(keys, clientId, clientMode, role, scopes, token, challengeNonce) {
|
|
1045
1045
|
const signedAtMs = Date.now();
|
|
1046
|
-
const nonce = crypto2.randomBytes(16).toString("hex");
|
|
1046
|
+
const nonce = challengeNonce || crypto2.randomBytes(16).toString("hex");
|
|
1047
1047
|
const scopeStr = scopes.join(",");
|
|
1048
1048
|
const payload = `v2|${keys.deviceId}|${clientId}|${clientMode}|${role}|${scopeStr}|${signedAtMs}|${token ?? ""}|${nonce}`;
|
|
1049
1049
|
const privateKey = crypto2.createPrivateKey(keys.privateKeyPem);
|
|
@@ -1078,7 +1078,7 @@ var RelayClient = class {
|
|
|
1078
1078
|
claimToken: config.claimToken ?? state.claimToken ?? null,
|
|
1079
1079
|
roomId: config.roomId ?? state.roomId ?? null
|
|
1080
1080
|
};
|
|
1081
|
-
this.pendingClaimToken = this.config.claimToken;
|
|
1081
|
+
this.pendingClaimToken = this.config.roomId ? null : this.config.claimToken;
|
|
1082
1082
|
this.deviceKeys = loadOrCreateRelayDeviceKeys();
|
|
1083
1083
|
const newEntry = ensureDevicePaired(this.deviceKeys, this.config.operatorToken);
|
|
1084
1084
|
if (newEntry) {
|
|
@@ -1254,19 +1254,29 @@ var RelayClient = class {
|
|
|
1254
1254
|
}
|
|
1255
1255
|
/** Route a message from the relay to the appropriate user's local WS */
|
|
1256
1256
|
routeToUser(userId, innerMsg) {
|
|
1257
|
+
const msg = innerMsg;
|
|
1258
|
+
if (msg.type === "event" && typeof msg.event === "string" && msg.event.startsWith("relay.")) {
|
|
1259
|
+
if (msg.event === "relay.user.connected") {
|
|
1260
|
+
console.log(`[relay-client] User ${userId} connected via relay \u2014 creating local WS`);
|
|
1261
|
+
const existing = this.userConnections.get(userId);
|
|
1262
|
+
if (!existing || existing.localWs.readyState !== NodeWebSocket.OPEN) {
|
|
1263
|
+
this.createUserConnection(userId);
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
if (typeof msg.type === "string" && msg.type.startsWith("relay.")) {
|
|
1269
|
+
if (msg.type === "relay.e2e.exchange" && msg.publicKey) {
|
|
1270
|
+
this.handleE2EExchange(userId, msg.publicKey);
|
|
1271
|
+
}
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1257
1274
|
let conn = this.userConnections.get(userId);
|
|
1258
1275
|
if (!conn || conn.localWs.readyState !== NodeWebSocket.OPEN) {
|
|
1259
1276
|
this.createUserConnection(userId);
|
|
1260
1277
|
conn = this.userConnections.get(userId);
|
|
1261
1278
|
if (!conn) return;
|
|
1262
1279
|
}
|
|
1263
|
-
if (conn.localWs.readyState === NodeWebSocket.CONNECTING) {
|
|
1264
|
-
conn.localWs.once("open", () => {
|
|
1265
|
-
conn.localWs.send(JSON.stringify(innerMsg));
|
|
1266
|
-
});
|
|
1267
|
-
return;
|
|
1268
|
-
}
|
|
1269
|
-
const msg = innerMsg;
|
|
1270
1280
|
if (msg.type === "req" && msg.method === "connect") {
|
|
1271
1281
|
const params = msg.params ?? {};
|
|
1272
1282
|
if (this.config.operatorToken) {
|
|
@@ -1281,10 +1291,18 @@ var RelayClient = class {
|
|
|
1281
1291
|
client.mode ?? "ui",
|
|
1282
1292
|
role,
|
|
1283
1293
|
scopes,
|
|
1284
|
-
this.config.operatorToken
|
|
1294
|
+
this.config.operatorToken,
|
|
1295
|
+
conn.challengeNonce
|
|
1285
1296
|
);
|
|
1286
1297
|
msg.params = params;
|
|
1287
1298
|
conn.connectHandshakeComplete = false;
|
|
1299
|
+
console.log(`[relay-client] Injected device identity for user ${userId}: ${this.deviceKeys.deviceId.substring(0, 12)}...`);
|
|
1300
|
+
}
|
|
1301
|
+
if (conn.localWs.readyState === NodeWebSocket.CONNECTING) {
|
|
1302
|
+
conn.localWs.once("open", () => {
|
|
1303
|
+
conn.localWs.send(JSON.stringify(msg));
|
|
1304
|
+
});
|
|
1305
|
+
return;
|
|
1288
1306
|
}
|
|
1289
1307
|
conn.localWs.send(JSON.stringify(msg));
|
|
1290
1308
|
}
|
|
@@ -1304,7 +1322,8 @@ var RelayClient = class {
|
|
|
1304
1322
|
localWs,
|
|
1305
1323
|
userId,
|
|
1306
1324
|
e2e: null,
|
|
1307
|
-
connectHandshakeComplete: false
|
|
1325
|
+
connectHandshakeComplete: false,
|
|
1326
|
+
challengeNonce: null
|
|
1308
1327
|
};
|
|
1309
1328
|
this.userConnections.set(userId, conn);
|
|
1310
1329
|
localWs.on("open", () => {
|
|
@@ -1339,6 +1358,13 @@ var RelayClient = class {
|
|
|
1339
1358
|
const conn = this.userConnections.get(userId);
|
|
1340
1359
|
if (!conn) return;
|
|
1341
1360
|
const parsed = msg;
|
|
1361
|
+
if (parsed.type === "event" && parsed.event === "connect.challenge") {
|
|
1362
|
+
const payload = parsed.payload;
|
|
1363
|
+
if (payload?.nonce) {
|
|
1364
|
+
conn.challengeNonce = payload.nonce;
|
|
1365
|
+
console.log(`[relay-client] Captured challenge nonce for user ${userId}`);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1342
1368
|
if (parsed.type === "res" && parsed.id === "connect-1" && parsed.ok) {
|
|
1343
1369
|
conn.connectHandshakeComplete = true;
|
|
1344
1370
|
}
|
|
@@ -1428,9 +1454,40 @@ function startRelayClient(api, relayUrl) {
|
|
|
1428
1454
|
|
|
1429
1455
|
// src/index.ts
|
|
1430
1456
|
function squadAppPlugin(api) {
|
|
1457
|
+
const toolExecutors = /* @__PURE__ */ new Map();
|
|
1458
|
+
const origRegisterTool = api.registerTool.bind(api);
|
|
1459
|
+
api.registerTool = (toolDef) => {
|
|
1460
|
+
if (toolDef.name && typeof toolDef.execute === "function") {
|
|
1461
|
+
toolExecutors.set(toolDef.name, toolDef.execute);
|
|
1462
|
+
}
|
|
1463
|
+
return origRegisterTool(toolDef);
|
|
1464
|
+
};
|
|
1431
1465
|
registerEntityTools(api);
|
|
1432
1466
|
registerFilesystemTools(api);
|
|
1433
1467
|
registerVersionMethods(api);
|
|
1468
|
+
api.registerGatewayMethod(
|
|
1469
|
+
"tools.invoke",
|
|
1470
|
+
async ({ params, respond }) => {
|
|
1471
|
+
const tool = params?.tool;
|
|
1472
|
+
const args = params?.args ?? {};
|
|
1473
|
+
if (!tool) {
|
|
1474
|
+
respond(false, { errorMessage: "Missing 'tool' parameter" });
|
|
1475
|
+
return;
|
|
1476
|
+
}
|
|
1477
|
+
const executeFn = toolExecutors.get(tool);
|
|
1478
|
+
if (!executeFn) {
|
|
1479
|
+
respond(false, { errorMessage: `Unknown tool: ${tool}` });
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
try {
|
|
1483
|
+
const result = await executeFn(`ws-${Date.now()}`, args);
|
|
1484
|
+
respond(true, result);
|
|
1485
|
+
} catch (err2) {
|
|
1486
|
+
const msg = err2 instanceof Error ? err2.message : String(err2);
|
|
1487
|
+
respond(false, { errorMessage: msg });
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1490
|
+
);
|
|
1434
1491
|
const relayEnabled = api.pluginConfig?.["relay.enabled"] ?? true;
|
|
1435
1492
|
if (relayEnabled) {
|
|
1436
1493
|
const relayUrl = api.pluginConfig?.["relay.url"] || "wss://relay.squad.ceo";
|
package/package.json
CHANGED