squad-openclaw 2026.2.2002 → 2026.2.2004

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/README.md CHANGED
@@ -31,7 +31,7 @@ These directories are **completely blocked** from all filesystem operations (rea
31
31
 
32
32
  | Path | Reason |
33
33
  |---|---|
34
- | `~/.openclaw/squad-ceo-data/squad-relay.json` | Contains ed25519 private key for relay device identity |
34
+ | `~/.openclaw/squad-ceo-data/relay/squad-relay.json` | Contains ed25519 private key for relay device identity |
35
35
  | `~/.openclaw/*.bak` | Backup files at the top level contain unredacted config (tokens, keys) that would bypass redaction |
36
36
 
37
37
  ### Layer 2: Redacted Files (hardcoded, non-configurable)
@@ -60,7 +60,7 @@ Operators can customize via the `fs.allowedRoots` config option.
60
60
  These files/directories cannot be written to, even if they fall within `allowedRoots`:
61
61
 
62
62
  - `~/.openclaw/openclaw.json` — operator configuration (read-only with redaction)
63
- - `~/.openclaw/squad-ceo-data/squad-relay.json` — relay device private key
63
+ - `~/.openclaw/squad-ceo-data/relay/squad-relay.json` — relay device private key
64
64
  - All blocked directories above (credentials, devices, identity)
65
65
  - All `.bak` files at `~/.openclaw/` top level
66
66
 
package/dist/index.d.ts CHANGED
@@ -21,11 +21,11 @@
21
21
  * │ REDACTED on read (sensitive fields replaced with "[REDACTED]"): │
22
22
  * │ • ~/.openclaw/openclaw.json → channel.*.botToken │
23
23
  * │ • ~/.openclaw/openclaw.json → gateway.auth.* │
24
- * │ • squad-ceo-data/squad-relay.json → deviceKeys.privateKeyPem
24
+ * │ • squad-ceo-data/relay/squad-relay.json → deviceKeys.privateKeyPem
25
25
  * │ │
26
26
  * │ WRITE-PROTECTED (no writes, deletes, or renames): │
27
27
  * │ • ~/.openclaw/openclaw.json │
28
- * │ • squad-ceo-data/squad-relay.json
28
+ * │ • squad-ceo-data/relay/squad-relay.json
29
29
  * │ • All blocked directories above │
30
30
  * │ │
31
31
  * │ The bundle is NOT minified to allow security auditing of the │
package/dist/index.js CHANGED
@@ -1,3 +1,107 @@
1
+ // src/agents.ts
2
+ import { execSync } from "child_process";
3
+ function registerAgentMethods(api) {
4
+ api.registerGatewayMethod(
5
+ "squad.agents.add",
6
+ async ({ params, respond }) => {
7
+ const name = params?.name;
8
+ const model = params?.model;
9
+ if (!name || typeof name !== "string" || !name.trim()) {
10
+ respond(false, { error: "Missing or empty 'name' parameter" });
11
+ return;
12
+ }
13
+ const safeName = name.trim();
14
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9 _-]*$/.test(safeName)) {
15
+ respond(false, { error: "Agent name must start with a letter/number and contain only letters, numbers, spaces, hyphens, or underscores" });
16
+ return;
17
+ }
18
+ try {
19
+ let cmd = `openclaw agents add ${JSON.stringify(safeName)} --non-interactive`;
20
+ if (model) {
21
+ cmd += ` --model ${JSON.stringify(model)}`;
22
+ }
23
+ const output = execSync(cmd, {
24
+ timeout: 3e4,
25
+ encoding: "utf-8",
26
+ stdio: ["pipe", "pipe", "pipe"]
27
+ });
28
+ respond(true, { ok: true, output: output.slice(0, 1e3) });
29
+ } catch (err2) {
30
+ const msg = err2 instanceof Error ? err2.message : String(err2);
31
+ const stderr = err2?.stderr;
32
+ respond(false, {
33
+ error: `Failed to add agent: ${stderr || msg}`.slice(0, 500)
34
+ });
35
+ }
36
+ }
37
+ );
38
+ api.registerGatewayMethod(
39
+ "squad.agents.delete",
40
+ async ({ params, respond }) => {
41
+ const agentId = params?.agentId;
42
+ if (!agentId || typeof agentId !== "string" || !agentId.trim()) {
43
+ respond(false, { error: "Missing or empty 'agentId' parameter" });
44
+ return;
45
+ }
46
+ if (agentId === "main") {
47
+ respond(false, { error: "Cannot delete the main agent" });
48
+ return;
49
+ }
50
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(agentId)) {
51
+ respond(false, { error: "Invalid agent ID format" });
52
+ return;
53
+ }
54
+ try {
55
+ const output = execSync(
56
+ `openclaw agents delete ${JSON.stringify(agentId)} --non-interactive 2>&1`,
57
+ { timeout: 3e4, encoding: "utf-8" }
58
+ );
59
+ respond(true, { ok: true, output: output.slice(0, 1e3) });
60
+ } catch (err2) {
61
+ const msg = err2 instanceof Error ? err2.message : String(err2);
62
+ const stderr = err2?.stderr;
63
+ respond(false, {
64
+ error: `Failed to delete agent: ${stderr || msg}`.slice(0, 500)
65
+ });
66
+ }
67
+ }
68
+ );
69
+ api.registerGatewayMethod(
70
+ "squad.agents.set-identity",
71
+ async ({ params, respond }) => {
72
+ const agentId = params?.agentId;
73
+ const name = params?.name;
74
+ const emoji = params?.emoji;
75
+ const theme = params?.theme;
76
+ if (!agentId || typeof agentId !== "string") {
77
+ respond(false, { error: "Missing 'agentId' parameter" });
78
+ return;
79
+ }
80
+ const args = [`--agent`, JSON.stringify(agentId)];
81
+ if (name) args.push(`--name`, JSON.stringify(name));
82
+ if (emoji) args.push(`--emoji`, JSON.stringify(emoji));
83
+ if (theme) args.push(`--theme`, JSON.stringify(theme));
84
+ if (args.length <= 2) {
85
+ respond(false, { error: "No identity fields provided (name, emoji, or theme)" });
86
+ return;
87
+ }
88
+ try {
89
+ const output = execSync(
90
+ `openclaw agents set-identity ${args.join(" ")} 2>&1`,
91
+ { timeout: 15e3, encoding: "utf-8" }
92
+ );
93
+ respond(true, { ok: true, output: output.slice(0, 1e3) });
94
+ } catch (err2) {
95
+ const msg = err2 instanceof Error ? err2.message : String(err2);
96
+ const stderr = err2?.stderr;
97
+ respond(false, {
98
+ error: `Failed to set identity: ${stderr || msg}`.slice(0, 500)
99
+ });
100
+ }
101
+ }
102
+ );
103
+ }
104
+
1
105
  // src/entities.ts
2
106
  import { Type as T } from "@sinclair/typebox";
3
107
  import path3 from "path";
@@ -266,7 +370,7 @@ var SENSITIVE_BLOCKED_DIRS = [
266
370
  path2.join(OPENCLAW_DIR, "identity")
267
371
  ];
268
372
  var SENSITIVE_BLOCKED_FILES = [
269
- path2.join(OPENCLAW_DIR, "squad-ceo-data", "squad-relay.json")
373
+ path2.join(OPENCLAW_DIR, "squad-ceo-data", "relay", "squad-relay.json")
270
374
  ];
271
375
  function isSensitivePath(resolvedPath) {
272
376
  for (const blocked of SENSITIVE_BLOCKED_DIRS) {
@@ -1111,11 +1215,16 @@ function registerSqlTools(api) {
1111
1215
  }
1112
1216
 
1113
1217
  // src/version.ts
1114
- import { execSync } from "child_process";
1218
+ import { execSync as execSync2 } from "child_process";
1115
1219
  import fs5 from "fs";
1116
1220
  import path5 from "path";
1117
1221
  import { fileURLToPath } from "url";
1118
1222
  var PACKAGE_NAME = "squad-openclaw";
1223
+ var CONFIG_PATH = path5.join(
1224
+ process.env.HOME ?? "/root",
1225
+ ".openclaw",
1226
+ "openclaw.json"
1227
+ );
1119
1228
  function getCurrentVersion() {
1120
1229
  const thisFile = fileURLToPath(import.meta.url);
1121
1230
  const pkgPath = path5.resolve(path5.dirname(thisFile), "..", "package.json");
@@ -1175,18 +1284,36 @@ function registerVersionMethods(api) {
1175
1284
  try {
1176
1285
  const before = getCurrentVersion();
1177
1286
  let updateOutput = "";
1287
+ let configBackup = null;
1288
+ try {
1289
+ configBackup = fs5.readFileSync(CONFIG_PATH, "utf-8");
1290
+ } catch {
1291
+ }
1292
+ try {
1293
+ execSync2("openclaw doctor --fix 2>&1", {
1294
+ timeout: 3e4,
1295
+ encoding: "utf-8"
1296
+ });
1297
+ } catch {
1298
+ }
1178
1299
  try {
1179
- updateOutput = execSync(
1300
+ updateOutput = execSync2(
1180
1301
  `openclaw plugins update ${PACKAGE_NAME} 2>&1`,
1181
1302
  { timeout: 12e4, encoding: "utf-8" }
1182
1303
  );
1183
1304
  } catch {
1184
1305
  try {
1185
- updateOutput = execSync(
1306
+ updateOutput = execSync2(
1186
1307
  `npm install -g ${PACKAGE_NAME}@latest 2>&1`,
1187
1308
  { timeout: 12e4, encoding: "utf-8" }
1188
1309
  );
1189
1310
  } catch (npmErr) {
1311
+ if (configBackup) {
1312
+ try {
1313
+ fs5.writeFileSync(CONFIG_PATH, configBackup, "utf-8");
1314
+ } catch {
1315
+ }
1316
+ }
1190
1317
  const msg = npmErr instanceof Error ? npmErr.message : String(npmErr);
1191
1318
  respond(false, {
1192
1319
  error: `Update failed: ${msg}`,
@@ -1208,7 +1335,7 @@ function registerVersionMethods(api) {
1208
1335
  );
1209
1336
  setTimeout(() => {
1210
1337
  try {
1211
- execSync("openclaw gateway restart 2>&1", {
1338
+ execSync2("openclaw gateway restart 2>&1", {
1212
1339
  timeout: 3e4,
1213
1340
  encoding: "utf-8"
1214
1341
  });
@@ -1319,7 +1446,7 @@ function readOperatorToken() {
1319
1446
  return null;
1320
1447
  }
1321
1448
  }
1322
- var RELAY_DATA_DIR = path6.join(os.homedir(), ".openclaw", "squad-ceo-data");
1449
+ var RELAY_DATA_DIR = path6.join(os.homedir(), ".openclaw", "squad-ceo-data", "relay");
1323
1450
  var RELAY_STATE_PATH = path6.join(RELAY_DATA_DIR, "squad-relay.json");
1324
1451
  function readRelayState() {
1325
1452
  try {
@@ -1356,7 +1483,7 @@ function loadOrCreateRelayDeviceKeys() {
1356
1483
  }
1357
1484
  function writeDeviceInfoFile(keys) {
1358
1485
  const stateDir = process.env.OPENCLAW_STATE_DIR || path6.join(os.homedir(), ".openclaw");
1359
- const infoPath = path6.join(stateDir, "squad-ceo-data", "relay-device-info.json");
1486
+ const infoPath = path6.join(stateDir, "squad-ceo-data", "relay", "relay-device-info.json");
1360
1487
  const info = {
1361
1488
  deviceId: keys.deviceId,
1362
1489
  publicKey: keys.publicKey,
@@ -1895,6 +2022,7 @@ function squadAppPlugin(api) {
1895
2022
  registerFilesystemTools(api);
1896
2023
  registerSqlTools(api);
1897
2024
  registerVersionMethods(api);
2025
+ registerAgentMethods(api);
1898
2026
  api.registerGatewayMethod(
1899
2027
  "tools.invoke",
1900
2028
  async ({ params, respond }) => {
@@ -10,7 +10,7 @@
10
10
  "type": "array",
11
11
  "items": { "type": "string" },
12
12
  "default": ["~/.openclaw"],
13
- "description": "Restrict filesystem operations to these directories. Defaults to [\"~/.openclaw\"]. Hardcoded blocks on credentials/, devices/, identity/, squad-relay.json, and .bak files always apply."
13
+ "description": "Restrict filesystem operations to these directories. Defaults to [\"~/.openclaw\"]. Hardcoded blocks on credentials/, devices/, identity/, relay/squad-relay.json, and .bak files always apply."
14
14
  },
15
15
  "relay.enabled": {
16
16
  "type": "boolean",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squad-openclaw",
3
- "version": "2026.2.2002",
3
+ "version": "2026.2.2004",
4
4
  "description": "Entity registry, filesystem tools, and version management plugin for OpenClaw gateway",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",