@openclaw/slack 2026.5.18 → 2026.5.19-beta.2

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.
@@ -28,7 +28,7 @@ function sameSlackChannelTarget(targetChannel, currentChannelId) {
28
28
  let slackActionsRuntimePromise;
29
29
  let slackAccountsRuntimePromise;
30
30
  function loadSlackActionsRuntime() {
31
- slackActionsRuntimePromise ??= import("./actions.runtime-3XZA8-ot.js");
31
+ slackActionsRuntimePromise ??= import("./actions.runtime-B0Aj3qGe.js");
32
32
  return slackActionsRuntimePromise;
33
33
  }
34
34
  function loadSlackAccountsRuntime() {
@@ -67,8 +67,12 @@ const slackActionRuntime = {
67
67
  function resolveThreadTsFromContext(explicitThreadTs, targetChannel, context, opts) {
68
68
  if (explicitThreadTs) return explicitThreadTs;
69
69
  if (opts?.suppressImplicitThread) return;
70
- if (!context?.currentThreadTs || !context?.currentChannelId) return;
70
+ if (!context?.currentChannelId) return;
71
71
  if (!sameSlackChannelTarget(targetChannel, context.currentChannelId)) return;
72
+ if (!context.currentThreadTs) {
73
+ if (context.sameChannelThreadRequired) throw new Error("Slack thread context is required for same-channel replies from a threaded Slack turn. Set topLevel=true or threadId=null to post at the channel root.");
74
+ return;
75
+ }
72
76
  if (context.replyToMode === "all") return context.currentThreadTs;
73
77
  if (isSingleUseReplyToMode(context.replyToMode ?? "off") && context.hasRepliedRef && !context.hasRepliedRef.value) {
74
78
  context.hasRepliedRef.value = true;
@@ -0,0 +1,2 @@
1
+ import { t as handleSlackAction } from "./action-runtime-JEAXQ9qf.js";
2
+ export { handleSlackAction };
@@ -174,7 +174,7 @@ function createSlackMediaRequest(url, token) {
174
174
  function isMockedFetch(fetchImpl) {
175
175
  if (typeof fetchImpl !== "function") return false;
176
176
  const candidate = fetchImpl;
177
- return candidate.mock !== void 0 || candidate._isMockFunction === true;
177
+ return candidate.mock !== void 0 || candidate["_isMockFunction"] === true;
178
178
  }
179
179
  function createSlackMediaFetch() {
180
180
  return async (input, init) => {
@@ -1,2 +1,2 @@
1
- import { a as listSlackEmojis, c as pinSlackMessage, d as removeOwnSlackReactions, f as removeSlackReaction, i as getSlackMemberInfo, l as reactSlackMessage, m as unpinSlackMessage, n as downloadSlackFile, o as listSlackPins, p as sendSlackMessage, r as editSlackMessage, s as listSlackReactions, t as deleteSlackMessage, u as readSlackMessages } from "./actions-vFq9T_Kd.js";
1
+ import { a as listSlackEmojis, c as pinSlackMessage, d as removeOwnSlackReactions, f as removeSlackReaction, i as getSlackMemberInfo, l as reactSlackMessage, m as unpinSlackMessage, n as downloadSlackFile, o as listSlackPins, p as sendSlackMessage, r as editSlackMessage, s as listSlackReactions, t as deleteSlackMessage, u as readSlackMessages } from "./actions-v0fGE-kg.js";
2
2
  export { deleteSlackMessage, downloadSlackFile, editSlackMessage, getSlackMemberInfo, listSlackEmojis, listSlackPins, listSlackReactions, pinSlackMessage, reactSlackMessage, readSlackMessages, removeOwnSlackReactions, removeSlackReaction, sendSlackMessage, unpinSlackMessage };
package/dist/api.js CHANGED
@@ -2,7 +2,7 @@ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, l as resol
2
2
  import { t as inspectSlackAccount } from "./account-inspect-uMPQ6wIu.js";
3
3
  import { i as resolveSlackChannelId, n as normalizeSlackMessagingTarget, r as parseSlackTarget, t as looksLikeSlackTargetId } from "./target-parsing-CQmv-iSm.js";
4
4
  import "./targets-B1tYCAr6.js";
5
- import { i as resolveSlackChannelType, n as buildSlackThreadingToolContext, o as resolveSlackAutoThreadId, r as __resetSlackChannelTypeCacheForTest, t as slackPlugin } from "./channel-D9Wzqu3W.js";
5
+ import { i as resolveSlackChannelType, n as buildSlackThreadingToolContext, o as resolveSlackAutoThreadId, r as resetSlackChannelTypeCacheForTest, t as slackPlugin } from "./channel-B24T-HNy.js";
6
6
  import { n as resolveSlackGroupRequireMention, r as resolveSlackGroupToolPolicy } from "./reply-blocks-DgUdywKU.js";
7
7
  import { n as buildSlackPresentationBlocks, t as buildSlackInteractiveBlocks } from "./blocks-render-ziYgM0qF.js";
8
8
  import { a as validateSlackBlocksArray, i as parseSlackBlocksInput, r as SLACK_MAX_BLOCKS } from "./thread-ts-As_dcNbD.js";
@@ -12,10 +12,10 @@ import { a as getSlackWriteClient, c as resolveSlackWebClientOptions, i as creat
12
12
  import { a as normalizeSlackSlug, i as normalizeSlackAllowOwnerEntry, n as normalizeAllowList, o as resolveSlackAllowListMatch, r as normalizeAllowListLower, s as resolveSlackUserAllowed, t as allowListMatches } from "./allow-list-nwXs_eCP.js";
13
13
  import { t as slackSetupPlugin } from "./channel.setup-C2_IZ9It.js";
14
14
  import { a as recordSlackThreadParticipation, n as clearSlackThreadParticipationCache, r as hasSlackThreadParticipation } from "./send-Br_H5f6H.js";
15
- import { a as listSlackEmojis, c as pinSlackMessage, d as removeOwnSlackReactions, f as removeSlackReaction, i as getSlackMemberInfo, l as reactSlackMessage, m as unpinSlackMessage, n as downloadSlackFile, o as listSlackPins, p as sendSlackMessage, r as editSlackMessage, s as listSlackReactions, t as deleteSlackMessage, u as readSlackMessages } from "./actions-vFq9T_Kd.js";
15
+ import { a as listSlackEmojis, c as pinSlackMessage, d as removeOwnSlackReactions, f as removeSlackReaction, i as getSlackMemberInfo, l as reactSlackMessage, m as unpinSlackMessage, n as downloadSlackFile, o as listSlackPins, p as sendSlackMessage, r as editSlackMessage, s as listSlackReactions, t as deleteSlackMessage, u as readSlackMessages } from "./actions-v0fGE-kg.js";
16
16
  import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-qDXRTCcs.js";
17
17
  import { n as registerSlackHttpHandler, r as normalizeSlackWebhookPath, t as handleSlackHttpRequest } from "./registry-D2cWOLZV.js";
18
18
  import { t as probeSlack } from "./probe-DDef8MfR.js";
19
19
  import { t as collectSlackSecurityAuditFindings } from "./security-audit-BJzADAw3.js";
20
- import { n as resolveSlackRuntimeGroupPolicy } from "./provider-C7uiI7hL.js";
21
- export { SLACK_DEFAULT_RETRY_OPTIONS, SLACK_MAX_BLOCKS, SLACK_WRITE_RETRY_OPTIONS, __resetSlackChannelTypeCacheForTest, allowListMatches, buildSlackInteractiveBlocks, buildSlackPresentationBlocks, buildSlackThreadingToolContext, clearSlackThreadParticipationCache, clearSlackWriteClientCacheForTest, collectSlackSecurityAuditFindings, compileSlackInteractiveReplies, createSlackTokenCacheKey, createSlackWebClient, createSlackWriteClient, deleteSlackMessage, downloadSlackFile, editSlackMessage, extractSlackToolSend, getSlackMemberInfo, getSlackWriteClient, handleSlackHttpRequest, hasSlackThreadParticipation, inspectSlackAccount, isSlackInteractiveRepliesEnabled, listEnabledSlackAccounts, listSlackAccountIds, listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig, listSlackEmojis, listSlackMessageActions, listSlackPins, listSlackReactions, looksLikeSlackTargetId, mergeSlackAccountConfig, normalizeAllowList, normalizeAllowListLower, normalizeSlackAllowOwnerEntry, normalizeSlackMessagingTarget, normalizeSlackSlug, normalizeSlackWebhookPath, parseSlackBlocksInput, parseSlackOptionsLine, parseSlackTarget, pinSlackMessage, probeSlack, reactSlackMessage, readSlackMessages, recordSlackThreadParticipation, registerSlackHttpHandler, removeOwnSlackReactions, removeSlackReaction, resolveDefaultSlackAccountId, resolveSlackAccount, resolveSlackAllowListMatch, resolveSlackAutoThreadId, resolveSlackChannelId, resolveSlackChannelType, resolveSlackGroupRequireMention, resolveSlackGroupToolPolicy, resolveSlackReplyToMode, resolveSlackRuntimeGroupPolicy, resolveSlackUserAllowed, resolveSlackWebClientOptions, resolveSlackWriteClientOptions, sendSlackMessage, slackPlugin, slackSetupPlugin, unpinSlackMessage, validateSlackBlocksArray };
20
+ import { n as resolveSlackRuntimeGroupPolicy } from "./provider-D4PYUrak.js";
21
+ export { SLACK_DEFAULT_RETRY_OPTIONS, SLACK_MAX_BLOCKS, SLACK_WRITE_RETRY_OPTIONS, resetSlackChannelTypeCacheForTest as __resetSlackChannelTypeCacheForTest, resetSlackChannelTypeCacheForTest, allowListMatches, buildSlackInteractiveBlocks, buildSlackPresentationBlocks, buildSlackThreadingToolContext, clearSlackThreadParticipationCache, clearSlackWriteClientCacheForTest, collectSlackSecurityAuditFindings, compileSlackInteractiveReplies, createSlackTokenCacheKey, createSlackWebClient, createSlackWriteClient, deleteSlackMessage, downloadSlackFile, editSlackMessage, extractSlackToolSend, getSlackMemberInfo, getSlackWriteClient, handleSlackHttpRequest, hasSlackThreadParticipation, inspectSlackAccount, isSlackInteractiveRepliesEnabled, listEnabledSlackAccounts, listSlackAccountIds, listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig, listSlackEmojis, listSlackMessageActions, listSlackPins, listSlackReactions, looksLikeSlackTargetId, mergeSlackAccountConfig, normalizeAllowList, normalizeAllowListLower, normalizeSlackAllowOwnerEntry, normalizeSlackMessagingTarget, normalizeSlackSlug, normalizeSlackWebhookPath, parseSlackBlocksInput, parseSlackOptionsLine, parseSlackTarget, pinSlackMessage, probeSlack, reactSlackMessage, readSlackMessages, recordSlackThreadParticipation, registerSlackHttpHandler, removeOwnSlackReactions, removeSlackReaction, resolveDefaultSlackAccountId, resolveSlackAccount, resolveSlackAllowListMatch, resolveSlackAutoThreadId, resolveSlackChannelId, resolveSlackChannelType, resolveSlackGroupRequireMention, resolveSlackGroupToolPolicy, resolveSlackReplyToMode, resolveSlackRuntimeGroupPolicy, resolveSlackUserAllowed, resolveSlackWebClientOptions, resolveSlackWriteClientOptions, sendSlackMessage, slackPlugin, slackSetupPlugin, unpinSlackMessage, validateSlackBlocksArray };
@@ -34,11 +34,15 @@ import { readNumberParam, readStringParam } from "openclaw/plugin-sdk/param-read
34
34
  //#region extensions/slack/src/action-threading.ts
35
35
  function resolveSlackAutoThreadId(params) {
36
36
  const context = params.toolContext;
37
- if (!context?.currentThreadTs || !context.currentChannelId) return;
38
- if (context.replyToMode !== "all" && !isSingleUseReplyToMode(context.replyToMode ?? "off")) return;
37
+ if (!context?.currentChannelId) return;
39
38
  const parsedTarget = parseSlackTarget(params.to, { defaultKind: "channel" });
40
39
  if (!parsedTarget || parsedTarget.kind !== "channel") return;
41
40
  if (normalizeLowercaseStringOrEmpty(parsedTarget.id) !== normalizeLowercaseStringOrEmpty(context.currentChannelId)) return;
41
+ if (!context.currentThreadTs) {
42
+ if (context.sameChannelThreadRequired) throw new Error("Slack thread context is required for same-channel replies from a threaded Slack turn. Set topLevel=true or threadId=null to post at the channel root.");
43
+ return;
44
+ }
45
+ if (context.replyToMode !== "all" && !isSingleUseReplyToMode(context.replyToMode ?? "off")) return;
42
46
  if (isSingleUseReplyToMode(context.replyToMode ?? "off") && context.hasRepliedRef?.value) return;
43
47
  return context.currentThreadTs;
44
48
  }
@@ -340,7 +344,7 @@ async function handleSlackMessageAction(params) {
340
344
  //#region extensions/slack/src/channel-actions.ts
341
345
  let slackActionRuntimePromise$1;
342
346
  async function loadSlackActionRuntime$1() {
343
- slackActionRuntimePromise$1 ??= import("./action-runtime.runtime-CGEyxfMu.js");
347
+ slackActionRuntimePromise$1 ??= import("./action-runtime.runtime-DNspDL64.js");
344
348
  return await slackActionRuntimePromise$1;
345
349
  }
346
350
  function resolveSlackActionContext(params) {
@@ -439,7 +443,7 @@ async function resolveSlackConversationInfo(params) {
439
443
  async function resolveSlackChannelType(params) {
440
444
  return (await resolveSlackConversationInfo(params)).type;
441
445
  }
442
- function __resetSlackChannelTypeCacheForTest() {
446
+ function resetSlackChannelTypeCacheForTest() {
443
447
  SLACK_CONVERSATION_INFO_CACHE.clear();
444
448
  }
445
449
  //#endregion
@@ -454,12 +458,14 @@ function buildSlackThreadingToolContext(params) {
454
458
  const replyToThreadTs = normalizeSlackThreadTsCandidate(params.context.ReplyToId);
455
459
  const currentMessageTs = normalizeSlackThreadTsCandidate(params.context.CurrentMessageId);
456
460
  const currentThreadTs = messageThreadTs ?? transportThreadTs ?? replyToThreadTs;
457
- const effectiveReplyToMode = messageThreadTs != null || transportThreadTs != null || replyToThreadTs != null && currentMessageTs != null && replyToThreadTs !== currentMessageTs ? "all" : configuredReplyToMode;
461
+ const hasExplicitThreadTarget = messageThreadTs != null || transportThreadTs != null || replyToThreadTs != null && currentMessageTs != null && replyToThreadTs !== currentMessageTs;
462
+ const effectiveReplyToMode = hasExplicitThreadTarget ? "all" : configuredReplyToMode;
458
463
  return {
459
464
  currentChannelId: params.context.To?.startsWith("channel:") ? params.context.To.slice(8) : normalizeOptionalString(params.context.NativeChannelId),
460
465
  currentThreadTs,
461
466
  replyToMode: effectiveReplyToMode,
462
- hasRepliedRef: params.hasRepliedRef
467
+ hasRepliedRef: params.hasRepliedRef,
468
+ sameChannelThreadRequired: hasExplicitThreadTarget
463
469
  };
464
470
  }
465
471
  //#endregion
@@ -494,7 +500,7 @@ const loadSlackDirectoryConfigModule = createLazyRuntimeModule(() => import("./d
494
500
  const loadSlackResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-gx65A1PR.js").then((n) => n.n));
495
501
  const loadSlackResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-OknHaiRY.js").then((n) => n.n));
496
502
  async function loadSlackActionRuntime() {
497
- slackActionRuntimePromise ??= import("./action-runtime.runtime-CGEyxfMu.js");
503
+ slackActionRuntimePromise ??= import("./action-runtime.runtime-DNspDL64.js");
498
504
  return await slackActionRuntimePromise;
499
505
  }
500
506
  async function loadSlackSendRuntime() {
@@ -506,7 +512,7 @@ async function loadSlackProbeModule() {
506
512
  return await slackProbeModulePromise;
507
513
  }
508
514
  async function loadSlackMonitorModule() {
509
- slackMonitorModulePromise ??= import("./monitor-beou_Rl6.js").then((n) => n.t);
515
+ slackMonitorModulePromise ??= import("./monitor-VZvVe0AD.js").then((n) => n.t);
510
516
  return await slackMonitorModulePromise;
511
517
  }
512
518
  async function loadSlackDirectoryLiveModule() {
@@ -993,4 +999,4 @@ const slackPlugin = createChatChannelPlugin({
993
999
  outbound: slackChannelOutbound
994
1000
  });
995
1001
  //#endregion
996
- export { createSlackActions as a, resolveSlackChannelType as i, buildSlackThreadingToolContext as n, resolveSlackAutoThreadId as o, __resetSlackChannelTypeCacheForTest as r, slackPlugin as t };
1002
+ export { createSlackActions as a, resolveSlackChannelType as i, buildSlackThreadingToolContext as n, resolveSlackAutoThreadId as o, resetSlackChannelTypeCacheForTest as r, slackPlugin as t };
@@ -1,2 +1,2 @@
1
- import { t as slackPlugin } from "./channel-D9Wzqu3W.js";
1
+ import { t as slackPlugin } from "./channel-B24T-HNy.js";
2
2
  export { slackPlugin };
@@ -1,3 +1,3 @@
1
- import { t as prepareSlackMessage } from "./prepare-BjlcuiLr.js";
1
+ import { t as prepareSlackMessage } from "./prepare-MN66ygug.js";
2
2
  import { t as createInboundSlackTestContext } from "./prepare.test-helpers-D807wdul.js";
3
3
  export { createInboundSlackTestContext, prepareSlackMessage };
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
2
  import { h as isSlackChannelAllowedByPolicy, k as buildSlackSlashCommandMatcher } from "./room-context-BI26wVBb.js";
3
- import { t as monitorSlackProvider } from "./provider-C7uiI7hL.js";
3
+ import { t as monitorSlackProvider } from "./provider-D4PYUrak.js";
4
4
  import { o as resolveSlackThreadTs } from "./replies-ClYRn89v.js";
5
5
  //#region extensions/slack/src/monitor.ts
6
6
  var monitor_exports = /* @__PURE__ */ __exportAll({
@@ -3,11 +3,11 @@ import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveRepl
3
3
  import { i as normalizeSlackAllowOwnerEntry } from "./allow-list-nwXs_eCP.js";
4
4
  import { n as resolveSlackNativeStreaming, r as resolveSlackStreamingMode, t as mapStreamingModeToSlackLegacyDraftStreamMode } from "./streaming-compat-eu5Rj5gj.js";
5
5
  import { a as recordSlackThreadParticipation, s as normalizeSlackOutboundText, t as sendMessageSlack } from "./send-Br_H5f6H.js";
6
- import { b as buildSlackEditTextPayload, f as removeSlackReaction, l as reactSlackMessage, r as editSlackMessage, t as deleteSlackMessage } from "./actions-vFq9T_Kd.js";
6
+ import { b as buildSlackEditTextPayload, f as removeSlackReaction, l as reactSlackMessage, r as editSlackMessage, t as deleteSlackMessage } from "./actions-v0fGE-kg.js";
7
7
  import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
8
8
  import { D as updateLastRoute, E as resolveStorePath, a as recordInboundSession } from "./room-context-BI26wVBb.js";
9
- import { r as escapeSlackMrkdwn } from "./provider-C7uiI7hL.js";
10
- import { n as resolveSlackThreadTargets, t as prepareSlackMessage } from "./prepare-BjlcuiLr.js";
9
+ import { r as escapeSlackMrkdwn } from "./provider-D4PYUrak.js";
10
+ import { n as resolveSlackThreadTargets, t as prepareSlackMessage } from "./prepare-MN66ygug.js";
11
11
  import { a as resolveDeliveredSlackReplyThreadTs, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, t as createSlackReplyDeliveryPlan } from "./replies-ClYRn89v.js";
12
12
  import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
13
13
  import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
@@ -3,7 +3,7 @@ import { r as parseSlackTarget } from "./target-parsing-CQmv-iSm.js";
3
3
  import "./targets-B1tYCAr6.js";
4
4
  import { i as normalizeSlackAllowOwnerEntry, o as resolveSlackAllowListMatch, r as normalizeAllowListLower } from "./allow-list-nwXs_eCP.js";
5
5
  import { i as hasSlackThreadParticipationWithPersistence, t as sendMessageSlack } from "./send-Br_H5f6H.js";
6
- import { _ as resolveSlackThreadStarter, g as resolveSlackThreadHistory, l as reactSlackMessage, y as formatSlackFileReference } from "./actions-vFq9T_Kd.js";
6
+ import { _ as resolveSlackThreadStarter, g as resolveSlackThreadHistory, l as reactSlackMessage, y as formatSlackFileReference } from "./actions-v0fGE-kg.js";
7
7
  import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
8
8
  import { C as resolveChannelContextVisibilityMode, E as resolveStorePath, S as readSessionUpdatedAt, _ as resolveSlackChatType, c as authorizeSlackBotRoomMessage, d as resolveSlackEffectiveAllowFrom, f as buildSlackAssistantThreadMetadata, g as normalizeSlackChannelType, j as stripSlackMentionsForCommandDetection, m as parseSlackAssistantThreadMetadata, n as authorizeSlackDirectMessage, o as resolveConversationLabel$1, t as resolveSlackRoomContextHints, u as resolveSlackCommandIngress, v as resolveSlackChannelConfig } from "./room-context-BI26wVBb.js";
9
9
  import "./send.runtime-CjgsYARn.js";
@@ -30,7 +30,7 @@ const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
30
30
  const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
31
31
  let slackMediaModulePromise$1;
32
32
  function loadSlackMediaModule$1() {
33
- slackMediaModulePromise$1 ??= import("./actions-vFq9T_Kd.js").then((n) => n.h);
33
+ slackMediaModulePromise$1 ??= import("./actions-v0fGE-kg.js").then((n) => n.h);
34
34
  return slackMediaModulePromise$1;
35
35
  }
36
36
  function collectUniqueSlackMentionIds$1(texts) {
@@ -578,7 +578,7 @@ function formatSlackBotStarterThreadLabel(params) {
578
578
  //#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
579
579
  let slackMediaModulePromise;
580
580
  function loadSlackMediaModule() {
581
- slackMediaModulePromise ??= import("./actions-vFq9T_Kd.js").then((n) => n.h);
581
+ slackMediaModulePromise ??= import("./actions-v0fGE-kg.js").then((n) => n.h);
582
582
  return slackMediaModulePromise;
583
583
  }
584
584
  const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
@@ -1265,7 +1265,7 @@ async function prepareSlackMessage(params) {
1265
1265
  surface: "slack"
1266
1266
  });
1267
1267
  const shouldRequireMention = isRoom ? channelConfig?.requireMention ?? ctx.defaultRequireMention : false;
1268
- if (message._ambiguousThreadReply) {
1268
+ if (message["_ambiguousThreadReply"]) {
1269
1269
  ctx.logger.info({
1270
1270
  channel: message.channel,
1271
1271
  ts: message.ts,
@@ -4,6 +4,7 @@ import "./blocks-render-ziYgM0qF.js";
4
4
  import { o as SLACK_TEXT_LIMIT, s as truncateSlackText } from "./thread-ts-As_dcNbD.js";
5
5
  import { c as resolveSlackWebClientOptions } from "./client-Dr7pteMR.js";
6
6
  import { n as normalizeAllowList, r as normalizeAllowListLower, t as allowListMatches } from "./allow-list-nwXs_eCP.js";
7
+ import { t as getOptionalSlackRuntime } from "./runtime-DQxkf7k2.js";
7
8
  import { n as registerSlackHttpHandler, r as normalizeSlackWebhookPath } from "./registry-D2cWOLZV.js";
8
9
  import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
9
10
  import { t as resolveSlackChannelAllowlist } from "./resolve-channels-gx65A1PR.js";
@@ -20,6 +21,7 @@ import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
20
21
  import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
21
22
  import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
22
23
  import { chunkItems } from "openclaw/plugin-sdk/text-chunking";
24
+ import { resolveGlobalDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
23
25
  import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "openclaw/plugin-sdk/native-command-config-runtime";
24
26
  import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
25
27
  import { DEFAULT_GROUP_HISTORY_LIMIT } from "openclaw/plugin-sdk/reply-history";
@@ -1758,6 +1760,90 @@ function registerSlackMonitorEvents(params) {
1758
1760
  });
1759
1761
  }
1760
1762
  //#endregion
1763
+ //#region extensions/slack/src/monitor/inbound-delivery-state.ts
1764
+ const TTL_MS = 1440 * 60 * 1e3;
1765
+ const MAX_ENTRIES = 2e4;
1766
+ const PERSISTENT_MAX_ENTRIES = 2e4;
1767
+ const PERSISTENT_NAMESPACE = "slack.inbound-deliveries";
1768
+ const deliveredMessages = resolveGlobalDedupeCache(Symbol.for("openclaw.slackInboundDeliveries"), {
1769
+ ttlMs: TTL_MS,
1770
+ maxSize: MAX_ENTRIES
1771
+ });
1772
+ let persistentStore;
1773
+ let persistentStoreDisabled = false;
1774
+ function makeKey(accountId, channelId, ts) {
1775
+ return `${accountId}:${channelId}:${ts}`;
1776
+ }
1777
+ function reportPersistentInboundDeliveryError(error) {
1778
+ try {
1779
+ getOptionalSlackRuntime()?.logging.getChildLogger({
1780
+ plugin: "slack",
1781
+ feature: "inbound-delivery-state"
1782
+ }).warn("Slack persistent inbound delivery state failed", { error: String(error) });
1783
+ } catch {}
1784
+ }
1785
+ function disablePersistentInboundDelivery(error) {
1786
+ persistentStoreDisabled = true;
1787
+ persistentStore = void 0;
1788
+ reportPersistentInboundDeliveryError(error);
1789
+ }
1790
+ function getPersistentInboundDeliveryStore() {
1791
+ if (persistentStoreDisabled) return;
1792
+ if (persistentStore) return persistentStore;
1793
+ const runtime = getOptionalSlackRuntime();
1794
+ if (!runtime) return;
1795
+ try {
1796
+ persistentStore = runtime.state.openKeyedStore({
1797
+ namespace: PERSISTENT_NAMESPACE,
1798
+ maxEntries: PERSISTENT_MAX_ENTRIES,
1799
+ defaultTtlMs: TTL_MS
1800
+ });
1801
+ return persistentStore;
1802
+ } catch (error) {
1803
+ disablePersistentInboundDelivery(error);
1804
+ return;
1805
+ }
1806
+ }
1807
+ async function lookupPersistentInboundDelivery(key) {
1808
+ const store = getPersistentInboundDeliveryStore();
1809
+ if (!store) return false;
1810
+ try {
1811
+ return Boolean(await store.lookup(key));
1812
+ } catch (error) {
1813
+ disablePersistentInboundDelivery(error);
1814
+ return false;
1815
+ }
1816
+ }
1817
+ async function rememberPersistentInboundDelivery(key, deliveredAt) {
1818
+ const store = getPersistentInboundDeliveryStore();
1819
+ if (!store) return;
1820
+ try {
1821
+ await store.register(key, { deliveredAt });
1822
+ } catch (error) {
1823
+ disablePersistentInboundDelivery(error);
1824
+ }
1825
+ }
1826
+ async function hasSlackInboundMessageDelivery(params) {
1827
+ if (!params.accountId || !params.channelId || !params.ts) return false;
1828
+ const key = makeKey(params.accountId, params.channelId, params.ts);
1829
+ if (deliveredMessages.peek(key)) return true;
1830
+ const found = await lookupPersistentInboundDelivery(key);
1831
+ if (found) deliveredMessages.check(key);
1832
+ return found;
1833
+ }
1834
+ async function recordSlackInboundMessageDeliveries(params) {
1835
+ if (!params.accountId || params.messages.length === 0) return;
1836
+ const deliveredAt = Date.now();
1837
+ const keys = /* @__PURE__ */ new Set();
1838
+ for (const message of params.messages) {
1839
+ if (!message.channel || !message.ts) continue;
1840
+ keys.add(makeKey(params.accountId, message.channel, message.ts));
1841
+ }
1842
+ if (keys.size === 0) return;
1843
+ for (const key of keys) deliveredMessages.check(key, deliveredAt);
1844
+ await Promise.all(Array.from(keys, (key) => rememberPersistentInboundDelivery(key, deliveredAt)));
1845
+ }
1846
+ //#endregion
1761
1847
  //#region extensions/slack/src/monitor/message-handler/debounce-key.ts
1762
1848
  function resolveSlackSenderId(message) {
1763
1849
  return message.user ?? message.bot_id ?? null;
@@ -1875,7 +1961,7 @@ function createSlackThreadTsResolver(params) {
1875
1961
  //#region extensions/slack/src/monitor/message-handler.ts
1876
1962
  let slackMessagePipelinePromise;
1877
1963
  function loadSlackMessagePipeline() {
1878
- slackMessagePipelinePromise ??= import("./pipeline.runtime-COwSmZG5.js");
1964
+ slackMessagePipelinePromise ??= import("./pipeline.runtime-fkqlk8kV.js");
1879
1965
  return slackMessagePipelinePromise;
1880
1966
  }
1881
1967
  const APP_MENTION_RETRY_TTL_MS = 6e4;
@@ -1952,7 +2038,19 @@ function createSlackMessageHandler(params) {
1952
2038
  prepared.ctxPayload.MessageSidLast = ids[ids.length - 1];
1953
2039
  }
1954
2040
  }
1955
- await dispatchPreparedSlackMessage(prepared);
2041
+ try {
2042
+ await dispatchPreparedSlackMessage(prepared);
2043
+ await recordSlackInboundMessageDeliveries({
2044
+ accountId: ctx.accountId,
2045
+ messages: entries.map((entry) => entry.message)
2046
+ });
2047
+ } catch (error) {
2048
+ if (!(error instanceof SlackRetryableInboundError)) await recordSlackInboundMessageDeliveries({
2049
+ accountId: ctx.accountId,
2050
+ messages: entries.map((entry) => entry.message)
2051
+ });
2052
+ throw error;
2053
+ }
1956
2054
  } catch (error) {
1957
2055
  if (error instanceof SlackRetryableInboundError) {
1958
2056
  if (seenMessageKey) appMentionDispatchedKeys.delete(seenMessageKey);
@@ -1988,6 +2086,11 @@ function createSlackMessageHandler(params) {
1988
2086
  if (opts.source === "message" && message.type !== "message") return;
1989
2087
  if (opts.source === "message" && message.subtype && message.subtype !== "file_share" && message.subtype !== "bot_message" && message.subtype !== "thread_broadcast") return;
1990
2088
  const seenMessageKey = buildSeenMessageKey(message.channel, message.ts);
2089
+ if (seenMessageKey && await hasSlackInboundMessageDelivery({
2090
+ accountId: ctx.accountId,
2091
+ channelId: message.channel,
2092
+ ts: message.ts
2093
+ })) return;
1991
2094
  const wasSeen = seenMessageKey ? ctx.markMessageSeen(message.channel, message.ts) : false;
1992
2095
  if (seenMessageKey && opts.source === "message" && !wasSeen) rememberAppMentionRetryKey(seenMessageKey);
1993
2096
  if (seenMessageKey && wasSeen) {
@@ -2,13 +2,13 @@ import { a as resolveSlackAccount, d as resolveSlackBotToken, i as resolveDefaul
2
2
  import { n as resolveSlackGroupRequireMention, r as resolveSlackGroupToolPolicy } from "./reply-blocks-DgUdywKU.js";
3
3
  import { n as setSlackRuntime } from "./runtime-DQxkf7k2.js";
4
4
  import { t as sendMessageSlack } from "./send-Br_H5f6H.js";
5
- import { a as listSlackEmojis, c as pinSlackMessage, d as removeOwnSlackReactions, f as removeSlackReaction, i as getSlackMemberInfo, l as reactSlackMessage, m as unpinSlackMessage, o as listSlackPins, p as sendSlackMessage, r as editSlackMessage, s as listSlackReactions, t as deleteSlackMessage, u as readSlackMessages } from "./actions-vFq9T_Kd.js";
5
+ import { a as listSlackEmojis, c as pinSlackMessage, d as removeOwnSlackReactions, f as removeSlackReaction, i as getSlackMemberInfo, l as reactSlackMessage, m as unpinSlackMessage, o as listSlackPins, p as sendSlackMessage, r as editSlackMessage, s as listSlackReactions, t as deleteSlackMessage, u as readSlackMessages } from "./actions-v0fGE-kg.js";
6
6
  import { t as probeSlack } from "./probe-DDef8MfR.js";
7
7
  import { t as resolveSlackChannelAllowlist } from "./resolve-channels-gx65A1PR.js";
8
8
  import { t as resolveSlackUserAllowlist } from "./resolve-users-OknHaiRY.js";
9
- import { t as monitorSlackProvider } from "./provider-C7uiI7hL.js";
9
+ import { t as monitorSlackProvider } from "./provider-D4PYUrak.js";
10
10
  import { t as registerSlackPluginHttpRoutes } from "./plugin-routes-hrKOqBIn.js";
11
- import { n as slackActionRuntime, t as handleSlackAction } from "./action-runtime-DgzkekLM.js";
11
+ import { n as slackActionRuntime, t as handleSlackAction } from "./action-runtime-JEAXQ9qf.js";
12
12
  import { n as listSlackDirectoryGroupsLive, r as listSlackDirectoryPeersLive } from "./directory-live-BnN4Zawp.js";
13
- import "./monitor-beou_Rl6.js";
13
+ import "./monitor-VZvVe0AD.js";
14
14
  export { deleteSlackMessage, editSlackMessage, getSlackMemberInfo, handleSlackAction, listEnabledSlackAccounts, listSlackAccountIds, listSlackDirectoryGroupsLive, listSlackDirectoryPeersLive, listSlackEmojis, listSlackPins, listSlackReactions, monitorSlackProvider, pinSlackMessage, probeSlack, reactSlackMessage, readSlackMessages, registerSlackPluginHttpRoutes, removeOwnSlackReactions, removeSlackReaction, resolveDefaultSlackAccountId, resolveSlackAccount, resolveSlackAppToken, resolveSlackBotToken, resolveSlackChannelAllowlist, resolveSlackGroupRequireMention, resolveSlackGroupToolPolicy, resolveSlackUserAllowlist, sendMessageSlack, sendSlackMessage, setSlackRuntime, slackActionRuntime, unpinSlackMessage };
package/dist/test-api.js CHANGED
@@ -1,7 +1,7 @@
1
- import { a as createSlackActions, t as slackPlugin } from "./channel-D9Wzqu3W.js";
1
+ import { a as createSlackActions, t as slackPlugin } from "./channel-B24T-HNy.js";
2
2
  import { n as setSlackRuntime } from "./runtime-DQxkf7k2.js";
3
3
  import { t as sendMessageSlack } from "./send-Br_H5f6H.js";
4
- import { t as prepareSlackMessage } from "./prepare-BjlcuiLr.js";
4
+ import { t as prepareSlackMessage } from "./prepare-MN66ygug.js";
5
5
  import { t as createInboundSlackTestContext } from "./prepare.test-helpers-D807wdul.js";
6
6
  import { t as createSlackOutboundPayloadHarness } from "./outbound-payload.test-harness-B8N8U_AA.js";
7
7
  import { n as slackOutbound } from "./outbound-adapter-Dcy9jZv1.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/slack",
3
- "version": "2026.5.18",
3
+ "version": "2026.5.19-beta.2",
4
4
  "description": "OpenClaw Slack channel plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,7 +20,7 @@
20
20
  "openclaw": "workspace:*"
21
21
  },
22
22
  "peerDependencies": {
23
- "openclaw": ">=2026.5.18"
23
+ "openclaw": ">=2026.5.19-beta.2"
24
24
  },
25
25
  "peerDependenciesMeta": {
26
26
  "openclaw": {
@@ -65,10 +65,10 @@
65
65
  "allowInvalidConfigRecovery": true
66
66
  },
67
67
  "compat": {
68
- "pluginApi": ">=2026.5.18"
68
+ "pluginApi": ">=2026.5.19-beta.2"
69
69
  },
70
70
  "build": {
71
- "openclawVersion": "2026.5.18",
71
+ "openclawVersion": "2026.5.19-beta.2",
72
72
  "bundledDist": false
73
73
  },
74
74
  "release": {
@@ -1,2 +0,0 @@
1
- import { t as handleSlackAction } from "./action-runtime-DgzkekLM.js";
2
- export { handleSlackAction };