@openclaw/slack 2026.7.2-beta.1 → 2026.7.2-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.
Files changed (42) hide show
  1. package/dist/{action-runtime-p6M2ULpv.js → action-runtime-Cee2ih0s.js} +9 -6
  2. package/dist/action-runtime.runtime-DZfd7IFr.js +2 -0
  3. package/dist/{actions-DkTcWmpT.js → actions-BZiuSTIq.js} +4 -8
  4. package/dist/{actions.runtime-BSxpwgUc.js → actions.runtime-DoD0-gxw.js} +1 -1
  5. package/dist/api.js +9 -9
  6. package/dist/{approval-handler.runtime-UGbnz9OC.js → approval-handler.runtime-CUPtIM4k.js} +2 -2
  7. package/dist/{channel-B0_j6C6z.js → channel-DaIiGUOp.js} +20 -18
  8. package/dist/channel-config-api.js +1 -1
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/{channel-type-BpeTezY4.js → channel-type-Cfm6_6n1.js} +2 -2
  11. package/dist/{channel.setup-BQFut21T.js → channel.setup-C-mLz50O.js} +3 -3
  12. package/dist/{client-D2F6m8CP.js → client-WIPAS3Yr.js} +9 -1
  13. package/dist/{config-schema-DYI01PV2.js → config-schema-xPSnK2VK.js} +12 -0
  14. package/dist/{directory-live-DX7yFsM-.js → directory-live-D_yZhjgp.js} +1 -1
  15. package/dist/{group-policy-C-b2ZnSl.js → group-policy-85UWiriS.js} +28 -15
  16. package/dist/{monitor-BN_uuvrQ.js → monitor-CalGciTs.js} +3 -3
  17. package/dist/{outbound-adapter-ECl0go7d.js → outbound-adapter-BiLKcnyH.js} +2 -2
  18. package/dist/{pipeline.runtime-f0eJJoJL.js → pipeline.runtime-DofAvTtb.js} +176 -54
  19. package/dist/{policy-f8b0edSi.js → policy-BVs4LiSa.js} +7 -7
  20. package/dist/{probe-CfALk0l4.js → probe-CN0ssfLN.js} +2 -2
  21. package/dist/{provider-Ds-y-imP.js → provider-CmeoUiIM.js} +282 -47
  22. package/dist/{relay-source-B-6LFUdz.js → relay-source-DMmgtvg4.js} +1 -1
  23. package/dist/{replies-BMvf3ihj.js → replies-CJJCp6qz.js} +3 -3
  24. package/dist/{resolve-channels-DOMgNCWb.js → resolve-channels-Rfts6POK.js} +1 -1
  25. package/dist/{resolve-users-aL6-Ssee.js → resolve-users-y6wAxR8E.js} +1 -1
  26. package/dist/{runtime-CauEvswP.js → runtime-JSVZSWAj.js} +2 -2
  27. package/dist/{runtime-api-CVb6CQjX.js → runtime-api-BGDyOt1D.js} +1 -1
  28. package/dist/runtime-api.js +11 -11
  29. package/dist/runtime-setter-api.js +1 -1
  30. package/dist/{scopes-Dw8wbU0j.js → scopes-CuxNQZ6v.js} +2 -2
  31. package/dist/{send-NEfJ0GvM.js → send-DYp8ca-l.js} +4 -4
  32. package/dist/{send.runtime-BkKpitPu.js → send.runtime-CJLxAt26.js} +1 -1
  33. package/dist/{setup-core-fGd6Gquy.js → setup-core-CkwVLzFO.js} +15 -21
  34. package/dist/setup-plugin-api.js +1 -1
  35. package/dist/{setup-surface-BN2WeG5c.js → setup-surface-oSd3NX9J.js} +4 -4
  36. package/dist/{shared-BLnB9R1T.js → shared-D9yz5Otg.js} +12 -35
  37. package/dist/{slash-dispatch.runtime-C0Otuf_T.js → slash-dispatch.runtime-CSja9VuD.js} +1 -1
  38. package/npm-shrinkwrap.json +3 -3
  39. package/openclaw.plugin.json +68 -0
  40. package/package.json +5 -7
  41. package/dist/action-runtime.runtime-DQstDkHG.js +0 -2
  42. package/dist/configured-state.js +0 -11
@@ -1,13 +1,13 @@
1
1
  import { n as registerSlackHttpHandler, r as normalizeSlackWebhookPath } from "./registry-bbjH7IHX.js";
2
2
  import { a as resolveSlackAccount, d as formatSlackBotTokenIdentityWarning, f as resolveSlackAppToken, i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, p as resolveSlackBotToken, s as resolveSlackAccountDmPolicy } from "./accounts-BOJJiHSr.js";
3
- import { $ as isSlackAnyNativeApprovalClientEnabled, F as SLACK_TEXT_LIMIT, K as escapeSlackMrkdwn, U as isSlackApprovalActionId, W as isSlackCallbackActionId, a as allowListMatches, c as normalizeSlackAllowOwnerEntry, dt as isSlackExecApprovalAuthorizedSender, l as normalizeSlackSlug, lt as isSlackApprovalAuthorizedSender, o as normalizeAllowList, q as decodeSlackApprovalAction, r as formatSlackError, s as normalizeAllowListLower, u as resolveSlackAllowListMatch, z as truncateSlackText } from "./group-policy-C-b2ZnSl.js";
3
+ import { B as truncateSlackText, G as isSlackCallbackActionId, I as SLACK_TEXT_LIMIT, J as decodeSlackApprovalAction, W as isSlackApprovalActionId, c as normalizeAllowListLower, d as resolveSlackAllowListMatch, et as isSlackAnyNativeApprovalClientEnabled, ft as isSlackExecApprovalAuthorizedSender, i as formatSlackError, l as normalizeSlackAllowOwnerEntry, o as allowListMatches, q as escapeSlackMrkdwn, s as normalizeAllowList, u as normalizeSlackSlug, ut as isSlackApprovalAuthorizedSender } from "./group-policy-85UWiriS.js";
4
4
  import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-BilWUdcI.js";
5
- import { o as getSlackListenerUploadCompletionClient, u as resolveSlackWebClientOptions } from "./client-D2F6m8CP.js";
6
- import { t as getOptionalSlackRuntime } from "./runtime-CauEvswP.js";
7
- import { i as setSlackDefaultSendIdentity } from "./send-NEfJ0GvM.js";
8
- import { t as resolveSlackChannelAllowlist } from "./resolve-channels-DOMgNCWb.js";
9
- import { t as resolveSlackUserAllowlist } from "./resolve-users-aL6-Ssee.js";
10
- import { n as resolveSlackChannelConfig, r as resolveSlackChannelLabel, t as isSlackChannelAllowedByPolicy } from "./policy-f8b0edSi.js";
5
+ import { d as resolveSlackWebClientOptions, r as createSlackStartupAuthClient, s as getSlackListenerUploadCompletionClient } from "./client-WIPAS3Yr.js";
6
+ import { n as getSlackRuntime, t as getOptionalSlackRuntime } from "./runtime-JSVZSWAj.js";
7
+ import { i as setSlackDefaultSendIdentity } from "./send-DYp8ca-l.js";
8
+ import { t as resolveSlackChannelAllowlist } from "./resolve-channels-Rfts6POK.js";
9
+ import { t as resolveSlackUserAllowlist } from "./resolve-users-y6wAxR8E.js";
10
+ import { n as resolveSlackChannelConfig, r as resolveSlackChannelLabel, t as isSlackChannelAllowedByPolicy } from "./policy-BVs4LiSa.js";
11
11
  import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
12
12
  import { asOptionalRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, normalizeStringEntriesLower, normalizeUniqueTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
13
13
  import { normalizeAccountId, normalizeMainKey, resolveAgentRoute, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
@@ -94,9 +94,26 @@ function resolveSlackChatType(channelType) {
94
94
  return "channel";
95
95
  }
96
96
  //#endregion
97
+ //#region extensions/slack/src/monitor/lru-map-cache.ts
98
+ /** LRU-touch read: move hit to newest so pruneMapToMaxSize keeps active keys. */
99
+ function readLruMapEntry(cache, cacheKey) {
100
+ const cached = cache.get(cacheKey);
101
+ if (cached) {
102
+ cache.delete(cacheKey);
103
+ cache.set(cacheKey, cached);
104
+ }
105
+ return cached;
106
+ }
107
+ function writeLruMapEntry(cache, cacheKey, entry, maxEntries) {
108
+ cache.delete(cacheKey);
109
+ cache.set(cacheKey, entry);
110
+ pruneMapToMaxSize(cache, maxEntries);
111
+ }
112
+ //#endregion
97
113
  //#region extensions/slack/src/monitor/context.ts
98
114
  const SLACK_ASSISTANT_THREAD_CONTEXT_METADATA_EVENT = "assistant_thread_context";
99
115
  const SLACK_CHANNEL_CACHE_MAX_ENTRIES = 1024;
116
+ const SLACK_USER_CACHE_MAX_ENTRIES = 2048;
100
117
  const SLACK_CHANNEL_DENIAL_WARNING_TTL_MS = 5 * 6e4;
101
118
  const SLACK_CHANNEL_DENIAL_WARNING_MAX_ENTRIES = 1024;
102
119
  function buildSlackAssistantThreadMetadata(context) {
@@ -150,38 +167,25 @@ function createSlackMonitorContext(params) {
150
167
  const hasChannelAllowlistConfig = Object.keys(params.channelsConfig ?? {}).length > 0;
151
168
  const channelsConfigKeys = Object.keys(params.channelsConfig ?? {});
152
169
  const scopedKey = (key, eventScope) => eventScope ? `${params.accountId}:${eventScope.teamId}:${key}` : key;
153
- const readCachedChannel = (cacheKey) => {
154
- const cached = channelCache.get(cacheKey);
155
- if (cached) {
156
- channelCache.delete(cacheKey);
157
- channelCache.set(cacheKey, cached);
158
- }
159
- return cached;
160
- };
161
- const writeCachedChannel = (cacheKey, entry) => {
162
- channelCache.delete(cacheKey);
163
- channelCache.set(cacheKey, entry);
164
- pruneMapToMaxSize(channelCache, SLACK_CHANNEL_CACHE_MAX_ENTRIES);
165
- };
166
170
  const rememberSlackChannelType = (channelId, channelType, eventScope) => {
167
171
  const id = normalizeOptionalString(channelId);
168
172
  const normalizedType = normalizeOptionalString(channelType)?.toLowerCase();
169
173
  if (!id || normalizedType !== "im" && normalizedType !== "mpim" && normalizedType !== "channel" && normalizedType !== "group") return;
170
174
  const cacheKey = scopedKey(id, eventScope);
171
- const cached = readCachedChannel(cacheKey);
175
+ const cached = readLruMapEntry(channelCache, cacheKey);
172
176
  const type = normalizeSlackChannelType(normalizedType, id);
173
177
  if (cached?.info.type === type) return;
174
- writeCachedChannel(cacheKey, {
178
+ writeLruMapEntry(channelCache, cacheKey, {
175
179
  info: {
176
180
  ...cached?.info,
177
181
  type
178
182
  },
179
183
  metadataLoaded: cached?.metadataLoaded ?? false
180
- });
184
+ }, SLACK_CHANNEL_CACHE_MAX_ENTRIES);
181
185
  };
182
186
  const recallSlackChannelType = (channelId, eventScope) => {
183
187
  const id = normalizeOptionalString(channelId);
184
- return id ? readCachedChannel(scopedKey(id, eventScope))?.info.type : void 0;
188
+ return id ? readLruMapEntry(channelCache, scopedKey(id, eventScope))?.info.type : void 0;
185
189
  };
186
190
  const markMessageSeen = (channelId, ts, eventScope) => {
187
191
  if (!channelId || !ts) return false;
@@ -280,7 +284,7 @@ function createSlackMonitorContext(params) {
280
284
  };
281
285
  const resolveChannelName = async (channelId, eventScope) => {
282
286
  const cacheKey = scopedKey(channelId, eventScope);
283
- const cached = readCachedChannel(cacheKey);
287
+ const cached = readLruMapEntry(channelCache, cacheKey);
284
288
  if (cached?.metadataLoaded) return cached.info;
285
289
  try {
286
290
  const info = await (eventScope?.client ?? params.app.client).conversations.info({
@@ -301,7 +305,7 @@ function createSlackMonitorContext(params) {
301
305
  },
302
306
  metadataLoaded: true
303
307
  };
304
- writeCachedChannel(cacheKey, entry);
308
+ writeLruMapEntry(channelCache, cacheKey, entry, SLACK_CHANNEL_CACHE_MAX_ENTRIES);
305
309
  return entry.info;
306
310
  } catch {
307
311
  return cached?.info ?? {};
@@ -309,7 +313,7 @@ function createSlackMonitorContext(params) {
309
313
  };
310
314
  const resolveUserName = async (userId, eventScope) => {
311
315
  const cacheKey = scopedKey(userId, eventScope);
312
- const cached = userCache.get(cacheKey);
316
+ const cached = readLruMapEntry(userCache, cacheKey);
313
317
  if (cached) return cached;
314
318
  try {
315
319
  const info = await (eventScope?.client ?? params.app.client).users.info({
@@ -318,7 +322,7 @@ function createSlackMonitorContext(params) {
318
322
  });
319
323
  const profile = info.user?.profile;
320
324
  const entry = { name: profile?.display_name || profile?.real_name || info.user?.name || void 0 };
321
- userCache.set(cacheKey, entry);
325
+ writeLruMapEntry(userCache, cacheKey, entry, SLACK_USER_CACHE_MAX_ENTRIES);
322
326
  return entry;
323
327
  } catch {
324
328
  return {};
@@ -606,6 +610,20 @@ function resolveSlackInstallationIdentity(params) {
606
610
  ...enterpriseId ? { enterpriseId } : {}
607
611
  };
608
612
  }
613
+ function resolveSlackIdentityHealth(params) {
614
+ if (params.installationIdentity.kind === "enterprise") return {
615
+ healthState: "healthy",
616
+ lastError: null
617
+ };
618
+ const lastError = normalizeOptionalString(params.authTestError) ?? normalizeOptionalString(params.authIdentityWarning) ?? (params.installationIdentity.kind === "degraded" || !params.botUserId.trim() ? "slack bot identity unavailable" : void 0);
619
+ return lastError ? {
620
+ healthState: "degraded",
621
+ lastError
622
+ } : {
623
+ healthState: "healthy",
624
+ lastError: null
625
+ };
626
+ }
609
627
  //#endregion
610
628
  //#region extensions/slack/src/monitor/events/assistant.ts
611
629
  const DEFAULT_ASSISTANT_PROMPTS = [
@@ -3180,7 +3198,7 @@ function createSlackThreadTsResolver(params) {
3180
3198
  }
3181
3199
  //#endregion
3182
3200
  //#region extensions/slack/src/monitor/message-handler.ts
3183
- const loadSlackMessagePipeline = createLazyRuntimeModule(() => import("./pipeline.runtime-f0eJJoJL.js"));
3201
+ const loadSlackMessagePipeline = createLazyRuntimeModule(() => import("./pipeline.runtime-DofAvTtb.js"));
3184
3202
  function createSlackDispatchCompletion() {
3185
3203
  let resolve;
3186
3204
  let reject;
@@ -3212,7 +3230,7 @@ function buildSeenMessageKey(channelId, ts, teamId) {
3212
3230
  return `${teamId ? `${teamId}:` : ""}${channelId}:${ts}`;
3213
3231
  }
3214
3232
  function createSlackMessageHandler(params) {
3215
- const { ctx, account, trackEvent } = params;
3233
+ const { ctx, account, trackEvent, onPrepared } = params;
3216
3234
  const { debounceMs, debouncer } = createChannelInboundDebouncer({
3217
3235
  cfg: ctx.cfg,
3218
3236
  channel: "slack",
@@ -3297,6 +3315,7 @@ function createSlackMessageHandler(params) {
3297
3315
  }
3298
3316
  })();
3299
3317
  if (!prepared) return;
3318
+ onPrepared?.(prepared);
3300
3319
  if (entries.length > 1) {
3301
3320
  const ids = entries.map((entry) => entry.message.ts).filter(Boolean);
3302
3321
  if (ids.length > 0) {
@@ -3426,6 +3445,203 @@ function createSlackMessageHandler(params) {
3426
3445
  };
3427
3446
  }
3428
3447
  //#endregion
3448
+ //#region extensions/slack/src/monitor/presence-monitor.ts
3449
+ const SLACK_PRESENCE_GREETING_COOLDOWN_MS = 480 * 60 * 1e3;
3450
+ const SLACK_PRESENCE_POLL_INTERVAL_MS = 6e4;
3451
+ const SLACK_PRESENCE_AUTO_MAX_PARTICIPANTS = 8;
3452
+ const SLACK_PRESENCE_TARGET_TTL_MS = 1440 * 60 * 1e3;
3453
+ const SLACK_PRESENCE_MAX_POLLS_PER_INTERVAL = 45;
3454
+ const SLACK_PRESENCE_MAX_TARGETS = 2e3;
3455
+ function resolveMode(channelConfig, accountConfig) {
3456
+ return channelConfig?.mode ?? accountConfig?.mode ?? "off";
3457
+ }
3458
+ function hasSlackPresenceEventsEnabled(params) {
3459
+ if (resolveMode(void 0, params.account) !== "off") return true;
3460
+ return Object.values(params.channels ?? {}).some((entry) => resolveMode(entry?.presenceEvents, void 0) !== "off");
3461
+ }
3462
+ function isTargetEligible(target) {
3463
+ if (target.mode === "on") return true;
3464
+ if (target.autoEligibleKind === "channel") return false;
3465
+ return target.participants.size <= SLACK_PRESENCE_AUTO_MAX_PARTICIPANTS;
3466
+ }
3467
+ function formatSlackPresenceEvent(target, userId) {
3468
+ return [
3469
+ "Slack presence event:",
3470
+ `A human participant became active on Slack after being observed away: user_id=${JSON.stringify(userId)} channel_id=${JSON.stringify(target.channelId)}${target.threadId ? ` thread_ts=${JSON.stringify(target.threadId)}` : ""}.`,
3471
+ "Before greeting, retrieve relevant memory and wiki context for this immutable user_id, including a known timezone when available. Use their local time; if their timezone is unknown, do not guess.",
3472
+ "Send at most one short, natural greeting in this Slack conversation. Do not reveal private memory. If no greeting is appropriate, stay silent."
3473
+ ].join("\n");
3474
+ }
3475
+ function resolveObservedTarget(params) {
3476
+ const { prepared } = params;
3477
+ const userId = prepared.message.user?.trim();
3478
+ if (!userId || prepared.message.bot_id || prepared.message.subtype === "bot_message") return null;
3479
+ const mode = resolveMode(prepared.channelConfig?.presenceEvents, params.accountConfig);
3480
+ if (mode === "off") return null;
3481
+ const channelId = prepared.message.channel;
3482
+ const rawThreadId = prepared.ctxPayload.MessageThreadId ?? prepared.ctxPayload.TransportThreadId ?? void 0;
3483
+ const threadId = rawThreadId === void 0 ? void 0 : String(rawThreadId);
3484
+ const channelType = prepared.message.channel_type;
3485
+ const autoEligibleKind = prepared.isDirectMessage ? "direct" : channelType === "mpim" ? "group" : threadId ? "thread" : "channel";
3486
+ if (mode === "auto" && autoEligibleKind === "channel") return null;
3487
+ return {
3488
+ key: `${channelId}${threadId ? `:thread:${threadId}` : ":top"}`,
3489
+ mode,
3490
+ channelId,
3491
+ threadId,
3492
+ to: prepared.isDirectMessage ? `user:${userId}` : `channel:${channelId}`,
3493
+ sessionKey: prepared.route.sessionKey,
3494
+ agentId: prepared.route.agentId,
3495
+ participants: /* @__PURE__ */ new Map([[userId, params.nowMs]]),
3496
+ lastActivityAtMs: params.nowMs,
3497
+ autoEligibleKind
3498
+ };
3499
+ }
3500
+ function createSlackPresenceMonitor(params) {
3501
+ const targets = /* @__PURE__ */ new Map();
3502
+ const presenceByUser = /* @__PURE__ */ new Map();
3503
+ const nowMs = params.nowMs ?? Date.now;
3504
+ const enqueue = params.enqueue ?? enqueueSystemEvent;
3505
+ const wake = params.wake ?? requestHeartbeat;
3506
+ let pollOffset = 0;
3507
+ let timer;
3508
+ let activePoll;
3509
+ let stopped = false;
3510
+ const pruneTargets = (now) => {
3511
+ for (const [key, target] of targets) if (now - target.lastActivityAtMs >= SLACK_PRESENCE_TARGET_TTL_MS) targets.delete(key);
3512
+ while (targets.size > SLACK_PRESENCE_MAX_TARGETS) {
3513
+ const oldestKey = targets.keys().next().value;
3514
+ if (typeof oldestKey !== "string") break;
3515
+ targets.delete(oldestKey);
3516
+ }
3517
+ const eligibleUsers = new Set(Array.from(targets.values()).filter(isTargetEligible).flatMap((target) => Array.from(target.participants.keys())));
3518
+ for (const userId of presenceByUser.keys()) if (!eligibleUsers.has(userId)) presenceByUser.delete(userId);
3519
+ };
3520
+ const observe = (prepared) => {
3521
+ const now = nowMs();
3522
+ pruneTargets(now);
3523
+ const observed = resolveObservedTarget({
3524
+ prepared,
3525
+ accountConfig: params.accountConfig,
3526
+ nowMs: now
3527
+ });
3528
+ if (!observed) return;
3529
+ const current = targets.get(observed.key);
3530
+ if (current) {
3531
+ current.mode = observed.mode;
3532
+ current.sessionKey = observed.sessionKey;
3533
+ current.agentId = observed.agentId;
3534
+ current.to = observed.to;
3535
+ current.lastActivityAtMs = now;
3536
+ for (const [participant, observedAt] of observed.participants) current.participants.set(participant, observedAt);
3537
+ targets.delete(observed.key);
3538
+ targets.set(observed.key, current);
3539
+ } else targets.set(observed.key, observed);
3540
+ pruneTargets(now);
3541
+ };
3542
+ const emitTransition = (userId, now) => {
3543
+ const target = Array.from(targets.values()).filter((candidate) => candidate.participants.has(userId) && isTargetEligible(candidate)).toSorted((a, b) => (b.participants.get(userId) ?? 0) - (a.participants.get(userId) ?? 0))[0];
3544
+ if (!target) return;
3545
+ const cooldownKey = `${params.accountId}:${userId}`;
3546
+ let reserved;
3547
+ try {
3548
+ reserved = params.cooldownStore.registerIfAbsent(cooldownKey, now, { ttlMs: SLACK_PRESENCE_GREETING_COOLDOWN_MS });
3549
+ } catch (err) {
3550
+ params.error?.(`slack presence cooldown persistence failed: ${String(err)}`);
3551
+ return;
3552
+ }
3553
+ if (!reserved) return;
3554
+ if (!enqueue(formatSlackPresenceEvent(target, userId), {
3555
+ sessionKey: target.sessionKey,
3556
+ contextKey: `slack:presence-active:${params.accountId}:${userId}`,
3557
+ deliveryContext: {
3558
+ channel: "slack",
3559
+ to: target.to,
3560
+ accountId: params.accountId,
3561
+ threadId: target.threadId
3562
+ }
3563
+ })) {
3564
+ params.cooldownStore.delete(cooldownKey);
3565
+ return;
3566
+ }
3567
+ wake({
3568
+ source: "notifications-event",
3569
+ intent: "immediate",
3570
+ reason: "wake",
3571
+ agentId: target.agentId,
3572
+ sessionKey: target.sessionKey,
3573
+ heartbeat: {
3574
+ target: "slack",
3575
+ to: target.to,
3576
+ accountId: params.accountId
3577
+ }
3578
+ });
3579
+ };
3580
+ const performPoll = async () => {
3581
+ const now = nowMs();
3582
+ pruneTargets(now);
3583
+ const candidates = Array.from(new Set(Array.from(targets.values()).filter(isTargetEligible).flatMap((target) => Array.from(target.participants.keys())))).toSorted();
3584
+ if (candidates.length === 0) return;
3585
+ const count = Math.min(candidates.length, SLACK_PRESENCE_MAX_POLLS_PER_INTERVAL);
3586
+ const selected = Array.from({ length: count }, (_, index) => candidates[(pollOffset + index) % candidates.length]).filter((userId) => Boolean(userId));
3587
+ pollOffset = (pollOffset + count) % candidates.length;
3588
+ for (const userId of selected) {
3589
+ if (stopped) return;
3590
+ try {
3591
+ const response = await params.client.getPresence({ user: userId });
3592
+ if (stopped) return;
3593
+ const next = response.presence === "active" || response.presence === "away" ? response.presence : void 0;
3594
+ if (!next) continue;
3595
+ const previous = presenceByUser.get(userId);
3596
+ presenceByUser.set(userId, next);
3597
+ if (previous === "away" && next === "active") emitTransition(userId, now);
3598
+ } catch (err) {
3599
+ if (stopped) return;
3600
+ params.error?.(`slack presence poll failed for user ${userId}: ${String(err)}`);
3601
+ }
3602
+ }
3603
+ };
3604
+ const pollOnce = () => {
3605
+ if (stopped) return Promise.resolve();
3606
+ if (activePoll) return activePoll;
3607
+ const run = performPoll().finally(() => {
3608
+ if (activePoll === run) activePoll = void 0;
3609
+ });
3610
+ activePoll = run;
3611
+ return run;
3612
+ };
3613
+ return {
3614
+ observe,
3615
+ pollOnce,
3616
+ start: () => {
3617
+ if (timer) return;
3618
+ stopped = false;
3619
+ params.log?.(`slack presence polling enabled for account ${params.accountId}`);
3620
+ timer = setInterval(() => void pollOnce(), SLACK_PRESENCE_POLL_INTERVAL_MS);
3621
+ timer.unref?.();
3622
+ },
3623
+ stop: async () => {
3624
+ stopped = true;
3625
+ if (timer) {
3626
+ clearInterval(timer);
3627
+ timer = void 0;
3628
+ }
3629
+ await activePoll;
3630
+ }
3631
+ };
3632
+ }
3633
+ //#endregion
3634
+ //#region extensions/slack/src/monitor/presence-cooldown-store.ts
3635
+ const SLACK_PRESENCE_COOLDOWN_MAX_ENTRIES = 25e3;
3636
+ function openSlackPresenceCooldownStore() {
3637
+ return getSlackRuntime().state.openSyncKeyedStore({
3638
+ namespace: "presence-greeting-cooldowns",
3639
+ maxEntries: SLACK_PRESENCE_COOLDOWN_MAX_ENTRIES,
3640
+ overflowPolicy: "reject-new",
3641
+ defaultTtlMs: SLACK_PRESENCE_GREETING_COOLDOWN_MS
3642
+ });
3643
+ }
3644
+ //#endregion
3429
3645
  //#region extensions/slack/src/monitor/reconnect-policy.ts
3430
3646
  const SLACK_AUTH_ERROR_RE = /account_inactive|invalid_auth|token_revoked|token_expired|not_authed|org_login_required|team_access_not_granted|user_removed_from_team|team_disabled|missing_scope|cannot_find_service|invalid_token/i;
3431
3647
  const NO_ERROR_DETAIL = "no error detail";
@@ -3614,13 +3830,15 @@ function resolveSlackBoltInterop(params) {
3614
3830
  };
3615
3831
  throw new TypeError("Unable to resolve @slack/bolt App/HTTPReceiver exports");
3616
3832
  }
3617
- function publishSlackConnectedStatus(setStatus) {
3833
+ function publishSlackConnectedStatus(setStatus, identityHealth = {
3834
+ healthState: "healthy",
3835
+ lastError: null
3836
+ }) {
3618
3837
  if (!setStatus) return;
3619
3838
  setStatus({
3620
3839
  connected: true,
3621
3840
  lastConnectedAt: Date.now(),
3622
- healthState: "healthy",
3623
- lastError: null
3841
+ ...identityHealth
3624
3842
  });
3625
3843
  }
3626
3844
  function publishSlackDisconnectedStatus(setStatus, error) {
@@ -3960,7 +4178,7 @@ const SLACK_COMMAND_ARG_CONFIRM_TEXT_MAX = 300;
3960
4178
  const SLACK_HEADER_TEXT_MAX = 150;
3961
4179
  const SLACK_COMMAND_ARG_ACTION_BLOCKS_MAX = 47;
3962
4180
  const loadSlashCommandsRuntime = createLazyRuntimeModule(() => import("./slash-commands.runtime-BTTMlmwy.js"));
3963
- const loadSlashDispatchRuntime = createLazyRuntimeModule(() => import("./slash-dispatch.runtime-C0Otuf_T.js"));
4181
+ const loadSlashDispatchRuntime = createLazyRuntimeModule(() => import("./slash-dispatch.runtime-CSja9VuD.js"));
3964
4182
  const loadSlackPluginCommandsRuntime = createLazyRuntimeModule(() => import("./slash-plugin-commands.runtime-Dosfcx3X.js"));
3965
4183
  const loadSlashSkillCommandsRuntime = createLazyRuntimeModule(() => import("./slash-skill-commands.runtime-CD1J2ODY.js"));
3966
4184
  function resolveSlackCommandMenuModelContext(params) {
@@ -4700,7 +4918,7 @@ async function getSlackBoltInterop() {
4700
4918
  }
4701
4919
  return slackBoltInterop;
4702
4920
  }
4703
- const loadSlackRelaySource = createLazyRuntimeModule(() => import("./relay-source-B-6LFUdz.js"));
4921
+ const loadSlackRelaySource = createLazyRuntimeModule(() => import("./relay-source-DMmgtvg4.js"));
4704
4922
  const SLACK_WEBHOOK_MAX_BODY_BYTES = 1024 * 1024;
4705
4923
  const SLACK_WEBHOOK_BODY_TIMEOUT_MS = 3e4;
4706
4924
  function resolveStableSlackUserIdEntry(raw) {
@@ -4890,12 +5108,11 @@ async function monitorSlackProvider(opts = {}) {
4890
5108
  let botUserId = "";
4891
5109
  let botId = "";
4892
5110
  const expectedApiAppIdFromAppToken = slackMode === "socket" ? parseApiAppIdFromAppToken(appToken) : void 0;
4893
- let authTestFailed = false;
4894
5111
  let authTestError;
4895
5112
  let authIdentityWarning;
4896
5113
  let authTestIdentity;
4897
5114
  try {
4898
- const auth = await app.client.auth.test();
5115
+ const auth = await createSlackStartupAuthClient(botToken, clientOptions).auth.test();
4899
5116
  const authUserId = normalizeOptionalString(auth.user_id) ?? "";
4900
5117
  botId = normalizeOptionalString(auth.bot_id) ?? "";
4901
5118
  botUserId = botId ? authUserId : "";
@@ -4904,24 +5121,26 @@ async function monitorSlackProvider(opts = {}) {
4904
5121
  auth,
4905
5122
  accountId: account.accountId
4906
5123
  });
4907
- if (!authUserId && !enterpriseOrgInstall) {
4908
- authTestFailed = true;
4909
- authTestError = "auth.test returned no user_id";
4910
- }
5124
+ if (!authUserId && !enterpriseOrgInstall) authTestError = "auth.test returned no user_id";
4911
5125
  } catch (err) {
4912
- authTestFailed = true;
4913
5126
  authTestError = err instanceof Error ? err.message : String(err);
4914
5127
  }
4915
5128
  const installationIdentity = resolveSlackInstallationIdentity({
4916
5129
  enterpriseOrgInstall,
4917
- auth: authTestFailed ? void 0 : authTestIdentity,
5130
+ auth: authTestError === void 0 ? authTestIdentity : void 0,
4918
5131
  authError: authTestError,
4919
5132
  transportApiAppId: expectedApiAppIdFromAppToken
4920
5133
  });
4921
5134
  const teamId = installationIdentity.kind === "workspace" ? installationIdentity.teamId : "";
4922
5135
  const apiAppId = installationIdentity.kind === "degraded" ? "" : installationIdentity.apiAppId ?? "";
4923
- if (authTestFailed) runtime.log?.(warn(`[${account.accountId}] slack auth.test failed at boot (${authTestError ?? "unknown error"}); explicit bot-mention detection will be disabled until restart with a valid bot token; required-mention channels will fail closed without another trusted activation signal`));
5136
+ if (authTestError !== void 0) runtime.log?.(warn(`[${account.accountId}] slack auth.test failed at boot (${authTestError}); explicit bot-mention detection will be disabled until restart with a valid bot token; required-mention channels will fail closed without another trusted activation signal`));
4924
5137
  if (authIdentityWarning) runtime.log?.(warn(authIdentityWarning));
5138
+ const identityHealth = resolveSlackIdentityHealth({
5139
+ installationIdentity,
5140
+ botUserId,
5141
+ authTestError,
5142
+ authIdentityWarning
5143
+ });
4925
5144
  if (apiAppId && expectedApiAppIdFromAppToken && apiAppId !== expectedApiAppIdFromAppToken) runtime.error?.(`slack token mismatch: bot token app_id=${apiAppId} but app token looks like app_id=${expectedApiAppIdFromAppToken}`);
4926
5145
  const ctx = createSlackMonitorContext({
4927
5146
  cfg,
@@ -4968,10 +5187,24 @@ async function monitorSlackProvider(opts = {}) {
4968
5187
  lastInboundAt: Date.now()
4969
5188
  });
4970
5189
  } : void 0;
5190
+ const presenceEventsEnabled = hasSlackPresenceEventsEnabled({
5191
+ account: slackCfg.presenceEvents,
5192
+ channels: slackCfg.channels
5193
+ });
5194
+ const presenceMonitor = installationIdentity.kind !== "enterprise" && presenceEventsEnabled ? createSlackPresenceMonitor({
5195
+ accountId: account.accountId,
5196
+ accountConfig: slackCfg.presenceEvents,
5197
+ client: app.client.users,
5198
+ cooldownStore: openSlackPresenceCooldownStore(),
5199
+ log: runtime.log,
5200
+ error: runtime.error
5201
+ }) : void 0;
5202
+ if (installationIdentity.kind === "enterprise" && presenceEventsEnabled) runtime.log?.(warn("slack presence events are unavailable for Enterprise Grid org installs"));
4971
5203
  const handleSlackMessage = createSlackMessageHandler({
4972
5204
  ctx,
4973
5205
  account,
4974
- trackEvent
5206
+ trackEvent,
5207
+ onPrepared: presenceMonitor?.observe
4975
5208
  });
4976
5209
  if (installationIdentity.kind !== "enterprise" && isSlackAnyNativeApprovalClientEnabled({
4977
5210
  cfg,
@@ -4999,6 +5232,7 @@ async function monitorSlackProvider(opts = {}) {
4999
5232
  appHomeSlashCommandName: commandRegistration.mode === "single" ? commandRegistration.name : void 0,
5000
5233
  trackEvent
5001
5234
  });
5235
+ presenceMonitor?.start();
5002
5236
  if (slackMode === "http" && slackHttpHandler) unregisterHttpHandler = registerSlackHttpHandler({
5003
5237
  path: slackWebhookPath,
5004
5238
  handler: slackHttpHandler,
@@ -5113,10 +5347,10 @@ async function monitorSlackProvider(opts = {}) {
5113
5347
  abortSignal: opts.abortSignal,
5114
5348
  onStarted: () => {
5115
5349
  reconnectAttempts = 0;
5116
- publishSlackConnectedStatus(opts.setStatus);
5350
+ publishSlackConnectedStatus(opts.setStatus, identityHealth);
5117
5351
  if (!hasLoggedSocketConnected) {
5118
5352
  hasLoggedSocketConnected = true;
5119
- runtime.log?.("slack socket mode connected");
5353
+ runtime.log?.(identityHealth.healthState === "degraded" ? "slack socket mode connected (degraded identity)" : "slack socket mode connected");
5120
5354
  }
5121
5355
  }
5122
5356
  });
@@ -5178,6 +5412,7 @@ async function monitorSlackProvider(opts = {}) {
5178
5412
  });
5179
5413
  }
5180
5414
  } finally {
5415
+ await presenceMonitor?.stop();
5181
5416
  if (slackMode === "relay") setSlackDefaultSendIdentity(account.accountId, void 0);
5182
5417
  opts.abortSignal?.removeEventListener("abort", stopOnAbort);
5183
5418
  unregisterSocketModeConnectionDiagnostics();
@@ -1,4 +1,4 @@
1
- import { c as formatUnknownError, s as SLACK_SOCKET_RECONNECT_POLICY } from "./provider-Ds-y-imP.js";
1
+ import { c as formatUnknownError, s as SLACK_SOCKET_RECONNECT_POLICY } from "./provider-CmeoUiIM.js";
2
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { computeBackoff, sleepWithAbort, warn } from "openclaw/plugin-sdk/runtime-env";
4
4
  import { Buffer } from "node:buffer";
@@ -1,6 +1,6 @@
1
- import { C as hasSlackNativeDataBlock, D as markdownToSlackMrkdwnChunks, F as SLACK_TEXT_LIMIT, f as hasSlackReplyStructuredContent, h as resolveSlackReplyBlocks, k as buildSlackBlocksFallbackText, m as resolveSlackReplyBlockResolution, w as isSlackInvalidBlocksError, x as buildSlackNativeDataAccessibilityText } from "./group-policy-C-b2ZnSl.js";
2
- import { l as buildSlackNativeDataDeliveryPlan, r as sendMessageSlack, u as chunkSlackTextAtHardLimit } from "./send-NEfJ0GvM.js";
3
- import { a as createSlackResponseUrlBudget, i as SlackResponseAlreadyReportedError } from "./provider-Ds-y-imP.js";
1
+ import { A as buildSlackBlocksFallbackText, I as SLACK_TEXT_LIMIT, O as markdownToSlackMrkdwnChunks, S as buildSlackNativeDataAccessibilityText, T as isSlackInvalidBlocksError, g as resolveSlackReplyBlocks, h as resolveSlackReplyBlockResolution, p as hasSlackReplyStructuredContent, w as hasSlackNativeDataBlock } from "./group-policy-85UWiriS.js";
2
+ import { l as buildSlackNativeDataDeliveryPlan, r as sendMessageSlack, u as chunkSlackTextAtHardLimit } from "./send-DYp8ca-l.js";
3
+ import { a as createSlackResponseUrlBudget, i as SlackResponseAlreadyReportedError } from "./provider-CmeoUiIM.js";
4
4
  import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-reference";
5
5
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
6
6
  import { SILENT_REPLY_TOKEN, chunkMarkdownTextWithMode, isSilentReplyText } from "openclaw/plugin-sdk/reply-chunking";
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { n as createSlackLookupClient } from "./client-D2F6m8CP.js";
2
+ import { n as createSlackLookupClient } from "./client-WIPAS3Yr.js";
3
3
  import { t as collectSlackCursorPages } from "./cursor-pages-DSmTg0su.js";
4
4
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { resolveDirectoryAllowlistEntries } from "openclaw/plugin-sdk/directory-runtime";
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { n as createSlackLookupClient } from "./client-D2F6m8CP.js";
2
+ import { n as createSlackLookupClient } from "./client-WIPAS3Yr.js";
3
3
  import { t as collectSlackCursorPages } from "./cursor-pages-DSmTg0su.js";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { resolveDirectoryAllowlistEntries } from "openclaw/plugin-sdk/directory-runtime";
@@ -1,8 +1,8 @@
1
1
  import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
2
2
  //#region extensions/slack/src/runtime.ts
3
- const { setRuntime: setSlackRuntime, tryGetRuntime: getOptionalSlackRuntime } = createPluginRuntimeStore({
3
+ const { setRuntime: setSlackRuntime, tryGetRuntime: getOptionalSlackRuntime, getRuntime: getSlackRuntime } = createPluginRuntimeStore({
4
4
  pluginId: "slack",
5
5
  errorMessage: "Slack runtime not initialized"
6
6
  });
7
7
  //#endregion
8
- export { setSlackRuntime as n, getOptionalSlackRuntime as t };
8
+ export { getSlackRuntime as n, setSlackRuntime as r, getOptionalSlackRuntime as t };
@@ -1,5 +1,5 @@
1
1
  import "./target-parsing-N6lHogYZ.js";
2
- import "./client-D2F6m8CP.js";
2
+ import "./client-WIPAS3Yr.js";
3
3
  import "./config-api-Df9a1B8C.js";
4
4
  import "openclaw/plugin-sdk/account-id";
5
5
  import { createActionGate as createActionGate$1, imageResultFromFile, jsonResult, readPositiveIntegerParam, readReactionParams, readStringParam, withNormalizedTimestamp } from "openclaw/plugin-sdk/channel-actions";
@@ -1,14 +1,14 @@
1
1
  import { t as registerSlackPluginHttpRoutes } from "./plugin-routes-CLp4obpN.js";
2
2
  import { a as resolveSlackAccount, f as resolveSlackAppToken, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, p as resolveSlackBotToken, t as listEnabledSlackAccounts } from "./accounts-BOJJiHSr.js";
3
- import { n as resolveSlackGroupToolPolicy, t as resolveSlackGroupRequireMention } from "./group-policy-C-b2ZnSl.js";
4
- import { n as setSlackRuntime } from "./runtime-CauEvswP.js";
5
- import { a as listSlackEmojis, c as pinSlackMessage, d as removeOwnSlackReactions, f as removeSlackReaction, h as unpinSlackMessage, i as getSlackMemberInfo, l as reactSlackMessage, m as sendSlackMessage, o as listSlackPins, r as editSlackMessage, s as listSlackReactions, t as deleteSlackMessage, u as readSlackMessages } from "./actions-DkTcWmpT.js";
6
- import { r as sendMessageSlack } from "./send-NEfJ0GvM.js";
7
- import { t as probeSlack } from "./probe-CfALk0l4.js";
8
- import { t as resolveSlackChannelAllowlist } from "./resolve-channels-DOMgNCWb.js";
9
- import { t as resolveSlackUserAllowlist } from "./resolve-users-aL6-Ssee.js";
10
- import { t as monitorSlackProvider } from "./provider-Ds-y-imP.js";
11
- import { n as slackActionRuntime, t as handleSlackAction } from "./action-runtime-p6M2ULpv.js";
12
- import { n as listSlackDirectoryGroupsLive, r as listSlackDirectoryPeersLive } from "./directory-live-DX7yFsM-.js";
13
- import "./monitor-BN_uuvrQ.js";
3
+ import { n as resolveSlackGroupRequireMention, r as resolveSlackGroupToolPolicy } from "./group-policy-85UWiriS.js";
4
+ import { r as setSlackRuntime } from "./runtime-JSVZSWAj.js";
5
+ import { a as listSlackEmojis, c as pinSlackMessage, d as removeOwnSlackReactions, f as removeSlackReaction, h as unpinSlackMessage, i as getSlackMemberInfo, l as reactSlackMessage, m as sendSlackMessage, o as listSlackPins, r as editSlackMessage, s as listSlackReactions, t as deleteSlackMessage, u as readSlackMessages } from "./actions-BZiuSTIq.js";
6
+ import { r as sendMessageSlack } from "./send-DYp8ca-l.js";
7
+ import { t as probeSlack } from "./probe-CN0ssfLN.js";
8
+ import { t as resolveSlackChannelAllowlist } from "./resolve-channels-Rfts6POK.js";
9
+ import { t as resolveSlackUserAllowlist } from "./resolve-users-y6wAxR8E.js";
10
+ import { t as monitorSlackProvider } from "./provider-CmeoUiIM.js";
11
+ import { n as slackActionRuntime, t as handleSlackAction } from "./action-runtime-Cee2ih0s.js";
12
+ import { n as listSlackDirectoryGroupsLive, r as listSlackDirectoryPeersLive } from "./directory-live-D_yZhjgp.js";
13
+ import "./monitor-CalGciTs.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 };
@@ -1,2 +1,2 @@
1
- import { n as setSlackRuntime } from "./runtime-CauEvswP.js";
1
+ import { r as setSlackRuntime } from "./runtime-JSVZSWAj.js";
2
2
  export { setSlackRuntime };
@@ -1,5 +1,5 @@
1
- import { r as formatSlackError } from "./group-policy-C-b2ZnSl.js";
2
- import { i as createSlackWebClient } from "./client-D2F6m8CP.js";
1
+ import { i as formatSlackError } from "./group-policy-85UWiriS.js";
2
+ import { a as createSlackWebClient } from "./client-WIPAS3Yr.js";
3
3
  import { isRecord, normalizeOptionalString, normalizeStringEntries, sortUniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/slack/src/scopes.ts
5
5
  function collectScopes(value, into) {
@@ -1,10 +1,10 @@
1
1
  import { a as resolveSlackAccount, l as resolveSlackOperationToken, p as resolveSlackBotToken } from "./accounts-BOJJiHSr.js";
2
2
  import { i as parseSlackTarget, t as canonicalizeSlackApiTargetId } from "./target-parsing-N6lHogYZ.js";
3
- import { A as buildSlackCompleteBlocksFallbackText, C as hasSlackNativeDataBlock, D as markdownToSlackMrkdwnChunks, E as chunkSlackMrkdwnText, F as SLACK_TEXT_LIMIT, P as SLACK_MESSAGE_TEXT_HARD_LIMIT, S as createSlackNativeDataBaseTextConsumer, T as stripSlackNativeDataBlocks, Z as validateSlackBlocksArray, b as appendSlackNativeDataPlainTextFallback, i as assertSlackDirectSendAllowed, j as renderSlackBlockFallbackText, w as isSlackInvalidBlocksError, x as buildSlackNativeDataAccessibilityText, z as truncateSlackText } from "./group-policy-C-b2ZnSl.js";
3
+ import { B as truncateSlackText, C as createSlackNativeDataBaseTextConsumer, D as chunkSlackMrkdwnText, E as stripSlackNativeDataBlocks, F as SLACK_MESSAGE_TEXT_HARD_LIMIT, I as SLACK_TEXT_LIMIT, M as renderSlackBlockFallbackText, O as markdownToSlackMrkdwnChunks, Q as validateSlackBlocksArray, S as buildSlackNativeDataAccessibilityText, T as isSlackInvalidBlocksError, a as assertSlackDirectSendAllowed, j as buildSlackCompleteBlocksFallbackText, w as hasSlackNativeDataBlock, x as appendSlackNativeDataPlainTextFallback } from "./group-policy-85UWiriS.js";
4
4
  import { n as resolveSlackThreadTsValue, t as normalizeSlackThreadTsCandidate } from "./thread-ts-DUGhaYKq.js";
5
- import { i as createSlackWebClient, r as createSlackTokenCacheKey, s as getSlackWriteClient } from "./client-D2F6m8CP.js";
6
- import { t as getOptionalSlackRuntime } from "./runtime-CauEvswP.js";
7
- import { i as loadOutboundMediaFromUrl } from "./runtime-api-CVb6CQjX.js";
5
+ import { a as createSlackWebClient, c as getSlackWriteClient, i as createSlackTokenCacheKey } from "./client-WIPAS3Yr.js";
6
+ import { t as getOptionalSlackRuntime } from "./runtime-JSVZSWAj.js";
7
+ import { i as loadOutboundMediaFromUrl } from "./runtime-api-BGDyOt1D.js";
8
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
10
10
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
@@ -1,2 +1,2 @@
1
- import { n as resolveSlackDmChannelId, r as sendMessageSlack, t as reconcileSlackUnknownSend } from "./send-NEfJ0GvM.js";
1
+ import { n as resolveSlackDmChannelId, r as sendMessageSlack, t as reconcileSlackUnknownSend } from "./send-DYp8ca-l.js";
2
2
  export { reconcileSlackUnknownSend, resolveSlackDmChannelId, sendMessageSlack };