@openclaw/mattermost 2026.7.1 → 2026.7.2-beta.1

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.
@@ -0,0 +1,19 @@
1
+ import { createLegacyPrivateNetworkDoctorContract } from "openclaw/plugin-sdk/ssrf-runtime";
2
+ import { defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor";
3
+ //#region extensions/mattermost/src/doctor-contract.ts
4
+ const networkContract = createLegacyPrivateNetworkDoctorContract({ channelKey: "mattermost" });
5
+ const streamingAliasMigration = defineChannelAliasMigration({
6
+ channelId: "mattermost",
7
+ streaming: { defaultMode: "partial" },
8
+ accountStreamingReplacesRoot: true
9
+ });
10
+ const legacyConfigRules = [...networkContract.legacyConfigRules, ...streamingAliasMigration.legacyConfigRules];
11
+ function normalizeCompatibilityConfig({ cfg }) {
12
+ const network = networkContract.normalizeCompatibilityConfig({ cfg });
13
+ return streamingAliasMigration.normalizeChannelConfig({
14
+ cfg: network.config,
15
+ changes: network.changes
16
+ });
17
+ }
18
+ //#endregion
19
+ export { normalizeCompatibilityConfig as n, legacyConfigRules as t };
@@ -1,2 +1,2 @@
1
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-ttH0DCuq.js";
1
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-BaUvVh8e.js";
2
2
  export { legacyConfigRules, normalizeCompatibilityConfig };
@@ -1,2 +1,2 @@
1
- import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-BIXLORHU.js";
1
+ import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-CL1PxV3z.js";
2
2
  export { resolveMattermostGatewayAuthBypassPaths as resolveGatewayAuthBypassPaths };
@@ -23,8 +23,9 @@ function collectMattermostSlashCallbackPaths(raw) {
23
23
  } catch {}
24
24
  return [...paths];
25
25
  }
26
- function resolveMattermostGatewayAuthBypassPaths(cfg) {
27
- const base = cfg.channels?.mattermost && typeof cfg.channels.mattermost === "object" ? cfg.channels.mattermost : void 0;
26
+ function resolveMattermostGatewayAuthBypassPaths(params) {
27
+ const channels = params.cfg.channels;
28
+ const base = channels?.mattermost && typeof channels.mattermost === "object" ? channels.mattermost : void 0;
28
29
  const callbackPaths = new Set(collectMattermostSlashCallbackPaths(readMattermostCommands(base?.commands)).filter(isMattermostBypassPath));
29
30
  const accounts = base?.accounts ?? {};
30
31
  for (const account of Object.values(accounts)) {
@@ -0,0 +1,28 @@
1
+ import { collectSimpleChannelFieldAssignments, createChannelSecretTargetRegistryEntries, getChannelSurface } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
2
+ //#region extensions/mattermost/src/secret-contract.ts
3
+ const secretTargetRegistryEntries = createChannelSecretTargetRegistryEntries({
4
+ channelKey: "mattermost",
5
+ account: ["botToken"],
6
+ channel: ["botToken"]
7
+ });
8
+ function collectRuntimeConfigAssignments(params) {
9
+ const resolved = getChannelSurface(params.config, "mattermost");
10
+ if (!resolved) return;
11
+ const { channel: mattermost, surface } = resolved;
12
+ collectSimpleChannelFieldAssignments({
13
+ channelKey: "mattermost",
14
+ field: "botToken",
15
+ channel: mattermost,
16
+ surface,
17
+ defaults: params.defaults,
18
+ context: params.context,
19
+ topInactiveReason: "no enabled account inherits this top-level Mattermost botToken.",
20
+ accountInactiveReason: "Mattermost account is disabled."
21
+ });
22
+ }
23
+ const channelSecrets = {
24
+ secretTargetRegistryEntries,
25
+ collectRuntimeConfigAssignments
26
+ };
27
+ //#endregion
28
+ export { collectRuntimeConfigAssignments as n, secretTargetRegistryEntries as r, channelSecrets as t };
@@ -1,2 +1,2 @@
1
- import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-Cx0LUNXy.js";
1
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-B4R5Bmhv.js";
2
2
  export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
@@ -1,2 +1,2 @@
1
- import { i as registerSlashCommandRoute } from "./slash-state-BfOSlkmn.js";
1
+ import { i as registerSlashCommandRoute } from "./slash-state-Cr58Xd12.js";
2
2
  export { registerSlashCommandRoute };
@@ -1,5 +1,5 @@
1
1
  import { a as normalizeMattermostAllowList, b as readRequestBodyWithLimit, d as createChannelMessageReplyPipeline, g as loadOutboundMediaFromUrl, l as buildModelsProviderData, m as isTrustedProxyAddress, p as isRequestBodyLimitError, t as authorizeMattermostCommandInvocation, v as logTypingFailure, w as resolveClientIp } from "./monitor-auth-BiDuyvOc.js";
2
- import { b as updateMattermostPost, c as createMattermostPost, d as fetchMattermostChannelByName, f as fetchMattermostMe, g as normalizeMattermostBaseUrl, h as fetchMattermostUserTeams, m as fetchMattermostUserByUsername, o as createMattermostClient, p as fetchMattermostUser, r as resolveMattermostAccount, s as createMattermostDirectChannelWithRetry, u as fetchMattermostChannel, v as resolveMattermostReplyDeliveryBarrierTimeoutMs, x as uploadMattermostFile, y as sendMattermostTyping } from "./accounts-ITTlduDO.js";
2
+ import { b as updateMattermostPost, c as createMattermostPost, d as fetchMattermostChannelByName, f as fetchMattermostMe, g as normalizeMattermostBaseUrl, h as fetchMattermostUserTeams, m as fetchMattermostUserByUsername, o as createMattermostClient, p as fetchMattermostUser, r as resolveMattermostAccount, s as createMattermostDirectChannelWithRetry, u as fetchMattermostChannel, v as resolveMattermostReplyDeliveryBarrierTimeoutMs, x as uploadMattermostFile, y as sendMattermostTyping } from "./accounts-B2NRPlqr.js";
3
3
  import { t as getMattermostRuntime } from "./runtime-CNB4YGqJ.js";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringifiedOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
@@ -13,7 +13,9 @@ import { getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-s
13
13
  import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
14
14
  import { Readable } from "node:stream";
15
15
  import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
16
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
16
17
  import { createHash, createHmac } from "node:crypto";
18
+ import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
17
19
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
18
20
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
19
21
  const MATTERMOST_COMMAND_DESCRIPTION_MAX_BYTES = 128;
@@ -369,7 +371,9 @@ const ACTION_IDS = {
369
371
  function splitModelRef(modelRef) {
370
372
  const match = normalizeOptionalString(modelRef)?.match(/^([^/]+)\/(.+)$/u);
371
373
  if (!match) return null;
372
- const provider = normalizeProviderId(match[1]);
374
+ const rawProvider = match[1];
375
+ if (!rawProvider) return null;
376
+ const provider = normalizeProviderId(rawProvider);
373
377
  const model = normalizeOptionalString(match[2]);
374
378
  if (!provider || !model) return null;
375
379
  return {
@@ -1052,7 +1056,12 @@ function createMattermostInteractionHandler(params) {
1052
1056
  }
1053
1057
  //#endregion
1054
1058
  //#region extensions/mattermost/src/mattermost/target-resolution.ts
1059
+ const MATTERMOST_OPAQUE_TARGET_CACHE_MAX_ENTRIES = 1024;
1055
1060
  const mattermostOpaqueTargetCache = /* @__PURE__ */ new Map();
1061
+ function cacheMattermostOpaqueTarget(key, kind) {
1062
+ mattermostOpaqueTargetCache.set(key, kind);
1063
+ pruneMapToMaxSize(mattermostOpaqueTargetCache, MATTERMOST_OPAQUE_TARGET_CACHE_MAX_ENTRIES);
1064
+ }
1056
1065
  function cacheKey$1(baseUrl, token, id) {
1057
1066
  return `${baseUrl}::${token}::${id}`;
1058
1067
  }
@@ -1060,6 +1069,71 @@ function cacheKey$1(baseUrl, token, id) {
1060
1069
  function isMattermostId(value) {
1061
1070
  return /^[a-z0-9]{26}$/.test(value);
1062
1071
  }
1072
+ function parseMattermostTarget(raw) {
1073
+ const trimmed = raw.trim();
1074
+ if (!trimmed) throw new Error("Recipient is required for Mattermost sends");
1075
+ const lower = normalizeLowercaseStringOrEmpty(trimmed);
1076
+ if (lower.startsWith("channel:")) {
1077
+ const id = trimmed.slice(8).trim();
1078
+ if (!id) throw new Error("Channel id is required for Mattermost sends");
1079
+ if (id.startsWith("#")) {
1080
+ const name = id.slice(1).trim();
1081
+ if (!name) throw new Error("Channel name is required for Mattermost sends");
1082
+ return {
1083
+ kind: "channel-name",
1084
+ name
1085
+ };
1086
+ }
1087
+ if (!isMattermostId(id)) return {
1088
+ kind: "channel-name",
1089
+ name: id
1090
+ };
1091
+ return {
1092
+ kind: "channel",
1093
+ id
1094
+ };
1095
+ }
1096
+ if (lower.startsWith("user:")) {
1097
+ const id = trimmed.slice(5).trim();
1098
+ if (!id) throw new Error("User id is required for Mattermost sends");
1099
+ return {
1100
+ kind: "user",
1101
+ id
1102
+ };
1103
+ }
1104
+ if (lower.startsWith("mattermost:")) {
1105
+ const id = trimmed.slice(11).trim();
1106
+ if (!id) throw new Error("User id is required for Mattermost sends");
1107
+ return {
1108
+ kind: "user",
1109
+ id
1110
+ };
1111
+ }
1112
+ if (trimmed.startsWith("@")) {
1113
+ const username = trimmed.slice(1).trim();
1114
+ if (!username) throw new Error("Username is required for Mattermost sends");
1115
+ return {
1116
+ kind: "user",
1117
+ username
1118
+ };
1119
+ }
1120
+ if (trimmed.startsWith("#")) {
1121
+ const name = trimmed.slice(1).trim();
1122
+ if (!name) throw new Error("Channel name is required for Mattermost sends");
1123
+ return {
1124
+ kind: "channel-name",
1125
+ name
1126
+ };
1127
+ }
1128
+ if (!isMattermostId(trimmed)) return {
1129
+ kind: "channel-name",
1130
+ name: trimmed
1131
+ };
1132
+ return {
1133
+ kind: "channel",
1134
+ id: trimmed
1135
+ };
1136
+ }
1063
1137
  function isExplicitMattermostTarget(raw) {
1064
1138
  const trimmed = raw.trim();
1065
1139
  if (!trimmed) return false;
@@ -1084,16 +1158,11 @@ async function resolveMattermostOpaqueTarget(params) {
1084
1158
  const baseUrl = normalizeMattermostBaseUrl(params.baseUrl ?? account?.baseUrl);
1085
1159
  if (!token || !baseUrl) return null;
1086
1160
  const key = cacheKey$1(baseUrl, token, input);
1087
- const cached = mattermostOpaqueTargetCache.get(key);
1088
- if (cached === true) return {
1089
- kind: "user",
1161
+ const cachedKind = mattermostOpaqueTargetCache.get(key);
1162
+ if (cachedKind) return {
1163
+ kind: cachedKind,
1090
1164
  id: input,
1091
- to: `user:${input}`
1092
- };
1093
- if (cached === false) return {
1094
- kind: "channel",
1095
- id: input,
1096
- to: `channel:${input}`
1165
+ to: `${cachedKind}:${input}`
1097
1166
  };
1098
1167
  const client = createMattermostClient({
1099
1168
  baseUrl,
@@ -1102,14 +1171,14 @@ async function resolveMattermostOpaqueTarget(params) {
1102
1171
  });
1103
1172
  try {
1104
1173
  await fetchMattermostUser(client, input);
1105
- mattermostOpaqueTargetCache.set(key, true);
1174
+ cacheMattermostOpaqueTarget(key, "user");
1106
1175
  return {
1107
1176
  kind: "user",
1108
1177
  id: input,
1109
1178
  to: `user:${input}`
1110
1179
  };
1111
1180
  } catch (err) {
1112
- if (parseMattermostApiStatus(err) === 404) mattermostOpaqueTargetCache.set(key, false);
1181
+ if (parseMattermostApiStatus(err) === 404) cacheMattermostOpaqueTarget(key, "channel");
1113
1182
  return {
1114
1183
  kind: "channel",
1115
1184
  id: input,
@@ -1119,10 +1188,17 @@ async function resolveMattermostOpaqueTarget(params) {
1119
1188
  }
1120
1189
  //#endregion
1121
1190
  //#region extensions/mattermost/src/mattermost/send.ts
1191
+ const MATTERMOST_BOT_USER_CACHE_MAX_ENTRIES = 64;
1192
+ const MATTERMOST_TARGET_CACHE_MAX_ENTRIES = 1024;
1122
1193
  const botUserCache = /* @__PURE__ */ new Map();
1123
1194
  const userByNameCache = /* @__PURE__ */ new Map();
1124
1195
  const channelByNameCache = /* @__PURE__ */ new Map();
1125
1196
  const dmChannelCache = /* @__PURE__ */ new Map();
1197
+ function cacheOutboundEntry(cache, key, value, maxEntries) {
1198
+ cache.delete(key);
1199
+ cache.set(key, value);
1200
+ pruneMapToMaxSize(cache, maxEntries);
1201
+ }
1126
1202
  const getCore = () => getMattermostRuntime();
1127
1203
  function createMattermostSendReceipt(params) {
1128
1204
  const messageIds = params.messageId.trim() && params.messageId !== "unknown" ? [params.messageId] : [];
@@ -1161,71 +1237,6 @@ function normalizeMessage(text, mediaUrl) {
1161
1237
  function isHttpUrl(value) {
1162
1238
  return /^https?:\/\//i.test(value);
1163
1239
  }
1164
- function parseMattermostTarget(raw) {
1165
- const trimmed = raw.trim();
1166
- if (!trimmed) throw new Error("Recipient is required for Mattermost sends");
1167
- const lower = normalizeLowercaseStringOrEmpty(trimmed);
1168
- if (lower.startsWith("channel:")) {
1169
- const id = trimmed.slice(8).trim();
1170
- if (!id) throw new Error("Channel id is required for Mattermost sends");
1171
- if (id.startsWith("#")) {
1172
- const name = id.slice(1).trim();
1173
- if (!name) throw new Error("Channel name is required for Mattermost sends");
1174
- return {
1175
- kind: "channel-name",
1176
- name
1177
- };
1178
- }
1179
- if (!isMattermostId(id)) return {
1180
- kind: "channel-name",
1181
- name: id
1182
- };
1183
- return {
1184
- kind: "channel",
1185
- id
1186
- };
1187
- }
1188
- if (lower.startsWith("user:")) {
1189
- const id = trimmed.slice(5).trim();
1190
- if (!id) throw new Error("User id is required for Mattermost sends");
1191
- return {
1192
- kind: "user",
1193
- id
1194
- };
1195
- }
1196
- if (lower.startsWith("mattermost:")) {
1197
- const id = trimmed.slice(11).trim();
1198
- if (!id) throw new Error("User id is required for Mattermost sends");
1199
- return {
1200
- kind: "user",
1201
- id
1202
- };
1203
- }
1204
- if (trimmed.startsWith("@")) {
1205
- const username = trimmed.slice(1).trim();
1206
- if (!username) throw new Error("Username is required for Mattermost sends");
1207
- return {
1208
- kind: "user",
1209
- username
1210
- };
1211
- }
1212
- if (trimmed.startsWith("#")) {
1213
- const name = trimmed.slice(1).trim();
1214
- if (!name) throw new Error("Channel name is required for Mattermost sends");
1215
- return {
1216
- kind: "channel-name",
1217
- name
1218
- };
1219
- }
1220
- if (!isMattermostId(trimmed)) return {
1221
- kind: "channel-name",
1222
- name: trimmed
1223
- };
1224
- return {
1225
- kind: "channel",
1226
- id: trimmed
1227
- };
1228
- }
1229
1240
  async function resolveBotUser(baseUrl, token, allowPrivateNetwork) {
1230
1241
  const key = cacheKey(baseUrl, token);
1231
1242
  const cached = botUserCache.get(key);
@@ -1235,7 +1246,7 @@ async function resolveBotUser(baseUrl, token, allowPrivateNetwork) {
1235
1246
  botToken: token,
1236
1247
  allowPrivateNetwork
1237
1248
  }));
1238
- botUserCache.set(key, user);
1249
+ cacheOutboundEntry(botUserCache, key, user, MATTERMOST_BOT_USER_CACHE_MAX_ENTRIES);
1239
1250
  return user;
1240
1251
  }
1241
1252
  async function resolveUserIdByUsername(params) {
@@ -1248,7 +1259,7 @@ async function resolveUserIdByUsername(params) {
1248
1259
  botToken: token,
1249
1260
  allowPrivateNetwork: params.allowPrivateNetwork
1250
1261
  }), username);
1251
- userByNameCache.set(key, user);
1262
+ cacheOutboundEntry(userByNameCache, key, user, MATTERMOST_TARGET_CACHE_MAX_ENTRIES);
1252
1263
  return user.id;
1253
1264
  }
1254
1265
  async function resolveChannelIdByName(params) {
@@ -1265,7 +1276,7 @@ async function resolveChannelIdByName(params) {
1265
1276
  for (const team of teams) try {
1266
1277
  const channel = await fetchMattermostChannelByName(client, team.id, name);
1267
1278
  if (channel?.id) {
1268
- channelByNameCache.set(key, channel.id);
1279
+ cacheOutboundEntry(channelByNameCache, key, channel.id, MATTERMOST_TARGET_CACHE_MAX_ENTRIES);
1269
1280
  return channel.id;
1270
1281
  }
1271
1282
  } catch {}
@@ -1313,7 +1324,7 @@ async function resolveTargetChannelId(params) {
1313
1324
  });
1314
1325
  params.onDmChannelResolution?.(resolution);
1315
1326
  const channel = await resolution;
1316
- dmChannelCache.set(dmKey, channel.id);
1327
+ cacheOutboundEntry(dmChannelCache, dmKey, channel.id, MATTERMOST_TARGET_CACHE_MAX_ENTRIES);
1317
1328
  return channel.id;
1318
1329
  }
1319
1330
  async function resolveMattermostSendContext(to, opts) {
@@ -1495,7 +1506,7 @@ function isDeletedMattermostCommand(command) {
1495
1506
  return typeof command.delete_at === "number" && command.delete_at > 0;
1496
1507
  }
1497
1508
  function sanitizeCommandLookupError(error) {
1498
- return (error instanceof Error ? error.message : String(error)).replace(/[\r\n\t]/gu, " ").replace(/https?:\/\/[^\s)\]}]+/giu, (urlText) => {
1509
+ return truncateUtf16Safe((error instanceof Error ? error.message : String(error)).replace(/[\r\n\t]/gu, " ").replace(/https?:\/\/[^\s)\]}]+/giu, (urlText) => {
1499
1510
  try {
1500
1511
  const url = new URL(urlText);
1501
1512
  if (url.username || url.password) {
@@ -1507,10 +1518,10 @@ function sanitizeCommandLookupError(error) {
1507
1518
  } catch {
1508
1519
  return urlText;
1509
1520
  }
1510
- }).replace(/(^|[^\w-])(Bearer|Token)\s+[A-Za-z0-9._~+/=-]+/giu, "$1$2 [redacted]").replace(/\b(token|authorization|access_token|refresh_token|client_secret|botToken)\b(\s*["']?\s*(?:=|:)\s*["']?)[^"',\s;}]+/giu, "$1$2[redacted]").slice(0, 300);
1521
+ }).replace(/(^|[^\w-])(Bearer|Token)\s+[A-Za-z0-9._~+/=-]+/giu, "$1$2 [redacted]").replace(/\b(token|authorization|access_token|refresh_token|client_secret|botToken)\b(\s*["']?\s*(?:=|:)\s*["']?)[^"',\s;}]+/giu, "$1$2[redacted]"), 300);
1511
1522
  }
1512
1523
  function sanitizeMattermostLogValue(value) {
1513
- return value.replace(/[\r\n\t]/gu, " ").slice(0, 200);
1524
+ return truncateUtf16Safe(value.replace(/[\r\n\t]/gu, " "), 200);
1514
1525
  }
1515
1526
  async function withCommandLookupTimeout(task) {
1516
1527
  const controller = new AbortController();
@@ -2065,12 +2076,16 @@ function resolveSlashHandlerForToken(token) {
2065
2076
  handler: state.handler
2066
2077
  });
2067
2078
  if (matches.length === 0) return { kind: "none" };
2068
- if (matches.length === 1) return {
2069
- kind: "single",
2070
- source: "token",
2071
- handler: matches[0].handler,
2072
- accountIds: [matches[0].accountId]
2073
- };
2079
+ if (matches.length === 1) {
2080
+ const match = matches[0];
2081
+ if (!match) return { kind: "none" };
2082
+ return {
2083
+ kind: "single",
2084
+ source: "token",
2085
+ handler: match.handler,
2086
+ accountIds: [match.accountId]
2087
+ };
2088
+ }
2074
2089
  return {
2075
2090
  kind: "ambiguous",
2076
2091
  source: "token",
@@ -2086,12 +2101,16 @@ function resolveSlashHandlerForCommand(params) {
2086
2101
  handler: state.handler
2087
2102
  });
2088
2103
  if (matches.length === 0) return { kind: "none" };
2089
- if (matches.length === 1) return {
2090
- kind: "single",
2091
- source: "command",
2092
- handler: matches[0].handler,
2093
- accountIds: [matches[0].accountId]
2094
- };
2104
+ if (matches.length === 1) {
2105
+ const match = matches[0];
2106
+ if (!match) return { kind: "none" };
2107
+ return {
2108
+ kind: "single",
2109
+ source: "command",
2110
+ handler: match.handler,
2111
+ accountIds: [match.accountId]
2112
+ };
2113
+ }
2095
2114
  return {
2096
2115
  kind: "ambiguous",
2097
2116
  source: "command",
@@ -2190,8 +2209,8 @@ function registerSlashCommandRoute(api) {
2190
2209
  return;
2191
2210
  }
2192
2211
  if (accountStates.size === 1) {
2193
- const [, state] = [...accountStates.entries()][0];
2194
- if (!state.handler) {
2212
+ const state = accountStates.values().next().value;
2213
+ if (!state?.handler) {
2195
2214
  res.statusCode = 503;
2196
2215
  res.setHeader("Content-Type", "application/json; charset=utf-8");
2197
2216
  res.end(JSON.stringify({
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@openclaw/mattermost",
3
- "version": "2026.7.1",
3
+ "version": "2026.7.2-beta.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/mattermost",
9
- "version": "2026.7.1",
9
+ "version": "2026.7.2-beta.1",
10
10
  "dependencies": {
11
11
  "ws": "8.21.0",
12
12
  "zod": "4.4.3"
13
13
  },
14
14
  "peerDependencies": {
15
- "openclaw": ">=2026.7.1"
15
+ "openclaw": ">=2026.7.2-beta.1"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {