@chrysb/alphaclaw 0.8.3 → 0.8.4
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/lib/public/css/tailwind.generated.css +1 -1
- package/lib/public/dist/app.bundle.js +1274 -1168
- package/lib/public/js/components/agents-tab/create-channel-modal.js +259 -59
- package/lib/public/js/components/modal-shell.js +1 -1
- package/lib/public/js/lib/channel-provider-availability.js +1 -2
- package/lib/server/agents/channels.js +1 -4
- package/lib/server/exec-defaults-config.js +163 -0
- package/lib/server/init/server-lifecycle.js +2 -0
- package/lib/server/onboarding/index.js +5 -0
- package/lib/server/routes/nodes.js +9 -23
- package/lib/server/startup.js +8 -0
- package/lib/server/watchdog-notify.js +172 -55
- package/lib/server.js +14 -1
- package/package.json +2 -2
- package/patches/openclaw+2026.4.1.patch +13 -0
- package/patches/openclaw+2026.3.28.patch +0 -13
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
const path = require("path");
|
|
2
1
|
const crypto = require("crypto");
|
|
3
2
|
const { parseJsonObjectFromNoisyOutput } = require("../utils/json");
|
|
4
3
|
const { quoteShellArg } = require("../utils/shell");
|
|
4
|
+
const {
|
|
5
|
+
readExecApprovalsConfig,
|
|
6
|
+
writeExecApprovalsConfig,
|
|
7
|
+
} = require("../exec-defaults-config");
|
|
5
8
|
|
|
6
9
|
const kAllowedExecHosts = new Set(["gateway", "node"]);
|
|
7
10
|
const kAllowedExecSecurity = new Set(["deny", "allowlist", "full"]);
|
|
@@ -81,23 +84,6 @@ const parseNodeBrowserStatus = (stdout) => {
|
|
|
81
84
|
return decodedResult && typeof decodedResult === "object" ? decodedResult : null;
|
|
82
85
|
};
|
|
83
86
|
|
|
84
|
-
const readExecApprovalsFile = ({ fsModule, openclawDir }) => {
|
|
85
|
-
const filePath = path.join(openclawDir, "exec-approvals.json");
|
|
86
|
-
try {
|
|
87
|
-
const raw = fsModule.readFileSync(filePath, "utf8");
|
|
88
|
-
const parsed = JSON.parse(raw);
|
|
89
|
-
return parsed && typeof parsed === "object" ? parsed : { version: 1 };
|
|
90
|
-
} catch {
|
|
91
|
-
return { version: 1 };
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const writeExecApprovalsFile = ({ fsModule, openclawDir, file }) => {
|
|
96
|
-
const filePath = path.join(openclawDir, "exec-approvals.json");
|
|
97
|
-
fsModule.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
98
|
-
fsModule.writeFileSync(filePath, JSON.stringify(file, null, 2) + "\n", "utf8");
|
|
99
|
-
};
|
|
100
|
-
|
|
101
87
|
const ensureWildcardAgent = (file) => {
|
|
102
88
|
const agents = file.agents && typeof file.agents === "object" ? file.agents : {};
|
|
103
89
|
const wildcard =
|
|
@@ -372,7 +358,7 @@ const registerNodeRoutes = ({
|
|
|
372
358
|
|
|
373
359
|
app.get("/api/nodes/exec-approvals", (_req, res) => {
|
|
374
360
|
const approvals = ensureWildcardAgent(
|
|
375
|
-
|
|
361
|
+
readExecApprovalsConfig({ fsModule, openclawDir }),
|
|
376
362
|
);
|
|
377
363
|
const allowlist = approvals?.agents?.["*"]?.allowlist || [];
|
|
378
364
|
return res.json({
|
|
@@ -388,7 +374,7 @@ const registerNodeRoutes = ({
|
|
|
388
374
|
return res.status(400).json({ ok: false, error: "pattern is required" });
|
|
389
375
|
}
|
|
390
376
|
const approvals = ensureWildcardAgent(
|
|
391
|
-
|
|
377
|
+
readExecApprovalsConfig({ fsModule, openclawDir }),
|
|
392
378
|
);
|
|
393
379
|
const allowlist = approvals.agents["*"].allowlist;
|
|
394
380
|
const existing = allowlist.find(
|
|
@@ -403,7 +389,7 @@ const registerNodeRoutes = ({
|
|
|
403
389
|
lastUsedAt: Date.now(),
|
|
404
390
|
};
|
|
405
391
|
approvals.agents["*"].allowlist = [...allowlist, entry];
|
|
406
|
-
|
|
392
|
+
writeExecApprovalsConfig({ fsModule, openclawDir, file: approvals });
|
|
407
393
|
return res.json({ ok: true, entry });
|
|
408
394
|
});
|
|
409
395
|
|
|
@@ -413,7 +399,7 @@ const registerNodeRoutes = ({
|
|
|
413
399
|
return res.status(400).json({ ok: false, error: "id is required" });
|
|
414
400
|
}
|
|
415
401
|
const approvals = ensureWildcardAgent(
|
|
416
|
-
|
|
402
|
+
readExecApprovalsConfig({ fsModule, openclawDir }),
|
|
417
403
|
);
|
|
418
404
|
const allowlist = approvals.agents["*"].allowlist;
|
|
419
405
|
const nextAllowlist = allowlist.filter((entry) => String(entry?.id || "") !== id);
|
|
@@ -421,7 +407,7 @@ const registerNodeRoutes = ({
|
|
|
421
407
|
return res.status(404).json({ ok: false, error: "Allowlist entry not found" });
|
|
422
408
|
}
|
|
423
409
|
approvals.agents["*"].allowlist = nextAllowlist;
|
|
424
|
-
|
|
410
|
+
writeExecApprovalsConfig({ fsModule, openclawDir, file: approvals });
|
|
425
411
|
return res.json({ ok: true });
|
|
426
412
|
});
|
|
427
413
|
};
|
package/lib/server/startup.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const runOnboardedBootSequence = ({
|
|
2
|
+
ensureManagedExecDefaults,
|
|
2
3
|
ensureUsageTrackerPluginConfig,
|
|
3
4
|
doSyncPromptFiles,
|
|
4
5
|
reloadEnv,
|
|
@@ -10,6 +11,13 @@ const runOnboardedBootSequence = ({
|
|
|
10
11
|
watchdog,
|
|
11
12
|
gmailWatchService,
|
|
12
13
|
}) => {
|
|
14
|
+
try {
|
|
15
|
+
ensureManagedExecDefaults();
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.error(
|
|
18
|
+
`[alphaclaw] Failed to ensure managed exec defaults on boot: ${error.message}`,
|
|
19
|
+
);
|
|
20
|
+
}
|
|
13
21
|
try {
|
|
14
22
|
ensureUsageTrackerPluginConfig();
|
|
15
23
|
} catch (error) {
|
|
@@ -1,35 +1,95 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const { OPENCLAW_DIR } = require("./constants");
|
|
4
|
+
const { createSlackApi } = require("./slack-api");
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
+
const kSlackBotEnvKey = "SLACK_BOT_TOKEN";
|
|
7
|
+
|
|
8
|
+
const normalizeAccountId = (value) =>
|
|
9
|
+
String(value || "").trim().toLowerCase() || "default";
|
|
10
|
+
|
|
11
|
+
const resolveCredentialPairingAccountId = ({ channel, fileName }) => {
|
|
12
|
+
const prefix = `${String(channel || "").trim().toLowerCase()}-`;
|
|
13
|
+
const suffix = "-allowFrom.json";
|
|
14
|
+
const rawFileName = String(fileName || "").trim();
|
|
15
|
+
if (!rawFileName.startsWith(prefix) || !rawFileName.endsWith(suffix)) {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
return normalizeAccountId(rawFileName.slice(prefix.length, -suffix.length));
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const deriveSlackBotEnvKey = (accountId = "default") => {
|
|
22
|
+
const normalizedAccountId = normalizeAccountId(accountId);
|
|
23
|
+
if (normalizedAccountId === "default") return kSlackBotEnvKey;
|
|
24
|
+
return `${kSlackBotEnvKey}_${normalizedAccountId.replace(/-/g, "_").toUpperCase()}`;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const getPairedTargetsByAccount = ({
|
|
28
|
+
channel,
|
|
29
|
+
fsImpl = fs,
|
|
30
|
+
openclawDir = OPENCLAW_DIR,
|
|
31
|
+
}) => {
|
|
6
32
|
const safeChannel = String(channel || "").trim().toLowerCase();
|
|
7
|
-
if (!safeChannel) return
|
|
8
|
-
const credentialsDir = path.join(
|
|
9
|
-
if (!
|
|
10
|
-
const
|
|
33
|
+
if (!safeChannel) return new Map();
|
|
34
|
+
const credentialsDir = path.join(openclawDir, "credentials");
|
|
35
|
+
if (!fsImpl.existsSync(credentialsDir)) return new Map();
|
|
36
|
+
const idsByAccount = new Map();
|
|
11
37
|
try {
|
|
12
|
-
const files =
|
|
38
|
+
const files = fsImpl
|
|
13
39
|
.readdirSync(credentialsDir)
|
|
14
40
|
.filter(
|
|
15
41
|
(fileName) =>
|
|
16
42
|
fileName.startsWith(`${safeChannel}-`) && fileName.endsWith("-allowFrom.json"),
|
|
17
43
|
);
|
|
18
44
|
for (const fileName of files) {
|
|
45
|
+
const accountId = resolveCredentialPairingAccountId({
|
|
46
|
+
channel: safeChannel,
|
|
47
|
+
fileName,
|
|
48
|
+
});
|
|
49
|
+
if (!accountId) continue;
|
|
19
50
|
const filePath = path.join(credentialsDir, fileName);
|
|
20
|
-
const raw =
|
|
51
|
+
const raw = fsImpl.readFileSync(filePath, "utf8");
|
|
21
52
|
const parsed = JSON.parse(raw);
|
|
22
53
|
const allowFrom = Array.isArray(parsed?.allowFrom) ? parsed.allowFrom : [];
|
|
54
|
+
const ids =
|
|
55
|
+
idsByAccount.get(accountId) instanceof Set
|
|
56
|
+
? idsByAccount.get(accountId)
|
|
57
|
+
: new Set();
|
|
23
58
|
for (const id of allowFrom) {
|
|
24
59
|
if (id == null) continue;
|
|
25
60
|
const value = String(id).trim();
|
|
26
61
|
if (!value) continue;
|
|
27
62
|
ids.add(value);
|
|
28
63
|
}
|
|
64
|
+
idsByAccount.set(accountId, ids);
|
|
29
65
|
}
|
|
30
66
|
} catch (err) {
|
|
31
67
|
console.error(`[watchdog] could not resolve ${safeChannel} allowFrom IDs: ${err.message}`);
|
|
32
68
|
}
|
|
69
|
+
return new Map(
|
|
70
|
+
Array.from(idsByAccount.entries()).map(([accountId, ids]) => [
|
|
71
|
+
accountId,
|
|
72
|
+
Array.from(ids),
|
|
73
|
+
]),
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const getPairedIds = ({
|
|
78
|
+
channel,
|
|
79
|
+
fsImpl = fs,
|
|
80
|
+
openclawDir = OPENCLAW_DIR,
|
|
81
|
+
}) => {
|
|
82
|
+
const ids = new Set();
|
|
83
|
+
const idsByAccount = getPairedTargetsByAccount({
|
|
84
|
+
channel,
|
|
85
|
+
fsImpl,
|
|
86
|
+
openclawDir,
|
|
87
|
+
});
|
|
88
|
+
for (const accountIds of idsByAccount.values()) {
|
|
89
|
+
for (const id of accountIds) {
|
|
90
|
+
ids.add(id);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
33
93
|
return Array.from(ids);
|
|
34
94
|
};
|
|
35
95
|
|
|
@@ -38,18 +98,30 @@ const formatDiscordMessage = (message) =>
|
|
|
38
98
|
|
|
39
99
|
/**
|
|
40
100
|
* Track thread state for Slack notifications
|
|
41
|
-
* Key: userId, Value: { threadTs, lastEvent }
|
|
101
|
+
* Key: accountId:userId, Value: { threadTs, lastEvent }
|
|
42
102
|
*/
|
|
43
103
|
const slackThreads = new Map();
|
|
44
104
|
|
|
45
|
-
const createWatchdogNotifier = ({
|
|
105
|
+
const createWatchdogNotifier = ({
|
|
106
|
+
telegramApi,
|
|
107
|
+
discordApi,
|
|
108
|
+
slackApi,
|
|
109
|
+
readEnvFile = () => [],
|
|
110
|
+
createSlackApi: createSlackApiFactory = createSlackApi,
|
|
111
|
+
fsImpl = fs,
|
|
112
|
+
openclawDir = OPENCLAW_DIR,
|
|
113
|
+
}) => {
|
|
46
114
|
const notify = async (message, opts = {}) => {
|
|
47
115
|
const summary = {
|
|
48
116
|
telegram: { sent: 0, failed: 0, skipped: false, targets: 0 },
|
|
49
117
|
discord: { sent: 0, failed: 0, skipped: false, targets: 0 },
|
|
50
118
|
slack: { sent: 0, failed: 0, skipped: false, targets: 0 },
|
|
51
119
|
};
|
|
52
|
-
const telegramTargets = getPairedIds(
|
|
120
|
+
const telegramTargets = getPairedIds({
|
|
121
|
+
channel: "telegram",
|
|
122
|
+
fsImpl,
|
|
123
|
+
openclawDir,
|
|
124
|
+
});
|
|
53
125
|
summary.telegram.targets = telegramTargets.length;
|
|
54
126
|
if (!telegramApi?.sendMessage || !process.env.TELEGRAM_BOT_TOKEN || telegramTargets.length === 0) {
|
|
55
127
|
summary.telegram.skipped = true;
|
|
@@ -67,7 +139,11 @@ const createWatchdogNotifier = ({ telegramApi, discordApi, slackApi }) => {
|
|
|
67
139
|
}
|
|
68
140
|
}
|
|
69
141
|
|
|
70
|
-
const discordTargets = getPairedIds(
|
|
142
|
+
const discordTargets = getPairedIds({
|
|
143
|
+
channel: "discord",
|
|
144
|
+
fsImpl,
|
|
145
|
+
openclawDir,
|
|
146
|
+
});
|
|
71
147
|
summary.discord.targets = discordTargets.length;
|
|
72
148
|
if (!discordApi?.sendDirectMessage || !process.env.DISCORD_BOT_TOKEN || discordTargets.length === 0) {
|
|
73
149
|
summary.discord.skipped = true;
|
|
@@ -85,61 +161,102 @@ const createWatchdogNotifier = ({ telegramApi, discordApi, slackApi }) => {
|
|
|
85
161
|
}
|
|
86
162
|
|
|
87
163
|
// Enhanced Slack notifications with threading and reactions
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
164
|
+
const slackTargetsByAccount = getPairedTargetsByAccount({
|
|
165
|
+
channel: "slack",
|
|
166
|
+
fsImpl,
|
|
167
|
+
openclawDir,
|
|
168
|
+
});
|
|
169
|
+
summary.slack.targets = Array.from(slackTargetsByAccount.values()).reduce(
|
|
170
|
+
(total, targets) => total + targets.length,
|
|
171
|
+
0,
|
|
172
|
+
);
|
|
173
|
+
if (summary.slack.targets === 0) {
|
|
91
174
|
summary.slack.skipped = true;
|
|
92
175
|
} else {
|
|
93
176
|
const eventType = opts.eventType || "info"; // crash, recovery, health, info
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
177
|
+
const envVars = typeof readEnvFile === "function" ? readEnvFile() : [];
|
|
178
|
+
|
|
179
|
+
const envMap = new Map(
|
|
180
|
+
(Array.isArray(envVars) ? envVars : [])
|
|
181
|
+
.map((entry) => [
|
|
182
|
+
String(entry?.key || "").trim(),
|
|
183
|
+
String(entry?.value || "").trim(),
|
|
184
|
+
])
|
|
185
|
+
.filter(([key]) => key),
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
for (const [accountId, slackTargets] of slackTargetsByAccount.entries()) {
|
|
189
|
+
if (!slackTargets.length) continue;
|
|
190
|
+
const envKey = deriveSlackBotEnvKey(accountId);
|
|
191
|
+
const botToken = String(envMap.get(envKey) || process.env[envKey] || "").trim();
|
|
192
|
+
if (!botToken) {
|
|
193
|
+
summary.slack.failed += slackTargets.length;
|
|
194
|
+
for (const userId of slackTargets) {
|
|
195
|
+
console.error(
|
|
196
|
+
`[watchdog] slack notification failed for ${accountId}/${userId}: missing ${envKey}`,
|
|
197
|
+
);
|
|
106
198
|
}
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
107
201
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
202
|
+
const accountSlackApi =
|
|
203
|
+
accountId === "default" &&
|
|
204
|
+
slackApi?.postMessage &&
|
|
205
|
+
botToken === String(process.env.SLACK_BOT_TOKEN || "").trim()
|
|
206
|
+
? slackApi
|
|
207
|
+
: createSlackApiFactory(() => botToken);
|
|
208
|
+
|
|
209
|
+
for (const userId of slackTargets) {
|
|
210
|
+
try {
|
|
211
|
+
let threadTs = null;
|
|
212
|
+
let shouldCreateNewThread = true;
|
|
213
|
+
const threadKey = `${accountId}:${userId}`;
|
|
214
|
+
|
|
215
|
+
const existingThread = slackThreads.get(threadKey);
|
|
216
|
+
if (existingThread && existingThread.lastEvent === "crash" && eventType === "recovery") {
|
|
217
|
+
threadTs = existingThread.threadTs;
|
|
218
|
+
shouldCreateNewThread = false;
|
|
219
|
+
}
|
|
113
220
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
threadTs: result.ts,
|
|
118
|
-
lastEvent: eventType,
|
|
221
|
+
const result = await accountSlackApi.postMessage(userId, String(message || ""), {
|
|
222
|
+
thread_ts: threadTs,
|
|
223
|
+
mrkdwn: true,
|
|
119
224
|
});
|
|
120
|
-
}
|
|
121
225
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
226
|
+
if (shouldCreateNewThread && result.ts) {
|
|
227
|
+
slackThreads.set(threadKey, {
|
|
228
|
+
threadTs: result.ts,
|
|
229
|
+
lastEvent: eventType,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (result.ts && result.channel && accountSlackApi.addReaction) {
|
|
234
|
+
try {
|
|
235
|
+
if (eventType === "crash") {
|
|
236
|
+
await accountSlackApi.addReaction(result.channel, result.ts, "x");
|
|
237
|
+
} else if (eventType === "recovery") {
|
|
238
|
+
await accountSlackApi.addReaction(
|
|
239
|
+
result.channel,
|
|
240
|
+
result.ts,
|
|
241
|
+
"white_check_mark",
|
|
242
|
+
);
|
|
243
|
+
} else if (eventType === "health") {
|
|
244
|
+
await accountSlackApi.addReaction(result.channel, result.ts, "heart");
|
|
245
|
+
}
|
|
246
|
+
} catch (reactionErr) {
|
|
247
|
+
console.error(
|
|
248
|
+
`[watchdog] slack reaction failed for ${accountId}/${userId}: ${reactionErr.message}`,
|
|
249
|
+
);
|
|
132
250
|
}
|
|
133
|
-
} catch (reactionErr) {
|
|
134
|
-
// Reactions are nice-to-have, don't fail the whole notification
|
|
135
|
-
console.error(`[watchdog] slack reaction failed for ${userId}: ${reactionErr.message}`);
|
|
136
251
|
}
|
|
137
|
-
}
|
|
138
252
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
253
|
+
summary.slack.sent += 1;
|
|
254
|
+
} catch (err) {
|
|
255
|
+
summary.slack.failed += 1;
|
|
256
|
+
console.error(
|
|
257
|
+
`[watchdog] slack notification failed for ${accountId}/${userId}: ${err.message}`,
|
|
258
|
+
);
|
|
259
|
+
}
|
|
143
260
|
}
|
|
144
261
|
}
|
|
145
262
|
}
|
package/lib/server.js
CHANGED
|
@@ -138,6 +138,9 @@ const {
|
|
|
138
138
|
const {
|
|
139
139
|
ensureUsageTrackerPluginConfig,
|
|
140
140
|
} = require("./server/usage-tracker-config");
|
|
141
|
+
const {
|
|
142
|
+
ensureManagedExecDefaults,
|
|
143
|
+
} = require("./server/exec-defaults-config");
|
|
141
144
|
|
|
142
145
|
const { PORT, kTrustProxyHops, SETUP_API_PREFIXES } = constants;
|
|
143
146
|
|
|
@@ -223,7 +226,12 @@ const webhookMiddleware = createWebhookMiddleware({
|
|
|
223
226
|
const telegramApi = createTelegramApi(() => process.env.TELEGRAM_BOT_TOKEN);
|
|
224
227
|
const discordApi = createDiscordApi(() => process.env.DISCORD_BOT_TOKEN);
|
|
225
228
|
const slackApi = createSlackApi(() => process.env.SLACK_BOT_TOKEN);
|
|
226
|
-
const watchdogNotifier = createWatchdogNotifier({
|
|
229
|
+
const watchdogNotifier = createWatchdogNotifier({
|
|
230
|
+
telegramApi,
|
|
231
|
+
discordApi,
|
|
232
|
+
slackApi,
|
|
233
|
+
readEnvFile,
|
|
234
|
+
});
|
|
227
235
|
const watchdog = createWatchdog({
|
|
228
236
|
clawCmd,
|
|
229
237
|
launchGatewayProcess,
|
|
@@ -379,6 +387,11 @@ startServerLifecycle({
|
|
|
379
387
|
PORT,
|
|
380
388
|
isOnboarded,
|
|
381
389
|
runOnboardedBootSequence,
|
|
390
|
+
ensureManagedExecDefaults: () =>
|
|
391
|
+
ensureManagedExecDefaults({
|
|
392
|
+
fsModule: fs,
|
|
393
|
+
openclawDir: constants.OPENCLAW_DIR,
|
|
394
|
+
}),
|
|
382
395
|
ensureUsageTrackerPluginConfig: () =>
|
|
383
396
|
ensureUsageTrackerPluginConfig({
|
|
384
397
|
fsModule: fs,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chrysb/alphaclaw",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"express": "^4.21.0",
|
|
38
38
|
"http-proxy": "^1.18.1",
|
|
39
|
-
"openclaw": "2026.
|
|
39
|
+
"openclaw": "2026.4.1",
|
|
40
40
|
"patch-package": "^8.0.1",
|
|
41
41
|
"ws": "^8.19.0"
|
|
42
42
|
},
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
diff --git a/node_modules/openclaw/dist/gateway-cli-6Ksv5U_O.js b/node_modules/openclaw/dist/gateway-cli-6Ksv5U_O.js
|
|
2
|
+
index 4c742cee..bb87239b 100644
|
|
3
|
+
--- a/node_modules/openclaw/dist/gateway-cli-6Ksv5U_O.js
|
|
4
|
+
+++ b/node_modules/openclaw/dist/gateway-cli-6Ksv5U_O.js
|
|
5
|
+
@@ -26669,7 +26669,7 @@ function attachGatewayWsMessageHandler(params) {
|
|
6
|
+
close(1008, truncateCloseReason(authMessage));
|
|
7
|
+
};
|
|
8
|
+
const clearUnboundScopes = () => {
|
|
9
|
+
- if (scopes.length > 0) {
|
|
10
|
+
+ if (scopes.length > 0 && !sharedAuthOk) {
|
|
11
|
+
scopes = [];
|
|
12
|
+
connectParams.scopes = scopes;
|
|
13
|
+
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
diff --git a/node_modules/openclaw/dist/gateway-cli-DlnlX7IW.js b/node_modules/openclaw/dist/gateway-cli-DlnlX7IW.js
|
|
2
|
-
index ca48b932..c12478c4 100644
|
|
3
|
-
--- a/node_modules/openclaw/dist/gateway-cli-DlnlX7IW.js
|
|
4
|
-
+++ b/node_modules/openclaw/dist/gateway-cli-DlnlX7IW.js
|
|
5
|
-
@@ -25935,7 +25935,7 @@ function attachGatewayWsMessageHandler(params) {
|
|
6
|
-
close(1008, truncateCloseReason(authMessage));
|
|
7
|
-
};
|
|
8
|
-
const clearUnboundScopes = () => {
|
|
9
|
-
- if (scopes.length > 0) {
|
|
10
|
-
+ if (scopes.length > 0 && !sharedAuthOk) {
|
|
11
|
-
scopes = [];
|
|
12
|
-
connectParams.scopes = scopes;
|
|
13
|
-
}
|