@openclaw/mattermost 2026.7.1-beta.2 → 2026.7.1-beta.5

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.
@@ -13,7 +13,7 @@ import { z } from "zod";
13
13
  //#region extensions/mattermost/src/mattermost/client.ts
14
14
  const MATTERMOST_ERROR_BODY_LIMIT_BYTES = 8 * 1024;
15
15
  const MATTERMOST_TEXT_RESPONSE_LIMIT_BYTES = 64 * 1024;
16
- const NULL_BODY_STATUSES = new Set([
16
+ const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([
17
17
  101,
18
18
  204,
19
19
  205,
@@ -183,7 +183,7 @@ function resolveMattermostReplyDeliveryBarrierTimeoutMs(params) {
183
183
  const totalTimeoutMs = perDeliveryTimeoutMs * deliveryCount + Math.max(0, params.humanDelayBudgetMs ?? 0);
184
184
  return resolveTimerTimeoutMs(Number.isFinite(totalTimeoutMs) ? totalTimeoutMs : Number.MAX_SAFE_INTEGER, perDeliveryTimeoutMs);
185
185
  }
186
- const RETRYABLE_NETWORK_ERROR_CODES = new Set([
186
+ const RETRYABLE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
187
187
  "ECONNRESET",
188
188
  "ECONNREFUSED",
189
189
  "ETIMEDOUT",
@@ -201,7 +201,7 @@ const RETRYABLE_NETWORK_ERROR_CODES = new Set([
201
201
  "UND_ERR_HEADERS_TIMEOUT",
202
202
  "UND_ERR_BODY_TIMEOUT"
203
203
  ]);
204
- const RETRYABLE_NETWORK_ERROR_NAMES = new Set([
204
+ const RETRYABLE_NETWORK_ERROR_NAMES = /* @__PURE__ */ new Set([
205
205
  "AbortError",
206
206
  "TimeoutError",
207
207
  "ConnectTimeoutError",
@@ -1,5 +1,5 @@
1
- import { a as describeMattermostAccount, c as mattermostMeta, i as MattermostChannelConfigSchema, n as mattermostSetupWizard, o as isMattermostConfigured, r as mattermostSetupAdapter, s as mattermostConfigAdapter, t as mattermostPlugin } from "./channel-plugin-runtime-CbFQSpwf.js";
2
- import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-BHgOAkk8.js";
1
+ import { a as describeMattermostAccount, c as mattermostMeta, i as MattermostChannelConfigSchema, n as mattermostSetupWizard, o as isMattermostConfigured, r as mattermostSetupAdapter, s as mattermostConfigAdapter, t as mattermostPlugin } from "./channel-plugin-runtime-DhS8rwfs.js";
2
+ import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-BIXLORHU.js";
3
3
  //#region extensions/mattermost/src/channel.setup.ts
4
4
  const mattermostSetupPlugin = {
5
5
  id: "mattermost",
@@ -1,5 +1,5 @@
1
- import { C as hasConfiguredSecretInput, S as buildSecretInputSchema, g as normalizeMattermostBaseUrl, i as resolveMattermostReplyToMode, n as resolveDefaultMattermostAccountId, r as resolveMattermostAccount, t as listMattermostAccountIds } from "./accounts-Bt60MyHp.js";
2
- import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-BHgOAkk8.js";
1
+ import { C as hasConfiguredSecretInput, S as buildSecretInputSchema, g as normalizeMattermostBaseUrl, i as resolveMattermostReplyToMode, n as resolveDefaultMattermostAccountId, r as resolveMattermostAccount, t as listMattermostAccountIds } from "./accounts-ITTlduDO.js";
2
+ import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-BIXLORHU.js";
3
3
  import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-ttH0DCuq.js";
4
4
  import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-Cx0LUNXy.js";
5
5
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -17,11 +17,11 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
17
17
  import { resolvePayloadMediaUrls, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
18
18
  import { isPrivateNetworkOptInEnabled } from "openclaw/plugin-sdk/ssrf-runtime";
19
19
  import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
20
+ import { chunkTextForOutbound, sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
20
21
  import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
21
22
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
22
23
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
23
24
  import { z } from "zod";
24
- import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
25
25
  import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
26
26
  import { BlockStreamingCoalesceSchema, DmPolicySchema, GroupPolicySchema, MarkdownConfigSchema, buildChannelConfigSchema, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-primitives";
27
27
  import { applyAccountNameToChannelSection, applySetupAccountConfigPatch, createSetupTranslator, createStandardChannelSetupStatus, formatDocsLink, migrateBaseNameToDefaultAccount } from "openclaw/plugin-sdk/setup";
@@ -380,12 +380,15 @@ function resolveMattermostOutboundSessionRoute(params) {
380
380
  if (trimmed.startsWith("@")) trimmed = trimmed.slice(1).trim();
381
381
  const rawId = stripTargetKindPrefix(trimmed);
382
382
  if (!rawId) return null;
383
+ const hasExplicitUserKind = resolvedKind === "user" || lower.startsWith("user:");
384
+ const recipientSessionExact = isUser && hasExplicitUserKind && /^[a-z0-9]{26}$/.test(rawId);
383
385
  return buildThreadAwareOutboundSessionRoute({
384
386
  route: buildChannelOutboundSessionRoute({
385
387
  cfg: params.cfg,
386
388
  agentId: params.agentId,
387
389
  channel: "mattermost",
388
390
  accountId: params.accountId,
391
+ recipientSessionExact,
389
392
  peer: {
390
393
  kind: isUser ? "direct" : "channel",
391
394
  id: rawId
@@ -565,7 +568,7 @@ const mattermostSetupWizard = {
565
568
  };
566
569
  //#endregion
567
570
  //#region extensions/mattermost/src/channel.ts
568
- const loadMattermostChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-CnE1CD40.js"));
571
+ const loadMattermostChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime-D0SJSEei.js"));
569
572
  function buildMattermostPresentationButtons(presentation) {
570
573
  return presentation.blocks.filter((block) => block.type === "buttons").map((block) => block.buttons.flatMap((button) => {
571
574
  if (button.action) return [];
@@ -886,6 +889,7 @@ const mattermostOutbound = {
886
889
  chunker: chunkTextForOutbound,
887
890
  chunkerMode: "markdown",
888
891
  textChunkLimit: 4e3,
892
+ sanitizeText: ({ text }) => sanitizeAssistantVisibleText(text),
889
893
  deliveryCapabilities: { durableFinal: {
890
894
  text: true,
891
895
  media: true,
@@ -1,2 +1,2 @@
1
- import { t as mattermostPlugin } from "./channel-plugin-runtime-CbFQSpwf.js";
1
+ import { t as mattermostPlugin } from "./channel-plugin-runtime-DhS8rwfs.js";
2
2
  export { mattermostPlugin };
@@ -1,9 +1,9 @@
1
1
  import { C as resolveChannelMediaMaxBytes, E as warnMissingProviderGroupPolicyFallbackOnce, S as resolveAllowlistProviderRuntimeGroupPolicy, T as resolveDefaultGroupPolicy, _ as logInboundDrop, c as buildAgentMediaPayload, d as createChannelMessageReplyPipeline, f as createChannelPairingController, h as listSkillCommandsForAgents, i as normalizeMattermostAllowEntry, l as buildModelsProviderData, n as formatMattermostDirectMessageDropLog, o as resolveMattermostMonitorInboundAccess, s as DEFAULT_GROUP_HISTORY_LIMIT, t as authorizeMattermostCommandInvocation, u as createChannelHistoryWindow, v as logTypingFailure, x as registerPluginHttpRoute, y as parseTcpPort } from "./monitor-auth-BiDuyvOc.js";
2
- import { _ as readMattermostError, a as MattermostPostSchema, b as updateMattermostPost, c as createMattermostPost, f as fetchMattermostMe, g as normalizeMattermostBaseUrl, h as fetchMattermostUserTeams, i as resolveMattermostReplyToMode, l as deleteMattermostPost, o as createMattermostClient, p as fetchMattermostUser, r as resolveMattermostAccount, t as listMattermostAccountIds, u as fetchMattermostChannel, y as sendMattermostTyping } from "./accounts-Bt60MyHp.js";
2
+ import { _ as readMattermostError, a as MattermostPostSchema, b as updateMattermostPost, c as createMattermostPost, f as fetchMattermostMe, g as normalizeMattermostBaseUrl, h as fetchMattermostUserTeams, i as resolveMattermostReplyToMode, l as deleteMattermostPost, o as createMattermostClient, p as fetchMattermostUser, r as resolveMattermostAccount, t as listMattermostAccountIds, u as fetchMattermostChannel, y as sendMattermostTyping } from "./accounts-ITTlduDO.js";
3
3
  import { n as getOptionalMattermostRuntime, t as getMattermostRuntime } from "./runtime-CNB4YGqJ.js";
4
- import { C as registerSlashCommands, S as isSlashCommandsEnabled, T as resolveSlashCommandConfig, _ as renderMattermostModelsPickerView, a as sendMessageMattermost, b as DEFAULT_COMMAND_SPECS, c as computeInteractionCallbackUrl, d as setInteractionCallbackUrl, f as setInteractionSecret, g as parseMattermostModelPickerContext, h as buildMattermostAllowedModelRefs, l as createMattermostInteractionHandler, m as deliverMattermostReplyPayload, n as deactivateSlashCommands, o as resolveMattermostOpaqueTarget, p as createMattermostReplyDeliveryBarrier, r as getSlashCommandState, s as buildButtonProps, t as activateSlashCommands, u as resolveInteractionCallbackPath, v as renderMattermostProviderPickerView, w as resolveCallbackUrl, x as cleanupSlashCommands, y as resolveMattermostModelPickerCurrentModel } from "./slash-state-D1lza2ZZ.js";
4
+ import { C as registerSlashCommands, S as isSlashCommandsEnabled, T as resolveSlashCommandConfig, _ as renderMattermostModelsPickerView, a as sendMessageMattermost, b as DEFAULT_COMMAND_SPECS, c as computeInteractionCallbackUrl, d as setInteractionCallbackUrl, f as setInteractionSecret, g as parseMattermostModelPickerContext, h as buildMattermostAllowedModelRefs, l as createMattermostInteractionHandler, m as deliverMattermostReplyPayload, n as deactivateSlashCommands, o as resolveMattermostOpaqueTarget, p as createMattermostReplyDeliveryBarrier, r as getSlashCommandState, s as buildButtonProps, t as activateSlashCommands, u as resolveInteractionCallbackPath, v as renderMattermostProviderPickerView, w as resolveCallbackUrl, x as cleanupSlashCommands, y as resolveMattermostModelPickerCurrentModel } from "./slash-state-BfOSlkmn.js";
5
5
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringEntries, normalizeTrimmedStringList, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
6
- import { formatInboundFromLabel } from "openclaw/plugin-sdk/channel-inbound";
6
+ import { formatInboundFromLabel, formatInboundMediaUnavailableText } from "openclaw/plugin-sdk/channel-inbound";
7
7
  import { buildChannelProgressDraftLineForEntry, createChannelProgressDraftCompositor, createFinalizableDraftLifecycle, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, resolveChannelStreamingPreviewToolProgress } from "openclaw/plugin-sdk/channel-outbound";
8
8
  import { rawDataToString } from "openclaw/plugin-sdk/webhook-ingress";
9
9
  import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
@@ -20,7 +20,7 @@ import { createClaimableDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
20
20
  import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
21
21
  import { captureWsEvent, createDebugProxyWebSocketAgent, resolveDebugProxySettings } from "openclaw/plugin-sdk/proxy-capture";
22
22
  import WebSocket from "ws";
23
- import { resolveGlobalDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
23
+ import { createPersistentDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
24
24
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
25
25
  //#region extensions/mattermost/src/mattermost/directory.ts
26
26
  function buildClient(params) {
@@ -338,6 +338,15 @@ function stripOncharPrefix(text, prefixes) {
338
338
  }
339
339
  //#endregion
340
340
  //#region extensions/mattermost/src/mattermost/monitor-resources.ts
341
+ function formatMattermostInboundMediaText(params) {
342
+ const unavailableCount = Math.max(0, params.expectedCount - params.mediaCount);
343
+ if (unavailableCount === 0) return params.body;
344
+ return formatInboundMediaUnavailableText({
345
+ body: params.body,
346
+ mediaPlaceholder: params.mediaCount === 0 ? params.mediaPlaceholder : void 0,
347
+ notice: `[mattermost ${unavailableCount > 1 ? `${unavailableCount} attachments` : "attachment"} unavailable]`
348
+ });
349
+ }
341
350
  const CHANNEL_CACHE_TTL_MS = 5 * 6e4;
342
351
  const USER_CACHE_TTL_MS = 10 * 6e4;
343
352
  function createMattermostMonitorResources(params) {
@@ -555,6 +564,7 @@ async function registerMattermostMonitorSlashCommands(params) {
555
564
  }
556
565
  //#endregion
557
566
  //#region extensions/mattermost/src/mattermost/monitor-websocket.ts
567
+ const MATTERMOST_WEBSOCKET_MAX_PAYLOAD_BYTES = 16 * 1024 * 1024;
558
568
  const MattermostEventPayloadSchema = z.object({
559
569
  event: z.string().optional(),
560
570
  data: z.object({
@@ -590,7 +600,10 @@ var WebSocketClosedBeforeOpenError = class extends Error {
590
600
  };
591
601
  const defaultMattermostWebSocketFactory = (url) => {
592
602
  const agent = createDebugProxyWebSocketAgent(resolveDebugProxySettings());
593
- return new WebSocket(url, agent ? { agent } : void 0);
603
+ return new WebSocket(url, {
604
+ ...agent ? { agent } : {},
605
+ maxPayload: MATTERMOST_WEBSOCKET_MAX_PAYLOAD_BYTES
606
+ });
594
607
  };
595
608
  function parsePostedPayload(payload) {
596
609
  if (payload.event !== "posted") return null;
@@ -945,88 +958,37 @@ function sleepAbortable(ms, signal) {
945
958
  }
946
959
  //#endregion
947
960
  //#region extensions/mattermost/src/mattermost/thread-participation.ts
948
- /**
949
- * In-memory + persisted cache of Mattermost threads the bot has replied in.
950
- * Lets the bot auto-respond to thread follow-ups without a re-mention after its
951
- * first visible reply. Mirrors the Slack `sent-thread-cache` dual-layer pattern.
952
- */
953
- const TTL_MS = 10080 * 60 * 1e3;
954
- const MAX_ENTRIES = 5e3;
955
- const PERSISTENT_MAX_ENTRIES = 1e3;
956
- const PERSISTENT_NAMESPACE = "mattermost.thread-participation";
957
- const threadParticipation = resolveGlobalDedupeCache(Symbol.for("openclaw.mattermostThreadParticipation"), {
958
- ttlMs: TTL_MS,
959
- maxSize: MAX_ENTRIES
961
+ const threadParticipation = createPersistentDedupeCache({
962
+ globalKey: Symbol.for("openclaw.mattermostThreadParticipation"),
963
+ ttlMs: 10080 * 60 * 1e3,
964
+ maxSize: 5e3,
965
+ persistent: {
966
+ namespace: "mattermost.thread-participation",
967
+ maxEntries: 1e3,
968
+ openStore: (options) => getOptionalMattermostRuntime()?.state.openKeyedStore(options),
969
+ logError: (error) => {
970
+ try {
971
+ getOptionalMattermostRuntime()?.logging.getChildLogger({
972
+ plugin: "mattermost",
973
+ feature: "thread-participation-state"
974
+ }).warn("Mattermost persistent thread participation state failed", { error: String(error) });
975
+ } catch {}
976
+ }
977
+ }
960
978
  });
961
- let persistentStore;
962
- let persistentStoreDisabled = false;
963
979
  function makeKey(accountId, channelId, threadRootId) {
964
980
  return `${accountId}:${channelId}:${threadRootId}`;
965
981
  }
966
- function reportPersistentThreadParticipationError(error) {
967
- try {
968
- getOptionalMattermostRuntime()?.logging.getChildLogger({
969
- plugin: "mattermost",
970
- feature: "thread-participation-state"
971
- }).warn("Mattermost persistent thread participation state failed", { error: String(error) });
972
- } catch {}
973
- }
974
- function disablePersistentThreadParticipation(error) {
975
- persistentStoreDisabled = true;
976
- persistentStore = void 0;
977
- reportPersistentThreadParticipationError(error);
978
- }
979
- function getPersistentThreadParticipationStore() {
980
- if (persistentStoreDisabled) return;
981
- if (persistentStore) return persistentStore;
982
- const runtime = getOptionalMattermostRuntime();
983
- if (!runtime) return;
984
- try {
985
- persistentStore = runtime.state.openKeyedStore({
986
- namespace: PERSISTENT_NAMESPACE,
987
- maxEntries: PERSISTENT_MAX_ENTRIES,
988
- defaultTtlMs: TTL_MS
989
- });
990
- return persistentStore;
991
- } catch (error) {
992
- disablePersistentThreadParticipation(error);
993
- return;
994
- }
995
- }
996
- function rememberPersistentThreadParticipation(params) {
997
- const store = getPersistentThreadParticipationStore();
998
- if (!store) return;
999
- store.register(params.key, {
1000
- ...params.agentId ? { agentId: params.agentId } : {},
1001
- repliedAt: Date.now()
1002
- }).catch(disablePersistentThreadParticipation);
1003
- }
1004
- async function lookupPersistentThreadParticipation(key) {
1005
- const store = getPersistentThreadParticipationStore();
1006
- if (!store) return false;
1007
- try {
1008
- return Boolean(await store.lookup(key));
1009
- } catch (error) {
1010
- disablePersistentThreadParticipation(error);
1011
- return false;
1012
- }
1013
- }
1014
982
  function recordMattermostThreadParticipation(accountId, channelId, threadRootId, opts) {
1015
983
  if (!accountId || !channelId || !threadRootId) return;
1016
- const key = makeKey(accountId, channelId, threadRootId);
1017
- threadParticipation.check(key);
1018
- rememberPersistentThreadParticipation({
1019
- key,
1020
- agentId: opts?.agentId
984
+ threadParticipation.register(makeKey(accountId, channelId, threadRootId), {
985
+ ...opts?.agentId ? { agentId: opts.agentId } : {},
986
+ repliedAt: Date.now()
1021
987
  });
1022
988
  }
1023
989
  async function hasMattermostThreadParticipationWithPersistence(params) {
1024
990
  if (!params.accountId || !params.channelId || !params.threadRootId) return false;
1025
- const key = makeKey(params.accountId, params.channelId, params.threadRootId);
1026
- if (threadParticipation.peek(key)) return true;
1027
- const found = await lookupPersistentThreadParticipation(key);
1028
- if (found) threadParticipation.check(key);
1029
- return found;
991
+ return await threadParticipation.lookup(makeKey(params.accountId, params.channelId, params.threadRootId));
1030
992
  }
1031
993
  //#endregion
1032
994
  //#region extensions/mattermost/src/mattermost/monitor.ts
@@ -2008,9 +1970,15 @@ async function monitorMattermostProvider(opts = {}) {
2008
1970
  recordPendingHistory();
2009
1971
  return;
2010
1972
  }
2011
- const mediaList = await resolveMattermostMedia(post.file_ids);
1973
+ const fileIds = uniqueStrings(normalizeTrimmedStringList(post.file_ids ?? []));
1974
+ const mediaList = await resolveMattermostMedia(fileIds);
2012
1975
  const mediaPlaceholder = buildMattermostAttachmentPlaceholder(mediaList);
2013
- const bodyText = normalizeMention([oncharTriggered ? oncharResult.stripped : rawText, mediaPlaceholder].filter(Boolean).join("\n").trim(), botUsername);
1976
+ const bodyText = normalizeMention(formatMattermostInboundMediaText({
1977
+ body: [oncharTriggered ? oncharResult.stripped : rawText, mediaPlaceholder].filter(Boolean).join("\n").trim(),
1978
+ mediaPlaceholder,
1979
+ expectedCount: fileIds.length,
1980
+ mediaCount: mediaList.length
1981
+ }), botUsername);
2014
1982
  if (shouldDropEmptyMattermostBody({
2015
1983
  bodyText,
2016
1984
  rawText: rawPostText,
@@ -2069,7 +2037,7 @@ async function monitorMattermostProvider(opts = {}) {
2069
2037
  Body: combinedBody,
2070
2038
  BodyForAgent: bodyForAgent,
2071
2039
  InboundHistory: inboundHistory,
2072
- RawBody: bodyText,
2040
+ RawBody: commandBody,
2073
2041
  CommandBody: commandBody,
2074
2042
  BodyForCommands: commandBody,
2075
2043
  From: kind === "direct" ? `mattermost:${senderId}` : kind === "group" ? `mattermost:group:${channelId}` : `mattermost:channel:${channelId}`,
@@ -1,2 +1,2 @@
1
- import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-BHgOAkk8.js";
1
+ import { t as resolveMattermostGatewayAuthBypassPaths } from "./gateway-auth-bypass-BIXLORHU.js";
2
2
  export { resolveMattermostGatewayAuthBypassPaths as resolveGatewayAuthBypassPaths };
@@ -15,7 +15,7 @@ function isMattermostBypassPath(path) {
15
15
  return path === DEFAULT_SLASH_CALLBACK_PATH || path.startsWith("/api/channels/mattermost/");
16
16
  }
17
17
  function collectMattermostSlashCallbackPaths(raw) {
18
- const paths = new Set([normalizeCallbackPath(raw?.callbackPath)]);
18
+ const paths = /* @__PURE__ */ new Set([normalizeCallbackPath(raw?.callbackPath)]);
19
19
  const callbackUrl = readTrimmedString(raw?.callbackUrl);
20
20
  if (callbackUrl) try {
21
21
  const pathname = new URL(callbackUrl).pathname;
@@ -1,2 +1,2 @@
1
- import { i as registerSlashCommandRoute } from "./slash-state-D1lza2ZZ.js";
1
+ import { i as registerSlashCommandRoute } from "./slash-state-BfOSlkmn.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-Bt60MyHp.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";
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";
@@ -16,6 +16,19 @@ import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
16
16
  import { createHash, createHmac } from "node:crypto";
17
17
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
18
18
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
19
+ const MATTERMOST_COMMAND_DESCRIPTION_MAX_BYTES = 128;
20
+ function truncateMattermostCommandDescription(description) {
21
+ if (Buffer.byteLength(description, "utf8") <= MATTERMOST_COMMAND_DESCRIPTION_MAX_BYTES) return description;
22
+ let bytes = 0;
23
+ let end = 0;
24
+ for (const char of description) {
25
+ const charBytes = Buffer.byteLength(char, "utf8");
26
+ if (bytes + charBytes > MATTERMOST_COMMAND_DESCRIPTION_MAX_BYTES) break;
27
+ bytes += charBytes;
28
+ end += char.length;
29
+ }
30
+ return description.slice(0, end);
31
+ }
19
32
  /**
20
33
  * Built-in OpenClaw commands to register as native slash commands.
21
34
  * These mirror the text-based commands already handled by the gateway.
@@ -142,6 +155,7 @@ async function registerSlashCommands(params) {
142
155
  }
143
156
  const registered = [];
144
157
  for (const spec of commands) {
158
+ const description = truncateMattermostCommandDescription(spec.description);
145
159
  const existingForTrigger = existingByTrigger.get(spec.trigger) ?? [];
146
160
  const ownedCommands = existingForTrigger.filter((cmd) => cmd.creator_id?.trim() === normalizedCreatorUserId);
147
161
  const foreignCommands = existingForTrigger.filter((cmd) => cmd.creator_id?.trim() !== normalizedCreatorUserId);
@@ -173,9 +187,9 @@ async function registerSlashCommands(params) {
173
187
  trigger: spec.trigger,
174
188
  method: "P",
175
189
  url: callbackUrl,
176
- description: spec.description,
190
+ description,
177
191
  auto_complete: spec.autoComplete,
178
- auto_complete_desc: spec.description,
192
+ auto_complete_desc: description,
179
193
  auto_complete_hint: spec.autoCompleteHint
180
194
  });
181
195
  registered.push({
@@ -204,9 +218,9 @@ async function registerSlashCommands(params) {
204
218
  trigger: spec.trigger,
205
219
  method: "P",
206
220
  url: callbackUrl,
207
- description: spec.description,
221
+ description,
208
222
  auto_complete: spec.autoComplete,
209
- auto_complete_desc: spec.description,
223
+ auto_complete_desc: description,
210
224
  auto_complete_hint: spec.autoCompleteHint
211
225
  });
212
226
  log?.(`mattermost: registered command /${spec.trigger} (id=${created.id})`);
@@ -1451,7 +1465,7 @@ const COMMAND_VALIDATION_LOOKUP_RATE_LIMIT_MAX_KEYS = 2e3;
1451
1465
  const commandLookupInflight = /* @__PURE__ */ new Map();
1452
1466
  const commandValidationFailureCache = /* @__PURE__ */ new Map();
1453
1467
  const commandValidationLookupRateLimit = /* @__PURE__ */ new Map();
1454
- const SECRET_LOG_KEYS = new Set([
1468
+ const SECRET_LOG_KEYS = /* @__PURE__ */ new Set([
1455
1469
  "access_token",
1456
1470
  "authorization",
1457
1471
  "bottoken",
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@openclaw/mattermost",
3
- "version": "2026.7.1-beta.2",
3
+ "version": "2026.7.1-beta.5",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/mattermost",
9
- "version": "2026.7.1-beta.2",
9
+ "version": "2026.7.1-beta.5",
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-beta.2"
15
+ "openclaw": ">=2026.7.1-beta.5"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/mattermost",
3
- "version": "2026.7.1-beta.2",
3
+ "version": "2026.7.1-beta.5",
4
4
  "description": "OpenClaw Mattermost channel plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -12,7 +12,7 @@
12
12
  "zod": "4.4.3"
13
13
  },
14
14
  "peerDependencies": {
15
- "openclaw": ">=2026.7.1-beta.2"
15
+ "openclaw": ">=2026.7.1-beta.5"
16
16
  },
17
17
  "peerDependenciesMeta": {
18
18
  "openclaw": {
@@ -41,10 +41,10 @@
41
41
  "allowInvalidConfigRecovery": true
42
42
  },
43
43
  "compat": {
44
- "pluginApi": ">=2026.7.1-beta.2"
44
+ "pluginApi": ">=2026.7.1-beta.5"
45
45
  },
46
46
  "build": {
47
- "openclawVersion": "2026.7.1-beta.2",
47
+ "openclawVersion": "2026.7.1-beta.5",
48
48
  "bundledDist": false
49
49
  },
50
50
  "release": {