@openclaw/slack 2026.8.1-beta.2 → 2026.8.1-beta.3

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 (54) hide show
  1. package/dist/{account-inspect-Drw2gAiN.js → account-inspect-YJvFBbCR.js} +1 -1
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{accounts-CK4AVI2_.js → accounts-BlzxuYle.js} +5 -1
  4. package/dist/{accounts.runtime-Cb7QwWBz.js → accounts.runtime-CbabBL8x.js} +1 -1
  5. package/dist/{action-runtime-BkGe7ny_.js → action-runtime-D6jg2CQd.js} +64 -68
  6. package/dist/action-runtime.runtime-JtoOK9l5.js +2 -0
  7. package/dist/{actions-BTDXwwE3.js → actions-DFk0ANVB.js} +52 -212
  8. package/dist/{actions.runtime-DLFyUkvg.js → actions.runtime-CYLsYRai.js} +1 -1
  9. package/dist/api.js +14 -14
  10. package/dist/{approval-handler.runtime-CJaNzAq2.js → approval-handler.runtime-BNvAoKdK.js} +4 -2
  11. package/dist/{channel-D_tovcUL.js → channel-CA5w7qDF.js} +78 -39
  12. package/dist/channel-config-api.js +1 -1
  13. package/dist/channel-plugin-api.js +1 -1
  14. package/dist/{channel-type-B9MSdoGN.js → channel-type-CZWv55Wu.js} +3 -7
  15. package/dist/{channel.setup-Bch9dYmA.js → channel.setup-CpyYsEXH.js} +4 -4
  16. package/dist/{config-schema-xto5jFIx.js → config-schema-CN3XZRX5.js} +23 -7
  17. package/dist/conversation-binding-route-DFVLUdYF.js +115 -0
  18. package/dist/{directory-config-CNBz8lJa.js → directory-config-BGYyuzWh.js} +1 -1
  19. package/dist/directory-contract-api.js +1 -1
  20. package/dist/{directory-live-CFKUtW9E.js → directory-live-DjUJQLbq.js} +2 -2
  21. package/dist/{group-policy-c4RP9bjc.js → group-policy-DyfB_ZIE.js} +38 -24
  22. package/dist/{message-tool-api-BykQB4AU.js → message-tool-api-CqMr5Rmc.js} +2 -2
  23. package/dist/message-tool-api.js +1 -1
  24. package/dist/{monitor-1nF1NtqT.js → monitor-Chrecrb9.js} +3 -3
  25. package/dist/{outbound-adapter-S81tsswN.js → outbound-adapter-DuRqAQXK.js} +18 -8
  26. package/dist/{pipeline.runtime-BvYsM5JO.js → pipeline.runtime-Bbfd5VFW.js} +376 -324
  27. package/dist/{policy-TapwbeaT.js → policy-BKXSxrIS.js} +1 -1
  28. package/dist/{probe-HoEg_WxB.js → probe-BVA65leh.js} +1 -1
  29. package/dist/{provider-CDNvBXUi.js → provider-CUUiwsg2.js} +65 -44
  30. package/dist/{relay-source-C9leF11u.js → relay-source-mhpMMRG-.js} +1 -1
  31. package/dist/{replies-CeOfv82I.js → replies-SnWyXcsL.js} +36 -25
  32. package/dist/{resolve-channels-CNPrxaXY.js → resolve-channels-BSpqC8jU.js} +1 -1
  33. package/dist/{resolve-users-Dzomuwnr.js → resolve-users-Dvz9pDe0.js} +1 -1
  34. package/dist/{runtime-api-Cj9nxBNv.js → runtime-api-DBi7xc_g.js} +2 -2
  35. package/dist/runtime-api.js +11 -11
  36. package/dist/{scopes-cYXKkrRD.js → scopes-BSk4GZvZ.js} +1 -1
  37. package/dist/security-contract-api.js +1 -1
  38. package/dist/{send-Nor0iBwY.js → send-CtnOxKCc.js} +58 -78
  39. package/dist/{send.runtime-BmgNe6S9.js → send.runtime-kYctMHSd.js} +1 -1
  40. package/dist/setup-plugin-api.js +1 -1
  41. package/dist/{setup-surface-CbX1-Knh.js → setup-surface-BPFfp6So.js} +6 -6
  42. package/dist/{shared-zdT5AMp-.js → shared-DJBaslN7.js} +13 -7
  43. package/dist/{block-text-YtiNkqmx.js → slack-client-kind-BXyOOICI.js} +17 -2
  44. package/dist/{slash-dispatch.runtime-Bnr9GR1S.js → slash-dispatch.runtime-Cf2FTrnf.js} +2 -2
  45. package/openclaw.plugin.json +43 -1
  46. package/package.json +4 -6
  47. package/dist/account-reply-mode-DrUXogvO.js +0 -14
  48. package/dist/action-runtime.runtime-D9I6uc0Q.js +0 -2
  49. package/node_modules/p-map/index.d.ts +0 -155
  50. package/node_modules/p-map/index.js +0 -285
  51. package/node_modules/p-map/license +0 -9
  52. package/node_modules/p-map/package.json +0 -57
  53. package/node_modules/p-map/readme.md +0 -190
  54. package/dist/{security-audit-DR097212.js → security-audit-B_yKr7MW.js} +1 -1
@@ -1,4 +1,4 @@
1
- import { i as resolveDefaultSlackAccountId, r as mergeSlackAccountConfig } from "./accounts-CK4AVI2_.js";
1
+ import { i as resolveDefaultSlackAccountId, r as mergeSlackAccountConfig } from "./accounts-BlzxuYle.js";
2
2
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
3
3
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,4 +1,4 @@
1
- import { t as inspectSlackAccount } from "./account-inspect-Drw2gAiN.js";
1
+ import { t as inspectSlackAccount } from "./account-inspect-YJvFBbCR.js";
2
2
  //#region extensions/slack/account-inspect-api.ts
3
3
  function inspectSlackReadOnlyAccount(cfg, accountId) {
4
4
  return inspectSlackAccount({
@@ -39,7 +39,11 @@ function resolveSlackOperationToken(account, operation) {
39
39
  return account.config.userTokenReadOnly === false ? botToken ?? userToken : botToken;
40
40
  }
41
41
  const { listAccountIds, resolveDefaultAccountId, resolveAccountConfig: resolveMergedSlackAccountConfig } = createAccountListHelpers("slack", {
42
- nestedObjectKeys: ["botLoopProtection", "relay"],
42
+ nestedObjectKeys: [
43
+ "botLoopProtection",
44
+ "presenceEvents",
45
+ "relay"
46
+ ],
43
47
  hasImplicitDefaultAccount: (cfg) => {
44
48
  const slack = cfg.channels?.slack;
45
49
  if (slack?.postAs === "user") {
@@ -1,2 +1,2 @@
1
- import { a as resolveSlackAccount, l as resolveSlackOperationToken, o as resolveSlackAccountAllowFrom } from "./accounts-CK4AVI2_.js";
1
+ import { a as resolveSlackAccount, l as resolveSlackOperationToken, o as resolveSlackAccountAllowFrom } from "./accounts-BlzxuYle.js";
2
2
  export { resolveSlackAccount, resolveSlackAccountAllowFrom, resolveSlackOperationToken };
@@ -1,8 +1,8 @@
1
1
  import { a as parseSlackTarget, n as formatSlackTarget, o as resolveSlackChannelId } from "./target-parsing-BnMD2ZqZ.js";
2
2
  import { t as slackContextTargetsMatch } from "./targets-Cx5W_n3W.js";
3
- import { St as getSlackInstallationKind, T as hasSlackNativeDataBlock, lt as parseSlackBlocksInput, p as assertSlackDetachedTargetAllowed, t as buildSlackChannelIdCandidates } from "./group-policy-c4RP9bjc.js";
4
- import { a as readPositiveIntegerParam, c as withNormalizedTimestamp, n as imageResultFromFile, o as readReactionParams, r as jsonResult, s as readStringParam, t as createActionGate } from "./runtime-api-Cj9nxBNv.js";
5
- import { n as resolveSlackChannelConfig, t as isSlackChannelAllowedByPolicy } from "./policy-TapwbeaT.js";
3
+ import { Et as getSlackInstallationKind, Lt as SLACK_PRIVATE_ACTION_DELIVERY_RESULT, O as hasSlackNativeDataBlock, Rt as resolveSlackAutoThreadId, g as assertSlackDetachedTargetAllowed, pt as parseSlackBlocksInput, t as buildSlackChannelIdCandidates } from "./group-policy-DyfB_ZIE.js";
4
+ import { a as readPositiveIntegerParam, c as withNormalizedTimestamp, n as imageResultFromFile, o as readReactionParams, r as jsonResult, s as readStringParam, t as createActionGate } from "./runtime-api-DBi7xc_g.js";
5
+ import { n as resolveSlackChannelConfig, t as isSlackChannelAllowedByPolicy } from "./policy-BKXSxrIS.js";
6
6
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
7
7
  import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
@@ -25,9 +25,9 @@ const pinActions = /* @__PURE__ */ new Set([
25
25
  "listPins"
26
26
  ]);
27
27
  const SLACK_REACTION_USER_LIMIT = 100;
28
- const loadSlackActionsRuntime = createLazyRuntimeModule(() => import("./actions.runtime-DLFyUkvg.js"));
29
- const loadSlackAccountsRuntime = createLazyRuntimeModule(() => import("./accounts.runtime-Cb7QwWBz.js"));
30
- const loadSlackChannelTypeRuntime = createLazyRuntimeModule(() => import("./channel-type-B9MSdoGN.js").then((n) => n.t));
28
+ const loadSlackActionsRuntime = createLazyRuntimeModule(() => import("./actions.runtime-CYLsYRai.js"));
29
+ const loadSlackAccountsRuntime = createLazyRuntimeModule(() => import("./accounts.runtime-CbabBL8x.js"));
30
+ const loadSlackChannelTypeRuntime = createLazyRuntimeModule(() => import("./channel-type-CZWv55Wu.js").then((n) => n.t));
31
31
  function createLazySlackAction(key) {
32
32
  return (async (...args) => {
33
33
  const action = (await loadSlackActionsRuntime())[key];
@@ -54,26 +54,15 @@ const slackActionRuntime = {
54
54
  sendSlackMessage: createLazySlackAction("sendSlackMessage"),
55
55
  unpinSlackMessage: createLazySlackAction("unpinSlackMessage")
56
56
  };
57
- /**
58
- * Resolve threadTs for a Slack message based on context and replyToMode.
59
- * - "all": always inject threadTs
60
- * - "first"/"batched": inject only for the first eligible message (updates hasRepliedRef)
61
- * - "off": never auto-inject
62
- */
63
57
  function resolveThreadTsFromContext(explicitThreadTs, targetChannel, context, opts) {
64
58
  if (explicitThreadTs) return explicitThreadTs;
65
59
  if (opts?.suppressImplicitThread) return;
66
- if (!context?.currentChannelId && !context?.currentMessagingTarget) return;
67
- if (!slackContextTargetsMatch(targetChannel, context)) return;
68
- if (!context.currentThreadTs) {
69
- 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.");
70
- return;
71
- }
72
- if (context.replyToMode === "all") return context.currentThreadTs;
73
- if (isSingleUseReplyToMode(context.replyToMode ?? "off") && context.hasRepliedRef && !context.hasRepliedRef.value) {
74
- context.hasRepliedRef.value = true;
75
- return context.currentThreadTs;
76
- }
60
+ const threadTs = resolveSlackAutoThreadId({
61
+ to: targetChannel,
62
+ toolContext: context
63
+ });
64
+ if (isSingleUseReplyToMode(context?.replyToMode ?? "off") && !context?.hasRepliedRef) return;
65
+ return threadTs;
77
66
  }
78
67
  function readSlackBlocksParam(params) {
79
68
  return slackActionRuntime.parseSlackBlocksInput(params.blocks);
@@ -348,6 +337,17 @@ async function handleSlackAction(params, cfg, context) {
348
337
  }
349
338
  if (messagingActions.has(action)) {
350
339
  if (!isActionEnabled("messages")) throw new Error("Slack messages are disabled.");
340
+ const sendSlackMessage = async (target, content, options) => {
341
+ const replyReference = context?.hasRepliedRef && slackContextTargetsMatch(target, context) ? context.hasRepliedRef : void 0;
342
+ const result = await slackActionRuntime.sendSlackMessage(target, content, {
343
+ ...options,
344
+ ...replyReference ? { [SLACK_PRIVATE_ACTION_DELIVERY_RESULT]: () => {
345
+ replyReference.value = true;
346
+ } } : {}
347
+ });
348
+ if (replyReference) replyReference.value = true;
349
+ return result;
350
+ };
351
351
  switch (action) {
352
352
  case "sendMessage": {
353
353
  const destination = resolveSlackActionTarget(account, readStringParam(params, "to", { required: true }), context).routingTarget;
@@ -385,48 +385,46 @@ async function handleSlackAction(params, cfg, context) {
385
385
  const shouldSplitLongContent = content && content.length > 8e3 && !hasSlackNativeDataBlock(blocks);
386
386
  if (content && shouldSplitLongContent) {
387
387
  const { replyBroadcast: _replyBroadcast, ...blockSendOpts } = sendOpts;
388
- await slackActionRuntime.sendSlackMessage(destination, "", {
388
+ await sendSlackMessage(destination, "", {
389
389
  ...blockSendOpts,
390
390
  blocks
391
391
  });
392
- return await slackActionRuntime.sendSlackMessage(destination, content, sendOpts);
392
+ return await sendSlackMessage(destination, content, sendOpts);
393
393
  }
394
- return await slackActionRuntime.sendSlackMessage(destination, content ?? "", {
394
+ return await sendSlackMessage(destination, content ?? "", {
395
395
  ...sendOpts,
396
396
  blocks
397
397
  });
398
398
  };
399
- const result = preparedMessages?.length ? await (async () => {
400
- let lastResult;
401
- if (mediaUrl) lastResult = await slackActionRuntime.sendSlackMessage(destination, "", {
402
- ...baseSendOpts,
403
- mediaUrl
404
- });
405
- for (const [index, message] of preparedMessages.entries()) lastResult = await slackActionRuntime.sendSlackMessage(destination, message.text, {
406
- ...baseSendOpts,
407
- ...index === 0 && replyBroadcast ? { replyBroadcast: true } : {},
408
- ...message.blocks ? { blocks: message.blocks } : {},
409
- ...message.authoredTextPlacement ? { authoredTextPlacement: message.authoredTextPlacement } : {},
410
- ...Object.hasOwn(message, "nativeDataFallbackBaseText") ? { nativeDataFallbackBaseText: message.nativeDataFallbackBaseText } : {},
411
- ...message.textIsSlackPlainText ? { textIsSlackPlainText: true } : {}
412
- });
413
- if (!lastResult) throw new Error("Slack prepared message plan produced no delivery.");
414
- return lastResult;
415
- })() : blocks ? await (async () => {
416
- if (mediaUrl) await slackActionRuntime.sendSlackMessage(destination, "", {
417
- ...sendOpts,
418
- mediaUrl
419
- });
420
- return await sendContentAndBlocks();
421
- })() : await slackActionRuntime.sendSlackMessage(destination, content ?? "", {
422
- ...sendOpts,
423
- mediaUrl: mediaUrl ?? void 0,
424
- blocks
425
- });
426
- if (context?.hasRepliedRef && slackContextTargetsMatch(destination, context)) context.hasRepliedRef.value = true;
427
399
  return jsonResult({
428
400
  ok: true,
429
- result
401
+ result: preparedMessages?.length ? await (async () => {
402
+ let lastResult;
403
+ if (mediaUrl) lastResult = await sendSlackMessage(destination, "", {
404
+ ...baseSendOpts,
405
+ mediaUrl
406
+ });
407
+ for (const [index, message] of preparedMessages.entries()) lastResult = await sendSlackMessage(destination, message.text, {
408
+ ...baseSendOpts,
409
+ ...index === 0 && replyBroadcast ? { replyBroadcast: true } : {},
410
+ ...message.blocks ? { blocks: message.blocks } : {},
411
+ ...message.authoredTextPlacement ? { authoredTextPlacement: message.authoredTextPlacement } : {},
412
+ ...Object.hasOwn(message, "nativeDataFallbackBaseText") ? { nativeDataFallbackBaseText: message.nativeDataFallbackBaseText } : {},
413
+ ...message.textIsSlackPlainText ? { textIsSlackPlainText: true } : {}
414
+ });
415
+ if (!lastResult) throw new Error("Slack prepared message plan produced no delivery.");
416
+ return lastResult;
417
+ })() : blocks ? await (async () => {
418
+ if (mediaUrl) await sendSlackMessage(destination, "", {
419
+ ...sendOpts,
420
+ mediaUrl
421
+ });
422
+ return await sendContentAndBlocks();
423
+ })() : await sendSlackMessage(destination, content ?? "", {
424
+ ...sendOpts,
425
+ mediaUrl: mediaUrl ?? void 0,
426
+ blocks
427
+ })
430
428
  });
431
429
  }
432
430
  case "uploadFile": {
@@ -441,21 +439,19 @@ async function handleSlackAction(params, cfg, context) {
441
439
  const forceDocument = readBooleanParam(params, "forceDocument") === true;
442
440
  if (readBooleanParam(params, "replyBroadcast")) throw new Error("Slack replyBroadcast is only supported for text or block thread replies.");
443
441
  const threadTs = resolveThreadTsFromContext(readStringParam(params, "threadTs"), destination, context, { suppressImplicitThread: params.topLevel === true || params.threadTs === null });
444
- const result = await slackActionRuntime.sendSlackMessage(destination, initialComment ?? "", {
445
- ...buildActionOpts("write"),
446
- mediaUrl: filePath,
447
- mediaAccess: context?.mediaAccess,
448
- mediaLocalRoots: context?.mediaLocalRoots,
449
- mediaReadFile: context?.mediaReadFile,
450
- threadTs: threadTs ?? void 0,
451
- ...forceDocument ? { forceDocument: true } : {},
452
- ...filename ? { uploadFileName: filename } : {},
453
- ...title ? { uploadTitle: title } : {}
454
- });
455
- if (context?.hasRepliedRef && slackContextTargetsMatch(destination, context)) context.hasRepliedRef.value = true;
456
442
  return jsonResult({
457
443
  ok: true,
458
- result
444
+ result: await sendSlackMessage(destination, initialComment ?? "", {
445
+ ...buildActionOpts("write"),
446
+ mediaUrl: filePath,
447
+ mediaAccess: context?.mediaAccess,
448
+ mediaLocalRoots: context?.mediaLocalRoots,
449
+ mediaReadFile: context?.mediaReadFile,
450
+ threadTs: threadTs ?? void 0,
451
+ ...forceDocument ? { forceDocument: true } : {},
452
+ ...filename ? { uploadFileName: filename } : {},
453
+ ...title ? { uploadTitle: title } : {}
454
+ })
459
455
  });
460
456
  }
461
457
  case "editMessage": {
@@ -0,0 +1,2 @@
1
+ import { t as handleSlackAction } from "./action-runtime-D6jg2CQd.js";
2
+ export { handleSlackAction };
@@ -1,23 +1,19 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { a as resolveSlackAccount, f as resolveSlackBotToken } from "./accounts-CK4AVI2_.js";
3
- import { E as isSlackInvalidBlocksError, K as truncateSlackTextByUtf8Bytes, L as SLACK_EDIT_TEXT_MAX_BYTES, M as normalizeSlackOutboundText, N as buildSlackBlocksFallbackText, P as buildSlackCompleteBlocksFallbackText, S as appendSlackNativeDataPlainTextFallback, T as hasSlackNativeDataBlock, W as countSlackTextUtf8Bytes, at as escapeSlackMrkdwn, k as stripSlackNativeDataBlocks, p as assertSlackDetachedTargetAllowed, ut as validateSlackBlocksArray, x as appendSlackNativeDataFallbackText } from "./group-policy-c4RP9bjc.js";
4
- import { d as getSlackWriteClient, i as createSlackLookupClient } from "./probe-HoEg_WxB.js";
5
- import { a as resolveSlackMessageText$1, i as resolveSlackBlocksText, n as hasSlackTableBlock, r as isSlackUnfurlAttachment, t as hasSlackMessageTableBlock } from "./block-text-YtiNkqmx.js";
6
- import { p as buildSlackNativeDataDeliveryPlan, r as sendMessageSlack } from "./send-Nor0iBwY.js";
2
+ import { a as resolveSlackAccount, f as resolveSlackBotToken } from "./accounts-BlzxuYle.js";
3
+ import { B as SLACK_EDIT_TEXT_MAX_BYTES, F as normalizeSlackOutboundText, I as buildSlackBlocksFallbackText, L as buildSlackCompleteBlocksFallbackText, Lt as SLACK_PRIVATE_ACTION_DELIVERY_RESULT, M as stripSlackNativeDataBlocks, O as hasSlackNativeDataBlock, T as appendSlackNativeDataPlainTextFallback, Y as truncateSlackTextByUtf8Bytes, ct as escapeSlackMrkdwn, g as assertSlackDetachedTargetAllowed, k as isSlackInvalidBlocksError, mt as validateSlackBlocksArray, q as countSlackTextUtf8Bytes, w as appendSlackNativeDataFallbackText } from "./group-policy-DyfB_ZIE.js";
4
+ import { d as getSlackWriteClient, i as createSlackLookupClient } from "./probe-BVA65leh.js";
5
+ import { c as resolveSlackMessageText, i as hasSlackMessageTableBlock, n as fetchWithRuntimeDispatcher, r as saveRemoteMedia, t as isGovSlackClient } from "./slack-client-kind-BXyOOICI.js";
6
+ import { m as buildSlackNativeDataDeliveryPlan, r as sendMessageSlack } from "./send-CtnOxKCc.js";
7
7
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
8
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { logVerbose, logVerbose as logVerbose$1 } from "openclaw/plugin-sdk/runtime-env";
10
- import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
11
10
  import { z } from "zod";
12
11
  import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
13
12
  import fs from "node:fs/promises";
13
+ import { runTasksWithConcurrency } from "openclaw/plugin-sdk/concurrency-runtime";
14
14
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
15
15
  import { normalizeHostname } from "openclaw/plugin-sdk/host-runtime";
16
16
  import { resolveRequestUrl } from "openclaw/plugin-sdk/request-url";
17
- import pMap, { pMapSkip } from "p-map";
18
- import { fetchWithRuntimeDispatcher } from "openclaw/plugin-sdk/runtime-fetch";
19
- import { saveRemoteMedia } from "openclaw/plugin-sdk/media-runtime";
20
- import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
21
17
  //#region extensions/slack/src/edit-text.ts
22
18
  function buildSlackEditTextPayload(content, blocks) {
23
19
  const trimmedContent = content.trim();
@@ -49,173 +45,12 @@ function formatSlackFileReferenceList(files) {
49
45
  return files.map((file) => formatSlackFileReference(file)).join(", ");
50
46
  }
51
47
  //#endregion
52
- //#region extensions/slack/src/monitor/thread.ts
53
- const THREAD_STARTER_CACHE = /* @__PURE__ */ new Map();
54
- const THREAD_STARTER_CACHE_TTL_MS = 360 * 6e4;
55
- const THREAD_STARTER_CACHE_MAX = 2e3;
56
- function evictThreadStarterCache() {
57
- const now = asDateTimestampMs(Date.now());
58
- if (now === void 0) {
59
- THREAD_STARTER_CACHE.clear();
60
- return;
61
- }
62
- for (const [cacheKey, entry] of THREAD_STARTER_CACHE.entries()) if (asDateTimestampMs(entry.expiresAt) === void 0 || entry.expiresAt <= now) THREAD_STARTER_CACHE.delete(cacheKey);
63
- pruneMapToMaxSize(THREAD_STARTER_CACHE, THREAD_STARTER_CACHE_MAX);
64
- }
65
- function formatSlackFilePlaceholder(files) {
66
- return `[attached: ${formatSlackFileReferenceList(files)}]`;
67
- }
68
- function pushUniqueText(parts, value, options = {}) {
69
- const text = options.preserveWhitespace ? typeof value === "string" && value.trim().length > 0 ? value : void 0 : normalizeOptionalString(value);
70
- if (text && !parts.includes(text)) parts.push(text);
71
- }
72
- function resolveSlackBlocksFallbackText(blocks) {
73
- return resolveSlackBlocksText(blocks)?.text;
74
- }
75
- function resolveSlackAttachmentFallbackText(attachments) {
76
- if (!Array.isArray(attachments) || attachments.length === 0) return;
77
- const parts = [];
78
- for (const attachment of attachments) {
79
- const excludeTableBlocks = isSlackUnfurlAttachment(attachment);
80
- const fallbackBlocks = (blocks) => excludeTableBlocks ? blocks?.filter((block) => !hasSlackTableBlock([block])) : blocks;
81
- pushUniqueText(parts, attachment.pretext);
82
- pushUniqueText(parts, attachment.title);
83
- pushUniqueText(parts, attachment.text);
84
- if (!(hasSlackTableBlock(attachment.blocks) && normalizeOptionalString(attachment.fallback) === "[no preview available]")) pushUniqueText(parts, attachment.fallback);
85
- for (const field of attachment.fields ?? []) {
86
- pushUniqueText(parts, field.title);
87
- pushUniqueText(parts, field.value);
88
- }
89
- pushUniqueText(parts, resolveSlackBlocksFallbackText(fallbackBlocks(attachment.blocks)), { preserveWhitespace: true });
90
- pushUniqueText(parts, resolveSlackBlocksFallbackText(fallbackBlocks(attachment.message_blocks)), { preserveWhitespace: true });
91
- }
92
- return parts.length > 0 ? parts.join("\n") : void 0;
93
- }
94
- function resolveSlackMessageText(message) {
95
- const messageText = normalizeOptionalString(message.text) ?? resolveSlackAttachmentFallbackText(message.attachments);
96
- return resolveSlackMessageText$1({
97
- ...message,
98
- text: messageText
99
- }, { preserveMessageTextWhitespace: true });
100
- }
101
- async function resolveSlackThreadStarter(params) {
102
- evictThreadStarterCache();
103
- const cacheKey = JSON.stringify([
104
- params.workspaceScope.accountId,
105
- params.workspaceScope.teamId,
106
- params.channelId,
107
- params.threadTs
108
- ]);
109
- const cached = THREAD_STARTER_CACHE.get(cacheKey);
110
- if (cached) {
111
- const now = asDateTimestampMs(Date.now());
112
- if (now !== void 0 && cached.expiresAt > now) return cached.value;
113
- THREAD_STARTER_CACHE.delete(cacheKey);
114
- }
115
- try {
116
- const message = (await params.client.conversations.replies({
117
- channel: params.channelId,
118
- ts: params.threadTs,
119
- limit: 1,
120
- inclusive: true
121
- }))?.messages?.[0];
122
- const text = message ? resolveSlackMessageText(message) : void 0;
123
- const files = message?.files?.length ? message.files : void 0;
124
- if (!message || !text && !files) return null;
125
- const starter = {
126
- text: text || formatSlackFilePlaceholder(files),
127
- userId: message.user,
128
- botId: message.bot_id,
129
- ts: message.ts,
130
- files
131
- };
132
- const expiresAt = resolveExpiresAtMsFromDurationMs(THREAD_STARTER_CACHE_TTL_MS);
133
- if (expiresAt !== void 0) {
134
- if (THREAD_STARTER_CACHE.has(cacheKey)) THREAD_STARTER_CACHE.delete(cacheKey);
135
- THREAD_STARTER_CACHE.set(cacheKey, {
136
- value: starter,
137
- expiresAt
138
- });
139
- evictThreadStarterCache();
140
- }
141
- return starter;
142
- } catch (err) {
143
- logVerbose$1(`slack thread starter fetch failed channel=${params.channelId} ts=${params.threadTs}: ${formatErrorMessage(err)}`);
144
- return null;
145
- }
146
- }
147
- function resetSlackThreadStarterCacheForTest() {
148
- THREAD_STARTER_CACHE.clear();
149
- }
150
- const SLACK_THREAD_HISTORY_MAX_PAGES = 3;
151
- /**
152
- * Fetches the most recent messages in a Slack thread (excluding the current message).
153
- * Used to populate thread context when a new thread session starts.
154
- *
155
- * Uses cursor pagination and keeps only the latest N retained messages when the full
156
- * thread fits in the bounded fetch window.
157
- */
158
- async function resolveSlackThreadHistory(params) {
159
- const maxMessages = params.limit ?? 20;
160
- if (!Number.isFinite(maxMessages) || maxMessages <= 0) return [];
161
- const fetchLimit = 200;
162
- const retained = [];
163
- let cursor;
164
- let pagesFetched = 0;
165
- try {
166
- do {
167
- pagesFetched += 1;
168
- const response = await params.client.conversations.replies({
169
- channel: params.channelId,
170
- ts: params.threadTs,
171
- limit: fetchLimit,
172
- inclusive: true,
173
- ...cursor ? { cursor } : {}
174
- });
175
- for (const msg of response.messages ?? []) {
176
- if (!resolveSlackMessageText(msg) && !msg.files?.length) continue;
177
- if (params.currentMessageTs && msg.ts === params.currentMessageTs) continue;
178
- retained.push(msg);
179
- }
180
- if (retained.length > maxMessages) retained.splice(0, retained.length - maxMessages);
181
- const next = response.response_metadata?.next_cursor;
182
- cursor = typeof next === "string" && next.trim().length > 0 ? next.trim() : void 0;
183
- } while (cursor && pagesFetched < SLACK_THREAD_HISTORY_MAX_PAGES);
184
- if (cursor) {
185
- logVerbose$1(`slack thread history capped channel=${params.channelId} ts=${params.threadTs} pages=${SLACK_THREAD_HISTORY_MAX_PAGES}`);
186
- return [];
187
- }
188
- return retained.map((msg) => ({
189
- text: resolveSlackMessageText(msg) ?? formatSlackFilePlaceholder(msg.files),
190
- userId: msg.user,
191
- botId: msg.bot_id,
192
- ts: msg.ts,
193
- files: msg.files
194
- }));
195
- } catch (err) {
196
- logVerbose$1(`slack thread history fetch failed channel=${params.channelId} ts=${params.threadTs}: ${formatErrorMessage(err)}`);
197
- return [];
198
- }
199
- }
200
- //#endregion
201
48
  //#region extensions/slack/src/monitor/media.ts
202
49
  var media_exports = /* @__PURE__ */ __exportAll({
203
50
  SLACK_MEDIA_READ_IDLE_TIMEOUT_MS: () => SLACK_MEDIA_READ_IDLE_TIMEOUT_MS,
204
- resetSlackThreadStarterCacheForTest: () => resetSlackThreadStarterCacheForTest,
205
51
  resolveSlackAttachmentContent: () => resolveSlackAttachmentContent,
206
- resolveSlackMedia: () => resolveSlackMedia,
207
- resolveSlackThreadHistory: () => resolveSlackThreadHistory,
208
- resolveSlackThreadStarter: () => resolveSlackThreadStarter
52
+ resolveSlackMedia: () => resolveSlackMedia
209
53
  });
210
- function isGovSlackClient(client) {
211
- if (!client?.slackApiUrl) return false;
212
- try {
213
- const apiUrl = new URL(client.slackApiUrl);
214
- return apiUrl.protocol === "https:" && !apiUrl.port && normalizeHostname(apiUrl.hostname) === "slack-gov.com";
215
- } catch {
216
- return false;
217
- }
218
- }
219
54
  function isSlackHostname(hostname, govSlack) {
220
55
  const normalized = normalizeHostname(hostname);
221
56
  if (!normalized) return false;
@@ -418,45 +253,48 @@ function resolveForwardedAttachmentImageUrl(attachment, govSlack) {
418
253
  async function resolveSlackMedia(params) {
419
254
  const govSlack = isGovSlackClient(params.client);
420
255
  const files = params.files ?? [];
421
- const resolved = await pMap(files.length > 8 ? files.slice(0, 8) : files, async (file) => {
422
- const preloaded = params.preloadedMedia?.get(file);
423
- if (preloaded) return preloaded;
424
- const eventUrl = file.url_private_download ?? file.url_private;
425
- const url = eventUrl ?? await fetchFreshSlackFileUrl({
426
- file,
427
- client: params.client
428
- });
429
- if (!url) return pMapSkip;
430
- const result = await downloadSlackMediaFile({
431
- file,
432
- url,
433
- token: params.token,
434
- maxBytes: params.maxBytes,
435
- readIdleTimeoutMs: params.readIdleTimeoutMs,
436
- totalTimeoutMs: params.totalTimeoutMs,
437
- abortSignal: params.abortSignal,
438
- govSlack
439
- }).catch(() => null);
440
- if (result || !eventUrl) return result ?? pMapSkip;
441
- const freshUrl = await fetchFreshSlackFileUrl({
442
- file,
443
- client: params.client
444
- });
445
- if (!freshUrl) return pMapSkip;
446
- return await downloadSlackMediaFile({
447
- file,
448
- url: freshUrl,
449
- token: params.token,
450
- maxBytes: params.maxBytes,
451
- readIdleTimeoutMs: params.readIdleTimeoutMs,
452
- totalTimeoutMs: params.totalTimeoutMs,
453
- abortSignal: params.abortSignal,
454
- govSlack
455
- }).catch(() => null) ?? pMapSkip;
456
- }, {
457
- concurrency: MAX_SLACK_MEDIA_CONCURRENCY,
458
- stopOnError: true
256
+ const { results } = await runTasksWithConcurrency({
257
+ tasks: (files.length > 8 ? files.slice(0, 8) : files).map((file) => async () => {
258
+ const preloaded = params.preloadedMedia?.get(file);
259
+ if (preloaded) return preloaded;
260
+ const eventUrl = file.url_private_download ?? file.url_private;
261
+ const url = eventUrl ?? await fetchFreshSlackFileUrl({
262
+ file,
263
+ client: params.client
264
+ });
265
+ if (!url) return null;
266
+ const result = await downloadSlackMediaFile({
267
+ file,
268
+ url,
269
+ token: params.token,
270
+ maxBytes: params.maxBytes,
271
+ readIdleTimeoutMs: params.readIdleTimeoutMs,
272
+ totalTimeoutMs: params.totalTimeoutMs,
273
+ abortSignal: params.abortSignal,
274
+ govSlack
275
+ }).catch(() => null);
276
+ if (result || !eventUrl) return result;
277
+ const freshUrl = await fetchFreshSlackFileUrl({
278
+ file,
279
+ client: params.client
280
+ });
281
+ if (!freshUrl) return null;
282
+ return await downloadSlackMediaFile({
283
+ file,
284
+ url: freshUrl,
285
+ token: params.token,
286
+ maxBytes: params.maxBytes,
287
+ readIdleTimeoutMs: params.readIdleTimeoutMs,
288
+ totalTimeoutMs: params.totalTimeoutMs,
289
+ abortSignal: params.abortSignal,
290
+ govSlack
291
+ }).catch(() => null);
292
+ }),
293
+ limit: MAX_SLACK_MEDIA_CONCURRENCY,
294
+ errorMode: "stop",
295
+ throwOnError: true
459
296
  });
297
+ const resolved = results.filter((result) => result !== null);
460
298
  return resolved.length > 0 ? resolved : null;
461
299
  }
462
300
  /** Extracts text and media from forwarded-message attachments. Returns null when empty. */
@@ -527,7 +365,7 @@ async function resolveSlackAttachmentContent(params) {
527
365
  //#region extensions/slack/src/actions.ts
528
366
  function renderSlackReadMessageText(message) {
529
367
  if (!hasSlackMessageTableBlock(message)) return message;
530
- const text = resolveSlackMessageText$1(message, { preserveMessageTextWhitespace: true });
368
+ const text = resolveSlackMessageText(message, { preserveMessageTextWhitespace: true });
531
369
  return text && text !== message.text ? {
532
370
  ...message,
533
371
  text
@@ -691,6 +529,7 @@ async function listSlackReactions(channelId, messageId, opts = {}) {
691
529
  })).message?.reactions ?? [];
692
530
  }
693
531
  async function sendSlackMessage(to, content, opts) {
532
+ const onDeliveryResult = Object.getOwnPropertyDescriptor(opts, SLACK_PRIVATE_ACTION_DELIVERY_RESULT)?.value;
694
533
  return await sendMessageSlack(to, content, {
695
534
  accountId: opts.accountId,
696
535
  cfg: opts.cfg,
@@ -709,6 +548,7 @@ async function sendSlackMessage(to, content, opts) {
709
548
  ...Object.hasOwn(opts, "nativeDataFallbackBaseText") ? { nativeDataFallbackBaseText: opts.nativeDataFallbackBaseText } : {},
710
549
  ...opts.uploadFileName ? { uploadFileName: opts.uploadFileName } : {},
711
550
  ...opts.uploadTitle ? { uploadTitle: opts.uploadTitle } : {},
551
+ ...typeof onDeliveryResult === "function" ? { onDeliveryResult } : {},
712
552
  blocks: opts.blocks
713
553
  });
714
554
  }
@@ -914,4 +754,4 @@ async function downloadSlackFile(fileId, opts) {
914
754
  }))?.[0] ?? null;
915
755
  }
916
756
  //#endregion
917
- export { media_exports as _, getSlackMemberInfo as a, formatSlackFileReference as b, listSlackReactions as c, readSlackMessages as d, removeOwnSlackReactions as f, unpinSlackMessage as g, sendSlackMessage as h, editSlackRenderedMessage as i, pinSlackMessage as l, resolveSlackConversationName as m, downloadSlackFile as n, listSlackEmojis as o, removeSlackReaction as p, editSlackMessage as r, listSlackPins as s, deleteSlackMessage as t, reactSlackMessage as u, resolveSlackThreadHistory as v, buildSlackEditTextPayload as x, resolveSlackThreadStarter as y };
757
+ export { media_exports as _, getSlackMemberInfo as a, formatSlackFileReferenceList as b, listSlackReactions as c, readSlackMessages as d, removeOwnSlackReactions as f, unpinSlackMessage as g, sendSlackMessage as h, editSlackRenderedMessage as i, pinSlackMessage as l, resolveSlackConversationName as m, downloadSlackFile as n, listSlackEmojis as o, removeSlackReaction as p, editSlackMessage as r, listSlackPins as s, deleteSlackMessage as t, reactSlackMessage as u, logVerbose$1 as v, buildSlackEditTextPayload as x, formatSlackFileReference as y };
@@ -1,2 +1,2 @@
1
- import { a as getSlackMemberInfo, c as listSlackReactions, d as readSlackMessages, f as removeOwnSlackReactions, g as unpinSlackMessage, h as sendSlackMessage, l as pinSlackMessage, m as resolveSlackConversationName, n as downloadSlackFile, o as listSlackEmojis, p as removeSlackReaction, r as editSlackMessage, s as listSlackPins, t as deleteSlackMessage, u as reactSlackMessage } from "./actions-BTDXwwE3.js";
1
+ import { a as getSlackMemberInfo, c as listSlackReactions, d as readSlackMessages, f as removeOwnSlackReactions, g as unpinSlackMessage, h as sendSlackMessage, l as pinSlackMessage, m as resolveSlackConversationName, n as downloadSlackFile, o as listSlackEmojis, p as removeSlackReaction, r as editSlackMessage, s as listSlackPins, t as deleteSlackMessage, u as reactSlackMessage } from "./actions-DFk0ANVB.js";
2
2
  export { deleteSlackMessage, downloadSlackFile, editSlackMessage, getSlackMemberInfo, listSlackEmojis, listSlackPins, listSlackReactions, pinSlackMessage, reactSlackMessage, readSlackMessages, removeOwnSlackReactions, removeSlackReaction, resolveSlackConversationName, sendSlackMessage, unpinSlackMessage };
package/dist/api.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import { n as registerSlackHttpHandler, r as normalizeSlackWebhookPath, t as handleSlackHttpRequest } from "./registry-bbjH7IHX.js";
2
- import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, r as mergeSlackAccountConfig, t as listEnabledSlackAccounts } from "./accounts-CK4AVI2_.js";
3
- import { t as resolveSlackReplyToMode } from "./account-reply-mode-DrUXogvO.js";
4
- import { t as inspectSlackAccount } from "./account-inspect-Drw2gAiN.js";
2
+ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, r as mergeSlackAccountConfig, t as listEnabledSlackAccounts } from "./accounts-BlzxuYle.js";
3
+ import { r as resolveSlackReplyToMode } from "./conversation-binding-route-DFVLUdYF.js";
4
+ import { t as inspectSlackAccount } from "./account-inspect-YJvFBbCR.js";
5
5
  import { a as parseSlackTarget, i as normalizeSlackMessagingTarget, o as resolveSlackChannelId, r as looksLikeSlackTargetId } from "./target-parsing-BnMD2ZqZ.js";
6
6
  import "./targets-Cx5W_n3W.js";
7
- import { n as buildSlackThreadingToolContext, r as resolveSlackAutoThreadId, t as slackPlugin } from "./channel-D_tovcUL.js";
8
- import { H as buildSlackPresentationBlocks, V as buildSlackInteractiveBlocks, a as allowListMatches, c as normalizeSlackAllowOwnerEntry, ct as SLACK_MAX_BLOCKS, f as resolveSlackUserAllowed, i as resolveSlackGroupToolPolicy, l as normalizeSlackSlug, lt as parseSlackBlocksInput, o as normalizeAllowList, r as resolveSlackGroupRequireMention, s as normalizeAllowListLower, u as resolveSlackAllowListMatch, ut as validateSlackBlocksArray } from "./group-policy-c4RP9bjc.js";
9
- import { n as extractSlackToolSend, r as listSlackMessageActions } from "./message-tool-api-BykQB4AU.js";
10
- import { _ as resolveSlackWriteClientOptions, c as createSlackWebClient, d as getSlackWriteClient, f as SLACK_DEFAULT_RETRY_OPTIONS, g as resolveSlackWebClientOptions, l as createSlackWriteClient, p as SLACK_WRITE_RETRY_OPTIONS, s as createSlackTokenCacheKey, t as probeSlack } from "./probe-HoEg_WxB.js";
11
- import { n as resolveSlackChannelType } from "./channel-type-B9MSdoGN.js";
12
- import { t as slackSetupPlugin } from "./channel.setup-Bch9dYmA.js";
13
- import { a as getSlackMemberInfo, c as listSlackReactions, d as readSlackMessages, f as removeOwnSlackReactions, g as unpinSlackMessage, h as sendSlackMessage, l as pinSlackMessage, n as downloadSlackFile, o as listSlackEmojis, p as removeSlackReaction, r as editSlackMessage, s as listSlackPins, t as deleteSlackMessage, u as reactSlackMessage } from "./actions-BTDXwwE3.js";
14
- import { f as recordSlackThreadParticipation, l as hasSlackThreadParticipation, s as clearSlackThreadParticipationCache } from "./send-Nor0iBwY.js";
15
- import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-CNBz8lJa.js";
16
- import { t as collectSlackSecurityAuditFindings } from "./security-audit-DR097212.js";
17
- import { n as resolveSlackRuntimeGroupPolicy } from "./provider-CDNvBXUi.js";
7
+ import { G as buildSlackPresentationBlocks, Rt as resolveSlackAutoThreadId, W as buildSlackInteractiveBlocks, c as allowListMatches, d as normalizeSlackAllowOwnerEntry, f as normalizeSlackSlug, ft as SLACK_MAX_BLOCKS, h as resolveSlackUserAllowed, i as resolveSlackGroupToolPolicy, l as normalizeAllowList, mt as validateSlackBlocksArray, p as resolveSlackAllowListMatch, pt as parseSlackBlocksInput, r as resolveSlackGroupRequireMention, u as normalizeAllowListLower } from "./group-policy-DyfB_ZIE.js";
8
+ import { n as buildSlackThreadingToolContext, t as slackPlugin } from "./channel-CA5w7qDF.js";
9
+ import { n as extractSlackToolSend, r as listSlackMessageActions } from "./message-tool-api-CqMr5Rmc.js";
10
+ import { _ as resolveSlackWriteClientOptions, c as createSlackWebClient, d as getSlackWriteClient, f as SLACK_DEFAULT_RETRY_OPTIONS, g as resolveSlackWebClientOptions, l as createSlackWriteClient, p as SLACK_WRITE_RETRY_OPTIONS, s as createSlackTokenCacheKey, t as probeSlack } from "./probe-BVA65leh.js";
11
+ import { n as resolveSlackChannelType } from "./channel-type-CZWv55Wu.js";
12
+ import { t as slackSetupPlugin } from "./channel.setup-CpyYsEXH.js";
13
+ import { a as getSlackMemberInfo, c as listSlackReactions, d as readSlackMessages, f as removeOwnSlackReactions, g as unpinSlackMessage, h as sendSlackMessage, l as pinSlackMessage, n as downloadSlackFile, o as listSlackEmojis, p as removeSlackReaction, r as editSlackMessage, s as listSlackPins, t as deleteSlackMessage, u as reactSlackMessage } from "./actions-DFk0ANVB.js";
14
+ import { f as recordSlackThreadParticipation, l as hasSlackThreadParticipation, s as clearSlackThreadParticipationCache } from "./send-CtnOxKCc.js";
15
+ import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-BGYyuzWh.js";
16
+ import { t as collectSlackSecurityAuditFindings } from "./security-audit-B_yKr7MW.js";
17
+ import { n as resolveSlackRuntimeGroupPolicy } from "./provider-CUUiwsg2.js";
18
18
  export { SLACK_DEFAULT_RETRY_OPTIONS, SLACK_MAX_BLOCKS, SLACK_WRITE_RETRY_OPTIONS, allowListMatches, buildSlackInteractiveBlocks, buildSlackPresentationBlocks, buildSlackThreadingToolContext, clearSlackThreadParticipationCache, collectSlackSecurityAuditFindings, createSlackTokenCacheKey, createSlackWebClient, createSlackWriteClient, deleteSlackMessage, downloadSlackFile, editSlackMessage, extractSlackToolSend, getSlackMemberInfo, getSlackWriteClient, handleSlackHttpRequest, hasSlackThreadParticipation, inspectSlackAccount, listEnabledSlackAccounts, listSlackAccountIds, listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig, listSlackEmojis, listSlackMessageActions, listSlackPins, listSlackReactions, looksLikeSlackTargetId, mergeSlackAccountConfig, normalizeAllowList, normalizeAllowListLower, normalizeSlackAllowOwnerEntry, normalizeSlackMessagingTarget, normalizeSlackSlug, normalizeSlackWebhookPath, parseSlackBlocksInput, 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 };
@@ -1,6 +1,6 @@
1
1
  import { a as parseSlackTarget } from "./target-parsing-BnMD2ZqZ.js";
2
- import { At as normalizeSlackApproverId, K as truncateSlackTextByUtf8Bytes, L as SLACK_EDIT_TEXT_MAX_BYTES, _ as resolveSlackReplyBlocks, ft as isSlackAnyNativeApprovalClientEnabled, yt as shouldHandleSlackNativeApprovalRequest } from "./group-policy-c4RP9bjc.js";
3
- import { r as sendMessageSlack } from "./send-Nor0iBwY.js";
2
+ import { B as SLACK_EDIT_TEXT_MAX_BYTES, Ct as shouldHandleSlackNativeApprovalRequest, Pt as normalizeSlackApproverId, Y as truncateSlackTextByUtf8Bytes, b as resolveSlackReplyBlocks, gt as isSlackAnyNativeApprovalClientEnabled, lt as SLACK_APPROVAL_HEADER_BLOCK_ID } from "./group-policy-DyfB_ZIE.js";
3
+ import { r as sendMessageSlack } from "./send-CtnOxKCc.js";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { buildChannelApprovalNativeTargetKey } from "openclaw/plugin-sdk/approval-native-runtime";
6
6
  import { buildApprovalPresentationFromActionDescriptors } from "openclaw/plugin-sdk/approval-reply-runtime";
@@ -123,6 +123,7 @@ function buildSlackExecPendingApprovalBlocks(view) {
123
123
  return [
124
124
  {
125
125
  type: "section",
126
+ block_id: SLACK_APPROVAL_HEADER_BLOCK_ID,
126
127
  text: {
127
128
  type: "mrkdwn",
128
129
  text: "*Exec approval required*\nA command needs your approval."
@@ -147,6 +148,7 @@ function buildSlackPluginPendingApprovalBlocks(view) {
147
148
  return [
148
149
  {
149
150
  type: "section",
151
+ block_id: SLACK_APPROVAL_HEADER_BLOCK_ID,
150
152
  text: {
151
153
  type: "mrkdwn",
152
154
  text: `*Plugin approval required*\n${truncateSlackMrkdwn(resolveSlackPluginDescription(view), 2600)}`