squad-openclaw 2026.2.199 → 2026.2.1802

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 +24 -37
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -991,73 +991,60 @@ function writeRelayState(state) {
991
991
  function toBase64Url(buf) {
992
992
  return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
993
993
  }
994
- function loadOrCreateDeviceKeys() {
995
- const keysPath = path5.join(os.homedir(), ".openclaw", "squad-relay-keys.json");
996
- try {
997
- const raw = fs5.readFileSync(keysPath, "utf-8");
998
- const keys2 = JSON.parse(raw);
999
- if (keys2.deviceId && keys2.publicKey && keys2.privateKey) {
1000
- return keys2;
1001
- }
1002
- } catch {
994
+ function loadOrCreateRelayDeviceKeys() {
995
+ const state = readRelayState();
996
+ if (state.deviceKeys) {
997
+ return state.deviceKeys;
1003
998
  }
1004
999
  const { publicKey, privateKey } = crypto2.generateKeyPairSync("ed25519");
1005
1000
  const pubDer = publicKey.export({ type: "spki", format: "der" });
1006
- const privDer = privateKey.export({ type: "pkcs8", format: "der" });
1007
1001
  const rawPub = pubDer.subarray(pubDer.length - 32);
1008
1002
  const deviceId = crypto2.createHash("sha256").update(rawPub).digest("hex");
1009
- const pubB64 = toBase64Url(rawPub);
1010
- const privB64 = toBase64Url(privDer);
1011
- const keys = { deviceId, publicKey: pubB64, privateKey: privB64 };
1012
- const dir = path5.dirname(keysPath);
1013
- if (!fs5.existsSync(dir)) {
1014
- fs5.mkdirSync(dir, { recursive: true });
1015
- }
1016
- fs5.writeFileSync(keysPath, JSON.stringify(keys, null, 2), { mode: 384 });
1017
- console.log(`[relay-client] Generated new device keys: ${deviceId.substring(0, 12)}...`);
1003
+ const publicKeyB64 = toBase64Url(rawPub);
1004
+ const privateKeyPem = privateKey.export({ type: "pkcs8", format: "pem" });
1005
+ const keys = { deviceId, publicKey: publicKeyB64, privateKeyPem };
1006
+ writeRelayState({ ...state, deviceKeys: keys });
1007
+ console.log(`[relay-client] Generated relay device identity: ${deviceId.substring(0, 12)}...`);
1018
1008
  return keys;
1019
1009
  }
1020
- function ensureDevicePaired(keys) {
1010
+ function ensureDevicePaired(keys, operatorToken) {
1021
1011
  const stateDir = process.env.OPENCLAW_STATE_DIR || path5.join(os.homedir(), ".openclaw");
1022
1012
  const pairedPath = path5.join(stateDir, "devices", "paired.json");
1023
1013
  let paired = {};
1024
1014
  try {
1025
- const raw = fs5.readFileSync(pairedPath, "utf-8");
1026
- paired = JSON.parse(raw);
1015
+ paired = JSON.parse(fs5.readFileSync(pairedPath, "utf-8"));
1027
1016
  } catch {
1028
1017
  }
1029
- if (paired[keys.deviceId]) {
1030
- return;
1031
- }
1018
+ if (paired[keys.deviceId]) return;
1032
1019
  const now = Date.now();
1020
+ const scopes = ["operator.admin", "operator.approvals", "operator.pairing"];
1033
1021
  paired[keys.deviceId] = {
1034
1022
  deviceId: keys.deviceId,
1035
1023
  publicKey: keys.publicKey,
1036
1024
  platform: process.platform,
1037
1025
  clientId: "cli",
1038
- clientMode: "ui",
1026
+ clientMode: "backend",
1039
1027
  role: "operator",
1040
1028
  roles: ["operator"],
1041
- scopes: ["operator.admin", "operator.read", "operator.write"],
1042
- tokens: {},
1029
+ scopes,
1030
+ tokens: operatorToken ? {
1031
+ operator: { token: operatorToken, role: "operator", scopes, createdAtMs: now, lastUsedAtMs: now }
1032
+ } : {},
1043
1033
  createdAtMs: now,
1044
1034
  approvedAtMs: now,
1045
1035
  displayName: "squad-relay"
1046
1036
  };
1047
1037
  const dir = path5.dirname(pairedPath);
1048
- if (!fs5.existsSync(dir)) {
1049
- fs5.mkdirSync(dir, { recursive: true });
1050
- }
1051
- fs5.writeFileSync(pairedPath, JSON.stringify(paired, null, 2));
1052
- console.log(`[relay-client] Auto-registered device in gateway store: ${keys.deviceId.substring(0, 12)}...`);
1038
+ if (!fs5.existsSync(dir)) fs5.mkdirSync(dir, { recursive: true });
1039
+ fs5.writeFileSync(pairedPath, JSON.stringify(paired, null, 2), { mode: 384 });
1040
+ console.log(`[relay-client] Device pairing entry created in paired.json`);
1053
1041
  }
1054
1042
  function signDeviceIdentity(keys, clientId, clientMode, role, scopes, token) {
1055
1043
  const signedAtMs = Date.now();
1056
1044
  const nonce = crypto2.randomBytes(16).toString("hex");
1057
1045
  const scopeStr = scopes.join(",");
1058
1046
  const payload = `v2|${keys.deviceId}|${clientId}|${clientMode}|${role}|${scopeStr}|${signedAtMs}|${token ?? ""}|${nonce}`;
1059
- const privDer = Buffer.from(keys.privateKey.replace(/-/g, "+").replace(/_/g, "/") + "==", "base64");
1060
- const privateKey = crypto2.createPrivateKey({ key: privDer, format: "der", type: "pkcs8" });
1047
+ const privateKey = crypto2.createPrivateKey(keys.privateKeyPem);
1061
1048
  const signature = crypto2.sign(null, Buffer.from(payload), privateKey);
1062
1049
  return {
1063
1050
  id: keys.deviceId,
@@ -1090,8 +1077,8 @@ var RelayClient = class {
1090
1077
  roomId: config.roomId ?? state.roomId ?? null
1091
1078
  };
1092
1079
  this.pendingClaimToken = this.config.claimToken;
1093
- this.deviceKeys = loadOrCreateDeviceKeys();
1094
- ensureDevicePaired(this.deviceKeys);
1080
+ this.deviceKeys = loadOrCreateRelayDeviceKeys();
1081
+ ensureDevicePaired(this.deviceKeys, this.config.operatorToken);
1095
1082
  }
1096
1083
  /** Start connecting to the relay */
1097
1084
  start() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squad-openclaw",
3
- "version": "2026.2.199",
3
+ "version": "2026.2.1802",
4
4
  "description": "Entity registry, filesystem tools, and version management plugin for OpenClaw gateway",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",