squad-openclaw 2026.2.2005 → 2026.2.2007
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 +3 -2
- package/package.json +1 -4
- package/dist/cli.js +0 -223
package/dist/index.js
CHANGED
|
@@ -2096,9 +2096,10 @@ function squadAppPlugin(api) {
|
|
|
2096
2096
|
respond(true, { tools: [...coreTools, ...groups, ...pluginTools] });
|
|
2097
2097
|
}
|
|
2098
2098
|
);
|
|
2099
|
-
const
|
|
2099
|
+
const relayState = readRelayState();
|
|
2100
|
+
const relayEnabled = !!(relayState.claimToken || relayState.roomId);
|
|
2100
2101
|
if (relayEnabled) {
|
|
2101
|
-
const relayUrl =
|
|
2102
|
+
const relayUrl = "wss://relay.squad.ceo";
|
|
2102
2103
|
startRelayClient(api, relayUrl);
|
|
2103
2104
|
}
|
|
2104
2105
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "squad-openclaw",
|
|
3
|
-
"version": "2026.2.
|
|
3
|
+
"version": "2026.2.2007",
|
|
4
4
|
"description": "Entity registry, filesystem tools, and version management plugin for OpenClaw gateway",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -16,9 +16,6 @@
|
|
|
16
16
|
"./dist/index.js"
|
|
17
17
|
]
|
|
18
18
|
},
|
|
19
|
-
"bin": {
|
|
20
|
-
"squad-pair": "./dist/cli.js"
|
|
21
|
-
},
|
|
22
19
|
"license": "MIT",
|
|
23
20
|
"files": [
|
|
24
21
|
"dist/",
|
package/dist/cli.js
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/cli.ts
|
|
4
|
-
import crypto2 from "crypto";
|
|
5
|
-
import fs2 from "fs";
|
|
6
|
-
import path2 from "path";
|
|
7
|
-
import os2 from "os";
|
|
8
|
-
import { execSync } from "child_process";
|
|
9
|
-
|
|
10
|
-
// src/device-keys.ts
|
|
11
|
-
import crypto from "crypto";
|
|
12
|
-
import fs from "fs";
|
|
13
|
-
import path from "path";
|
|
14
|
-
import os from "os";
|
|
15
|
-
var RELAY_DATA_DIR = path.join(os.homedir(), ".openclaw", "squad-ceo-data", "relay");
|
|
16
|
-
var RELAY_STATE_PATH = path.join(RELAY_DATA_DIR, "squad-relay.json");
|
|
17
|
-
var PENDING_APPROVAL_PATH = path.join(RELAY_DATA_DIR, "pending-approval.json");
|
|
18
|
-
function readRelayState() {
|
|
19
|
-
try {
|
|
20
|
-
const raw = fs.readFileSync(RELAY_STATE_PATH, "utf-8");
|
|
21
|
-
return JSON.parse(raw);
|
|
22
|
-
} catch {
|
|
23
|
-
return {};
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
function writeRelayState(state) {
|
|
27
|
-
if (!fs.existsSync(RELAY_DATA_DIR)) {
|
|
28
|
-
fs.mkdirSync(RELAY_DATA_DIR, { recursive: true });
|
|
29
|
-
}
|
|
30
|
-
fs.writeFileSync(RELAY_STATE_PATH, JSON.stringify(state, null, 2), { mode: 384 });
|
|
31
|
-
}
|
|
32
|
-
function toBase64Url(buf) {
|
|
33
|
-
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
34
|
-
}
|
|
35
|
-
function loadOrCreateRelayDeviceKeys() {
|
|
36
|
-
const state = readRelayState();
|
|
37
|
-
if (state.deviceKeys) {
|
|
38
|
-
return state.deviceKeys;
|
|
39
|
-
}
|
|
40
|
-
const { publicKey, privateKey } = crypto.generateKeyPairSync("ed25519");
|
|
41
|
-
const pubDer = publicKey.export({ type: "spki", format: "der" });
|
|
42
|
-
const rawPub = pubDer.subarray(pubDer.length - 32);
|
|
43
|
-
const deviceId = crypto.createHash("sha256").update(rawPub).digest("hex");
|
|
44
|
-
const publicKeyB64 = toBase64Url(rawPub);
|
|
45
|
-
const privateKeyPem = privateKey.export({ type: "pkcs8", format: "pem" });
|
|
46
|
-
const keys = { deviceId, publicKey: publicKeyB64, privateKeyPem };
|
|
47
|
-
writeRelayState({ ...state, deviceKeys: keys });
|
|
48
|
-
console.log(`[device-keys] Generated relay device identity: ${deviceId.substring(0, 12)}...`);
|
|
49
|
-
return keys;
|
|
50
|
-
}
|
|
51
|
-
function writeDeviceInfoFile(keys) {
|
|
52
|
-
const stateDir = process.env.OPENCLAW_STATE_DIR || path.join(os.homedir(), ".openclaw");
|
|
53
|
-
const infoPath = path.join(stateDir, "squad-ceo-data", "relay", "relay-device-info.json");
|
|
54
|
-
const info = {
|
|
55
|
-
deviceId: keys.deviceId,
|
|
56
|
-
publicKey: keys.publicKey,
|
|
57
|
-
displayName: "squad-relay",
|
|
58
|
-
platform: process.platform,
|
|
59
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
60
|
-
};
|
|
61
|
-
try {
|
|
62
|
-
fs.writeFileSync(infoPath, JSON.stringify(info, null, 2));
|
|
63
|
-
} catch (err) {
|
|
64
|
-
console.error("[device-keys] Failed to write relay-device-info.json:", err);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// src/cli.ts
|
|
69
|
-
var RELAY_URL = "https://relay.squad.ceo";
|
|
70
|
-
var DEVICES_DIR = path2.join(os2.homedir(), ".openclaw", "devices");
|
|
71
|
-
var PAIRED_JSON_PATH = path2.join(DEVICES_DIR, "paired.json");
|
|
72
|
-
function generateApprovalCode() {
|
|
73
|
-
const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
|
|
74
|
-
const bytes = crypto2.randomBytes(8);
|
|
75
|
-
let code = "";
|
|
76
|
-
for (let i = 0; i < 8; i++) {
|
|
77
|
-
code += chars[bytes[i] % chars.length];
|
|
78
|
-
}
|
|
79
|
-
return code;
|
|
80
|
-
}
|
|
81
|
-
function readPendingApproval() {
|
|
82
|
-
try {
|
|
83
|
-
const raw = fs2.readFileSync(PENDING_APPROVAL_PATH, "utf-8");
|
|
84
|
-
return JSON.parse(raw);
|
|
85
|
-
} catch {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function writePendingApproval(approval) {
|
|
90
|
-
if (!fs2.existsSync(RELAY_DATA_DIR)) {
|
|
91
|
-
fs2.mkdirSync(RELAY_DATA_DIR, { recursive: true });
|
|
92
|
-
}
|
|
93
|
-
fs2.writeFileSync(PENDING_APPROVAL_PATH, JSON.stringify(approval, null, 2));
|
|
94
|
-
}
|
|
95
|
-
async function handleRequest() {
|
|
96
|
-
const state = readRelayState();
|
|
97
|
-
if (!state.claimToken) {
|
|
98
|
-
console.error("Error: No claim token found in squad-relay.json.");
|
|
99
|
-
console.error("Run the setup from the Squad web app first to get a claim token.");
|
|
100
|
-
process.exit(1);
|
|
101
|
-
}
|
|
102
|
-
const keys = loadOrCreateRelayDeviceKeys();
|
|
103
|
-
console.log(`Device ID: ${keys.deviceId.substring(0, 16)}...`);
|
|
104
|
-
writeDeviceInfoFile(keys);
|
|
105
|
-
const code = generateApprovalCode();
|
|
106
|
-
const approval = {
|
|
107
|
-
code,
|
|
108
|
-
deviceId: keys.deviceId,
|
|
109
|
-
createdAt: Date.now()
|
|
110
|
-
};
|
|
111
|
-
writePendingApproval(approval);
|
|
112
|
-
console.log("Sending pairing request to relay...");
|
|
113
|
-
try {
|
|
114
|
-
const res = await fetch(`${RELAY_URL}/api/relay/device-pair-request`, {
|
|
115
|
-
method: "POST",
|
|
116
|
-
headers: { "Content-Type": "application/json" },
|
|
117
|
-
body: JSON.stringify({
|
|
118
|
-
claimToken: state.claimToken,
|
|
119
|
-
deviceId: keys.deviceId,
|
|
120
|
-
publicKey: keys.publicKey,
|
|
121
|
-
code
|
|
122
|
-
})
|
|
123
|
-
});
|
|
124
|
-
if (!res.ok) {
|
|
125
|
-
const text = await res.text();
|
|
126
|
-
console.error(`Error: Relay returned ${res.status}: ${text}`);
|
|
127
|
-
process.exit(1);
|
|
128
|
-
}
|
|
129
|
-
console.log("");
|
|
130
|
-
console.log("Pairing request sent successfully.");
|
|
131
|
-
console.log("Ask the user to check their Squad dashboard for the approval command.");
|
|
132
|
-
} catch (err) {
|
|
133
|
-
console.error("Error: Failed to reach relay server:", err.message);
|
|
134
|
-
process.exit(1);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
async function handleApprove(code) {
|
|
138
|
-
const pending = readPendingApproval();
|
|
139
|
-
if (!pending) {
|
|
140
|
-
console.error("Error: No pending pairing request found.");
|
|
141
|
-
console.error("Run 'squad-pair request' first.");
|
|
142
|
-
process.exit(1);
|
|
143
|
-
}
|
|
144
|
-
if (pending.code !== code.toUpperCase()) {
|
|
145
|
-
console.error("Error: Approval code does not match.");
|
|
146
|
-
console.error("Check the code shown in the Squad dashboard and try again.");
|
|
147
|
-
process.exit(1);
|
|
148
|
-
}
|
|
149
|
-
if (Date.now() - pending.createdAt > 30 * 60 * 1e3) {
|
|
150
|
-
console.error("Error: Pairing request has expired. Run 'squad-pair request' again.");
|
|
151
|
-
try {
|
|
152
|
-
fs2.unlinkSync(PENDING_APPROVAL_PATH);
|
|
153
|
-
} catch {
|
|
154
|
-
}
|
|
155
|
-
process.exit(1);
|
|
156
|
-
}
|
|
157
|
-
const state = readRelayState();
|
|
158
|
-
if (!state.deviceKeys) {
|
|
159
|
-
console.error("Error: No device keys found. Run 'squad-pair request' first.");
|
|
160
|
-
process.exit(1);
|
|
161
|
-
}
|
|
162
|
-
const { deviceId, publicKey } = state.deviceKeys;
|
|
163
|
-
let paired = {};
|
|
164
|
-
if (!fs2.existsSync(DEVICES_DIR)) {
|
|
165
|
-
fs2.mkdirSync(DEVICES_DIR, { recursive: true });
|
|
166
|
-
}
|
|
167
|
-
try {
|
|
168
|
-
const raw = fs2.readFileSync(PAIRED_JSON_PATH, "utf-8");
|
|
169
|
-
paired = JSON.parse(raw);
|
|
170
|
-
} catch {
|
|
171
|
-
}
|
|
172
|
-
paired[deviceId] = {
|
|
173
|
-
deviceId,
|
|
174
|
-
publicKey,
|
|
175
|
-
role: "operator",
|
|
176
|
-
scopes: ["operator"],
|
|
177
|
-
approvedAtMs: Date.now(),
|
|
178
|
-
displayName: "squad-relay"
|
|
179
|
-
};
|
|
180
|
-
fs2.writeFileSync(PAIRED_JSON_PATH, JSON.stringify(paired, null, 2));
|
|
181
|
-
console.log("Device paired successfully.");
|
|
182
|
-
try {
|
|
183
|
-
fs2.unlinkSync(PENDING_APPROVAL_PATH);
|
|
184
|
-
} catch {
|
|
185
|
-
}
|
|
186
|
-
console.log("Restarting gateway...");
|
|
187
|
-
try {
|
|
188
|
-
execSync("openclaw gateway restart", { stdio: "inherit" });
|
|
189
|
-
} catch {
|
|
190
|
-
console.error("Warning: Could not restart gateway automatically.");
|
|
191
|
-
console.error("Run 'openclaw gateway restart' manually.");
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
var args = process.argv.slice(2);
|
|
195
|
-
var command = args[0];
|
|
196
|
-
switch (command) {
|
|
197
|
-
case "request":
|
|
198
|
-
handleRequest().catch((err) => {
|
|
199
|
-
console.error("Fatal error:", err);
|
|
200
|
-
process.exit(1);
|
|
201
|
-
});
|
|
202
|
-
break;
|
|
203
|
-
case "approve": {
|
|
204
|
-
const code = args[1];
|
|
205
|
-
if (!code) {
|
|
206
|
-
console.error("Usage: squad-pair approve <CODE>");
|
|
207
|
-
console.error("The approval code is shown in your Squad dashboard.");
|
|
208
|
-
process.exit(1);
|
|
209
|
-
}
|
|
210
|
-
handleApprove(code).catch((err) => {
|
|
211
|
-
console.error("Fatal error:", err);
|
|
212
|
-
process.exit(1);
|
|
213
|
-
});
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
default:
|
|
217
|
-
console.log("squad-pair \u2014 Device pairing for Squad relay");
|
|
218
|
-
console.log("");
|
|
219
|
-
console.log("Commands:");
|
|
220
|
-
console.log(" squad-pair request Send a pairing request to the relay");
|
|
221
|
-
console.log(" squad-pair approve <CODE> Approve device pairing and restart gateway");
|
|
222
|
-
process.exit(command ? 1 : 0);
|
|
223
|
-
}
|