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.
Files changed (2) hide show
  1. package/dist/index.js +69 -12
  2. 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squad-openclaw",
3
- "version": "2026.2.1806",
3
+ "version": "2026.2.1809",
4
4
  "description": "Entity registry, filesystem tools, and version management plugin for OpenClaw gateway",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",