@openclaw/slack 2026.7.2-beta.7 → 2026.8.1-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 (78) hide show
  1. package/dist/{account-inspect-DEKpg9Ip.js → account-inspect-Drw2gAiN.js} +1 -1
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{accounts-CHAeNZOX.js → accounts-CK4AVI2_.js} +2 -2
  4. package/dist/{accounts.runtime-BHD4Ma2R.js → accounts.runtime-Cb7QwWBz.js} +1 -1
  5. package/dist/{action-runtime-DfuYoMjG.js → action-runtime-BkGe7ny_.js} +148 -76
  6. package/dist/action-runtime.runtime-D9I6uc0Q.js +2 -0
  7. package/dist/{actions-D3NuJvva.js → actions-BTDXwwE3.js} +85 -44
  8. package/dist/actions.runtime-DLFyUkvg.js +2 -0
  9. package/dist/api.js +15 -15
  10. package/dist/{approval-handler.runtime-BA05P0QT.js → approval-handler.runtime-CJaNzAq2.js} +51 -14
  11. package/dist/{block-text-DkHaoGem.js → block-text-YtiNkqmx.js} +1 -1
  12. package/dist/{channel-B9fVdW3s.js → channel-D_tovcUL.js} +151 -91
  13. package/dist/channel-config-api.js +1 -1
  14. package/dist/channel-plugin-api.js +1 -1
  15. package/dist/{channel-type-DXyos1d2.js → channel-type-B9MSdoGN.js} +9 -8
  16. package/dist/{config-adapter-CxBQH8fq.js → channel.setup-Bch9dYmA.js} +83 -25
  17. package/dist/{config-schema-SgZT6nXV.js → config-schema-xto5jFIx.js} +5 -11
  18. package/dist/{directory-config-CnCIAktf.js → directory-config-CNBz8lJa.js} +3 -3
  19. package/dist/directory-contract-api.js +1 -1
  20. package/dist/{directory-live-DKunWh3A.js → directory-live-CFKUtW9E.js} +13 -22
  21. package/dist/{doctor-contract-CsGH1Dfc.js → doctor-contract-BAy7-EUQ.js} +30 -3
  22. package/dist/doctor-contract-api.js +1 -1
  23. package/dist/{group-policy-NQZti9t-.js → group-policy-c4RP9bjc.js} +248 -163
  24. package/dist/index.js +4 -1
  25. package/dist/{message-tool-api-DkhFpMoy.js → message-tool-api-BykQB4AU.js} +14 -3
  26. package/dist/message-tool-api.js +1 -1
  27. package/dist/{monitor-CmKz0wtI.js → monitor-1nF1NtqT.js} +3 -3
  28. package/dist/{outbound-adapter-BkuMp2Vs.js → outbound-adapter-S81tsswN.js} +19 -17
  29. package/dist/{pipeline.runtime-DgtmuYCP.js → pipeline.runtime-BvYsM5JO.js} +1087 -682
  30. package/dist/{policy-PRysPn23.js → policy-TapwbeaT.js} +18 -14
  31. package/dist/{probe-CgDsSops.js → probe-HoEg_WxB.js} +38 -18
  32. package/dist/{provider-DmRizMZt.js → provider-CDNvBXUi.js} +3422 -2590
  33. package/dist/{relay-source-Blxj8xb4.js → relay-source-C9leF11u.js} +11 -21
  34. package/dist/{replies-4s_Vq_z9.js → replies-CeOfv82I.js} +52 -6
  35. package/dist/{resolve-channels-yEqmM-3I.js → resolve-channels-CNPrxaXY.js} +39 -12
  36. package/dist/{resolve-users-BOrt5K-5.js → resolve-users-Dzomuwnr.js} +28 -5
  37. package/dist/{runtime-api-QMb-Q5Ko.js → runtime-api-Cj9nxBNv.js} +3 -3
  38. package/dist/runtime-api.js +11 -11
  39. package/dist/{scopes-BJSrkAp6.js → scopes-cYXKkrRD.js} +1 -1
  40. package/dist/{send-DsLeZpST.js → send-Nor0iBwY.js} +211 -105
  41. package/dist/{send.runtime-gUdK6V3h.js → send.runtime-BmgNe6S9.js} +1 -1
  42. package/dist/setup-entry.js +1 -4
  43. package/dist/setup-plugin-api.js +1 -1
  44. package/dist/{setup-surface-BeNzrMrJ.js → setup-surface-CbX1-Knh.js} +6 -6
  45. package/dist/{shared-DgIN3Dcr.js → shared-zdT5AMp-.js} +36 -42
  46. package/dist/{slash-dispatch.runtime-zPkyl7dB.js → slash-dispatch.runtime-Bnr9GR1S.js} +1 -1
  47. package/dist/{streaming-compat-3_X-21wW.js → streaming-compat-B-e0mqM0.js} +3 -8
  48. package/dist/{target-parsing-N6lHogYZ.js → target-parsing-BnMD2ZqZ.js} +40 -2
  49. package/dist/{targets-KmjP2E8s.js → targets-Cx5W_n3W.js} +1 -1
  50. package/node_modules/@slack/bolt/node_modules/@types/node/README.md +1 -1
  51. package/node_modules/@slack/bolt/node_modules/@types/node/crypto.d.ts +1 -1
  52. package/node_modules/@slack/bolt/node_modules/@types/node/package.json +2 -2
  53. package/node_modules/@slack/socket-mode/node_modules/@types/node/README.md +1 -1
  54. package/node_modules/@slack/socket-mode/node_modules/@types/node/crypto.d.ts +1 -1
  55. package/node_modules/@slack/socket-mode/node_modules/@types/node/package.json +2 -2
  56. package/node_modules/@slack/web-api/node_modules/@types/node/README.md +1 -1
  57. package/node_modules/@slack/web-api/node_modules/@types/node/crypto.d.ts +1 -1
  58. package/node_modules/@slack/web-api/node_modules/@types/node/package.json +2 -2
  59. package/node_modules/undici/lib/cache/memory-cache-store.js +54 -9
  60. package/node_modules/undici/lib/cache/sqlite-cache-store.js +7 -1
  61. package/node_modules/undici/lib/core/request.js +12 -1
  62. package/node_modules/undici/lib/dispatcher/client-h1.js +11 -2
  63. package/node_modules/undici/lib/handler/cache-handler.js +246 -64
  64. package/node_modules/undici/lib/handler/cache-revalidation-handler.js +3 -3
  65. package/node_modules/undici/lib/handler/retry-handler.js +24 -0
  66. package/node_modules/undici/lib/interceptor/cache.js +159 -52
  67. package/node_modules/undici/lib/util/cache.js +324 -62
  68. package/node_modules/undici/lib/util/date.js +23 -6
  69. package/node_modules/undici/lib/web/cookies/util.js +79 -9
  70. package/node_modules/undici/package.json +1 -1
  71. package/openclaw.plugin.json +239 -34
  72. package/package.json +9 -9
  73. package/skills/slack/SKILL.md +10 -68
  74. package/dist/action-runtime.runtime-DQErZYpz.js +0 -2
  75. package/dist/actions.runtime-BIRU_G4M.js +0 -2
  76. package/dist/channel.setup-CLP5oTvh.js +0 -56
  77. package/dist/preflight-audio.runtime-D5Bgags0.js +0 -3
  78. package/dist/slash-plugin-commands.runtime-Dosfcx3X.js +0 -2
@@ -1,13 +1,14 @@
1
- import { a as resolveSlackAccount, l as resolveSlackOperationToken } from "./accounts-CHAeNZOX.js";
2
- import { i as parseSlackTarget, t as canonicalizeSlackApiTargetId } from "./target-parsing-N6lHogYZ.js";
3
- import { C as hasSlackNativeDataBlock, D as stripSlackNativeDataBlocks, F as SLACK_EDIT_TEXT_MAX_BYTES, H as truncateSlackText, I as SLACK_MESSAGE_TEXT_HARD_LIMIT, L as SLACK_TEXT_LIMIT, M as buildSlackCompleteBlocksFallbackText, N as renderSlackBlockFallbackText, O as chunkSlackMrkdwnText, S as createSlackNativeDataBaseTextConsumer, U as truncateSlackTextByUtf8Bytes, b as appendSlackNativeDataPlainTextFallback, i as assertSlackDirectSendAllowed, it as validateSlackBlocksArray, k as markdownToSlackMrkdwnChunks, w as isSlackInvalidBlocksError, x as buildSlackNativeDataAccessibilityText } from "./group-policy-NQZti9t-.js";
1
+ import { a as resolveSlackAccount, l as resolveSlackOperationToken } from "./accounts-CK4AVI2_.js";
2
+ import { a as parseSlackTarget, t as canonicalizeSlackApiTargetId } from "./target-parsing-BnMD2ZqZ.js";
3
+ import { A as chunkSlackMrkdwnText, B as SLACK_TEXT_LIMIT, C as buildSlackNativeDataAccessibilityText, E as isSlackInvalidBlocksError, F as renderSlackBlockFallbackText, G as truncateSlackText, K as truncateSlackTextByUtf8Bytes, L as SLACK_EDIT_TEXT_MAX_BYTES, P as buildSlackCompleteBlocksFallbackText, R as SLACK_MESSAGE_TEXT_HARD_LIMIT, S as appendSlackNativeDataPlainTextFallback, T as hasSlackNativeDataBlock, j as markdownToSlackMrkdwnChunks, k as stripSlackNativeDataBlocks, p as assertSlackDetachedTargetAllowed, q as SLACK_QUESTION_FINALIZATION_BLOCKS, tt as resolveSlackQuestionActionIds, ut as validateSlackBlocksArray, w as createSlackNativeDataBaseTextConsumer, z as SLACK_MESSAGE_TEXT_RECOMMENDED_LIMIT } from "./group-policy-c4RP9bjc.js";
4
4
  import { n as resolveSlackThreadTsValue, t as normalizeSlackThreadTsCandidate } from "./thread-ts-DUGhaYKq.js";
5
- import { c as createSlackTokenCacheKey, f as getSlackWriteClient, o as createSlackReadClient } from "./probe-CgDsSops.js";
5
+ import { a as createSlackReadClient, d as getSlackWriteClient, r as formatSlackError, s as createSlackTokenCacheKey } from "./probe-HoEg_WxB.js";
6
6
  import { t as getOptionalSlackRuntime } from "./runtime-JSVZSWAj.js";
7
- import { i as loadOutboundMediaFromUrl } from "./runtime-api-QMb-Q5Ko.js";
7
+ import { i as loadOutboundMediaFromUrl } from "./runtime-api-Cj9nxBNv.js";
8
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeTrimmedStringList } 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";
11
+ import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
11
12
  import { sliceUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
12
13
  import { createHash, createHmac } from "node:crypto";
13
14
  import { withTrustedEnvProxyGuardedFetchMode } from "openclaw/plugin-sdk/fetch-runtime";
@@ -19,25 +20,34 @@ import { chunkMarkdownTextWithMode, isSilentReplyText, resolveChunkMode, resolve
19
20
  import { resolveTextChunksWithFallback } from "openclaw/plugin-sdk/reply-payload";
20
21
  import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
21
22
  import { buildTimeoutAbortSignal } from "openclaw/plugin-sdk/extension-shared";
23
+ import { extensionForMime } from "openclaw/plugin-sdk/media-mime";
22
24
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
23
25
  import { createPersistentDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
26
+ import { createPluginStateErrorReporter } from "openclaw/plugin-sdk/plugin-state-runtime";
24
27
  //#region extensions/slack/src/native-data-fallback.ts
25
28
  const SLACK_SECTION_PLAIN_TEXT_MAX = 3e3;
26
29
  const SLACK_EMPTY_BLOCK_FALLBACK = "Shared a Block Kit message";
30
+ function sliceSlackTextChunk(text, start, limit) {
31
+ return sliceUtf16Safe(text, start, Math.min(text.length, start + limit)) || Array.from(text.slice(start))[0] || "";
32
+ }
27
33
  function chunkSlackTextAtHardLimit(text, limit = SLACK_MESSAGE_TEXT_HARD_LIMIT) {
28
- const effectiveLimit = Math.max(2, Math.floor(limit));
34
+ const effectiveLimit = Math.max(1, Math.floor(limit));
29
35
  const chunks = [];
30
36
  let offset = 0;
31
37
  while (offset < text.length) {
32
- const chunk = sliceUtf16Safe(text, offset, Math.min(text.length, offset + effectiveLimit));
38
+ const chunk = sliceSlackTextChunk(text, offset, effectiveLimit);
33
39
  if (!chunk) throw new Error("Slack plain-text fallback chunking made no progress.");
34
40
  chunks.push(chunk);
35
41
  offset += chunk.length;
36
42
  }
37
43
  return chunks;
38
44
  }
39
- function buildPlainTextBlocks(text) {
40
- return chunkSlackTextAtHardLimit(text, SLACK_SECTION_PLAIN_TEXT_MAX).map((chunk, index) => {
45
+ function fitsSlackTextLimit(text, limit) {
46
+ if (text.length <= limit) return true;
47
+ return sliceSlackTextChunk(text, 0, limit).length === text.length;
48
+ }
49
+ function buildPlainTextBlocks(text, textLimit) {
50
+ return chunkSlackTextAtHardLimit(text, Math.min(textLimit, SLACK_SECTION_PLAIN_TEXT_MAX)).map((chunk, index) => {
41
51
  const fallbackBlock = {
42
52
  block: {
43
53
  type: "section",
@@ -58,11 +68,11 @@ function renderNativeDataPlainText(block) {
58
68
  function buildOrderedFallbackBlocks(params) {
59
69
  const entries = [];
60
70
  const consumeFromBase = createSlackNativeDataBaseTextConsumer(params.baseText);
61
- if (params.baseText) entries.push(...buildPlainTextBlocks(params.baseText));
71
+ if (params.baseText) entries.push(...buildPlainTextBlocks(params.baseText, params.textLimit));
62
72
  for (const block of params.blocks) {
63
73
  if (hasSlackNativeDataBlock([block])) {
64
74
  const nativeText = renderNativeDataPlainText(block);
65
- if (!consumeFromBase(nativeText)) entries.push(...buildPlainTextBlocks(nativeText));
75
+ if (!consumeFromBase(nativeText)) entries.push(...buildPlainTextBlocks(nativeText, params.textLimit));
66
76
  continue;
67
77
  }
68
78
  const text = renderSlackBlockFallbackText(block, { nativeDataFormat: "plain" });
@@ -73,7 +83,7 @@ function buildOrderedFallbackBlocks(params) {
73
83
  }
74
84
  return entries;
75
85
  }
76
- function buildOrderedBlockMessages(entries) {
86
+ function buildOrderedBlockMessages(entries, textLimit) {
77
87
  const messages = [];
78
88
  let blocks = [];
79
89
  let text = "";
@@ -90,10 +100,10 @@ function buildOrderedBlockMessages(entries) {
90
100
  for (const entry of entries) {
91
101
  const separator = text && entry.text && !entry.continuesText ? "\n\n" : "";
92
102
  const nextText = entry.text ? `${text}${separator}${entry.text}` : text;
93
- if (blocks.length >= 50 || nextText.length > 4e4) flush();
103
+ if (blocks.length >= 50 || !fitsSlackTextLimit(nextText, textLimit)) flush();
94
104
  const freshSeparator = text && entry.text && !entry.continuesText ? "\n\n" : "";
95
105
  const freshText = entry.text ? `${text}${freshSeparator}${entry.text}` : text;
96
- if (freshText.length > 4e4) throw new Error("One Slack fallback block exceeds the message text hard limit.");
106
+ if (!fitsSlackTextLimit(freshText, textLimit)) throw new Error("One Slack fallback block exceeds the resolved message text limit.");
97
107
  blocks.push(entry.block);
98
108
  text = freshText;
99
109
  }
@@ -103,17 +113,19 @@ function buildOrderedBlockMessages(entries) {
103
113
  /** Build one complete, ordered retry plan after Slack rejects native data blocks. */
104
114
  function buildSlackNativeDataDeliveryPlan(params) {
105
115
  const baseText = params.baseText?.trim() ?? "";
116
+ const textLimit = Math.min(SLACK_MESSAGE_TEXT_RECOMMENDED_LIMIT, SLACK_MESSAGE_TEXT_HARD_LIMIT, Math.max(1, Math.floor(params.textLimit ?? 4e4)));
106
117
  const hasNativeData = hasSlackNativeDataBlock(params.blocks);
107
118
  const accessibilityText = buildSlackNativeDataAccessibilityText(baseText, params.blocks) || (hasNativeData ? "Slack could not render this chart or table data." : SLACK_EMPTY_BLOCK_FALLBACK);
108
119
  return {
109
120
  accessibilityText,
110
- fallbackMessages: stripSlackNativeDataBlocks(params.blocks).length === 0 ? chunkSlackTextAtHardLimit(accessibilityText).map((text) => ({
121
+ fallbackMessages: stripSlackNativeDataBlocks(params.blocks).length === 0 ? chunkSlackTextAtHardLimit(accessibilityText, textLimit).map((text) => ({
111
122
  text,
112
123
  mrkdwn: false
113
124
  })) : buildOrderedBlockMessages(buildOrderedFallbackBlocks({
114
125
  baseText,
115
- blocks: params.blocks
116
- })),
126
+ blocks: params.blocks,
127
+ textLimit
128
+ }), textLimit),
117
129
  skipOriginalBlocks: accessibilityText.length > SLACK_MESSAGE_TEXT_HARD_LIMIT
118
130
  };
119
131
  }
@@ -355,9 +367,10 @@ async function uploadSlackFile(params) {
355
367
  maxBytes: params.maxBytes,
356
368
  mediaAccess: params.mediaAccess,
357
369
  mediaLocalRoots: params.mediaLocalRoots,
358
- mediaReadFile: params.mediaReadFile
370
+ mediaReadFile: params.mediaReadFile,
371
+ ...params.optimizeImages !== void 0 ? { optimizeImages: params.optimizeImages } : {}
359
372
  });
360
- const uploadFileName = params.uploadFileName ?? fileName ?? "upload";
373
+ const uploadFileName = params.uploadFileName ?? fileName ?? `upload${extensionForMime(contentType) ?? ""}`;
361
374
  const uploadTitle = params.uploadTitle ?? uploadFileName;
362
375
  const uploadUrlResp = await withSlackDnsRequestRetry("files.getUploadURLExternal", () => params.client.files.getUploadURLExternal({
363
376
  filename: uploadFileName,
@@ -416,24 +429,32 @@ async function uploadSlackFile(params) {
416
429
  }
417
430
  //#endregion
418
431
  //#region extensions/slack/src/sent-thread-cache.ts
432
+ /**
433
+ * Cache of Slack threads the bot has participated in.
434
+ * Used to auto-respond in threads without requiring @mention after the first reply.
435
+ */
436
+ const MAX_ENTRIES = 5e3;
437
+ const PERSISTENT_MAX_ENTRIES = 1e3;
438
+ const MAX_FAILURE_NOTICES = 1e3;
439
+ const PERSISTENT_NAMESPACE = "slack.thread-participation";
440
+ /**
441
+ * Keep Slack thread participation shared across bundled chunks so thread
442
+ * auto-reply gating does not diverge between prepare/dispatch call paths.
443
+ */
444
+ const SLACK_THREAD_PARTICIPATION_KEY = Symbol.for("openclaw.slackThreadParticipation");
445
+ const SLACK_THREAD_FAILURE_NOTICES_KEY = Symbol.for("openclaw.slackThreadFailureNotices");
419
446
  const threadParticipation = createPersistentDedupeCache({
420
- globalKey: Symbol.for("openclaw.slackThreadParticipation"),
421
- ttlMs: 1440 * 60 * 1e3,
422
- maxSize: 5e3,
447
+ globalKey: SLACK_THREAD_PARTICIPATION_KEY,
448
+ ttlMs: 0,
449
+ maxSize: MAX_ENTRIES,
423
450
  persistent: {
424
- namespace: "slack.thread-participation",
425
- maxEntries: 1e3,
451
+ namespace: PERSISTENT_NAMESPACE,
452
+ maxEntries: PERSISTENT_MAX_ENTRIES,
426
453
  openStore: (options) => getOptionalSlackRuntime()?.state.openKeyedStore(options),
427
- logError: (error) => {
428
- try {
429
- getOptionalSlackRuntime()?.logging.getChildLogger({
430
- plugin: "slack",
431
- feature: "thread-participation-state"
432
- }).warn("Slack persistent thread participation state failed", { error: String(error) });
433
- } catch {}
434
- }
454
+ logError: createPluginStateErrorReporter(getOptionalSlackRuntime, "slack", "thread-participation-state", "Slack persistent thread participation state failed")
435
455
  }
436
456
  });
457
+ const threadFailureNotices = resolveGlobalSingleton(SLACK_THREAD_FAILURE_NOTICES_KEY, () => /* @__PURE__ */ new Map(), (notices) => notices.clear());
437
458
  function makeKey(accountId, channelId, threadTs, teamId) {
438
459
  return `${accountId}:${teamId ? `${teamId}:` : ""}${channelId}:${threadTs}`;
439
460
  }
@@ -452,8 +473,41 @@ async function hasSlackThreadParticipationWithPersistence(params) {
452
473
  if (!params.accountId || !params.channelId || !params.threadTs) return false;
453
474
  return await threadParticipation.lookup(makeKey(params.accountId, params.channelId, params.threadTs, params.teamId));
454
475
  }
476
+ function makeFailureNoticeKey(params) {
477
+ const scope = params.threadTs ? `thread:${params.threadTs}` : "channel";
478
+ return makeKey(params.accountId, params.channelId, scope, params.teamId);
479
+ }
480
+ /** Returns whether this failure was already delivered in the thread or channel. */
481
+ function hasSlackThreadFailureNotice(params) {
482
+ const { accountId, channelId, failureText } = params;
483
+ const fingerprint = failureText.trim().replace(/\s+/gu, " ");
484
+ if (!accountId || !channelId || !fingerprint) return false;
485
+ return threadFailureNotices.get(makeFailureNoticeKey(params)) === fingerprint;
486
+ }
487
+ /** Records a failure after it was delivered in the thread or channel. */
488
+ function recordSlackThreadFailureNotice(params) {
489
+ const { accountId, channelId, failureText } = params;
490
+ const fingerprint = failureText.trim().replace(/\s+/gu, " ");
491
+ if (!accountId || !channelId || !fingerprint) return false;
492
+ const key = makeFailureNoticeKey(params);
493
+ if (threadFailureNotices.get(key) === fingerprint) return false;
494
+ threadFailureNotices.delete(key);
495
+ threadFailureNotices.set(key, fingerprint);
496
+ if (threadFailureNotices.size > MAX_FAILURE_NOTICES) {
497
+ const oldestKey = threadFailureNotices.keys().next().value;
498
+ if (oldestKey !== void 0) threadFailureNotices.delete(oldestKey);
499
+ }
500
+ return true;
501
+ }
502
+ /** Clears a thread or channel outage notice after a healthy model turn completes. */
503
+ function clearSlackThreadFailureNotice(params) {
504
+ const { accountId, channelId } = params;
505
+ if (!accountId || !channelId) return;
506
+ threadFailureNotices.delete(makeFailureNoticeKey(params));
507
+ }
455
508
  function clearSlackThreadParticipationCache() {
456
509
  threadParticipation.clearForTest();
510
+ threadFailureNotices.clear();
457
511
  }
458
512
  //#endregion
459
513
  //#region extensions/slack/src/send.ts
@@ -537,11 +591,12 @@ async function updateMessageSlack(params) {
537
591
  cfg: requireRuntimeConfig(params.cfg, "Slack update"),
538
592
  accountId: params.accountId
539
593
  });
594
+ assertSlackDetachedTargetAllowed(account.accountId, params.teamId);
540
595
  await getSlackWriteClient(resolveToken({
541
596
  accountId: account.accountId,
542
597
  fallbackToken: account.botToken,
543
598
  fallbackSource: account.botTokenSource
544
- })).chat.update({
599
+ }), { teamId: params.teamId }).chat.update({
545
600
  channel: params.channelId,
546
601
  ts: params.messageTs,
547
602
  text: truncateSlackTextByUtf8Bytes(params.text, SLACK_EDIT_TEXT_MAX_BYTES),
@@ -577,7 +632,8 @@ function parseRecipient(raw) {
577
632
  if (!target) throw new Error("Recipient is required for Slack sends");
578
633
  return {
579
634
  kind: target.kind,
580
- id: canonicalizeSlackApiTargetId(target.kind, target.id, raw)
635
+ id: canonicalizeSlackApiTargetId(target.kind, target.id, raw),
636
+ teamId: target.teamId
581
637
  };
582
638
  }
583
639
  function parseEnterpriseEventRecipient(raw) {
@@ -588,20 +644,62 @@ function parseEnterpriseEventRecipient(raw) {
588
644
  id: canonicalizeSlackApiTargetId("channel", match[1])
589
645
  };
590
646
  }
591
- function resolveEnterpriseEventScope(params) {
592
- const scope = params.opts.enterpriseEventScope;
593
- if (!scope) {
594
- assertSlackDirectSendAllowed(params.account);
595
- return;
596
- }
597
- if (params.account.config.enterpriseOrgInstall !== true) throw new Error("unexpected_enterprise_slack_listener_scope");
598
- if (!scope.isEnterpriseInstall || !normalizeOptionalString(scope.apiAppId) || !normalizeOptionalString(scope.enterpriseId) || !/^T[A-Z0-9]+$/i.test(scope.teamId) || !scope.client || params.opts.client !== scope.client) throw new Error("invalid_enterprise_slack_listener_scope");
647
+ function resolveSlackSendEventScope(params) {
648
+ const scope = params.opts.eventScope;
649
+ if (!scope) return;
650
+ if (!/^T[A-Z0-9]+$/i.test(scope.teamId) || !scope.client) throw new Error("invalid_enterprise_slack_listener_scope");
599
651
  return scope;
600
652
  }
653
+ function resolveSlackDelivery(params) {
654
+ if (params.eventScope) {
655
+ if (params.opts.mediaUrl && !params.eventScope.uploadCompletionClient) throw new Error("missing_enterprise_slack_upload_completion_client");
656
+ return Object.freeze({
657
+ client: params.eventScope.client,
658
+ credential: SLACK_ENTERPRISE_LISTENER_QUEUE_CREDENTIAL,
659
+ identity: normalizeSlackSendIdentity(params.opts.identity),
660
+ recipient: params.recipient,
661
+ requireMessageTimestamp: true,
662
+ teamId: params.eventScope.teamId,
663
+ unfurl: { unfurlMedia: params.account.config.unfurlMedia },
664
+ ...params.eventScope.uploadCompletionClient ? { upload: Object.freeze({
665
+ completionClient: params.eventScope.uploadCompletionClient,
666
+ auditContext: "slack-enterprise-immediate-upload"
667
+ }) } : {}
668
+ });
669
+ }
670
+ const credential = resolveToken({
671
+ explicit: params.opts.token,
672
+ accountId: params.account.accountId,
673
+ fallbackToken: resolveSlackOperationToken(params.account, "write"),
674
+ fallbackSource: params.account.identity === "user" ? params.account.userTokenSource : params.account.botTokenSource
675
+ });
676
+ return Object.freeze({
677
+ client: params.recipient.teamId ? getSlackWriteClient(credential, { teamId: params.recipient.teamId }) : params.opts.client ?? getSlackWriteClient(credential),
678
+ credential,
679
+ identity: resolveSlackSendIdentity({
680
+ accountId: params.account.accountId,
681
+ explicit: params.opts.identity
682
+ }),
683
+ recipient: params.recipient,
684
+ requireMessageTimestamp: false,
685
+ teamId: params.recipient.teamId,
686
+ unfurl: params.recipient.teamId ? { unfurlMedia: params.account.config.unfurlMedia } : {
687
+ unfurlLinks: params.account.config.unfurlLinks,
688
+ unfurlMedia: params.account.config.unfurlMedia
689
+ }
690
+ });
691
+ }
692
+ function assertSlackPostMessageResponse(response, required) {
693
+ if (!required || response.ok && response.ts) return;
694
+ throw new Error(response.ok ? "Slack chat.postMessage returned no message timestamp" : `Slack chat.postMessage failed: ${formatSlackError(response.error, "unknown error")}`);
695
+ }
696
+ function resolveSlackTextChunkLimit(params) {
697
+ const configuredLimit = params.textLimit ?? resolveTextChunkLimit(params.cfg, "slack", params.accountId, { fallbackLimit: 8e3 });
698
+ return Math.min(configuredLimit, SLACK_TEXT_LIMIT);
699
+ }
601
700
  function resolveSlackTextChunks(params) {
602
701
  const text = params.preservePlainText ? params.text : params.text.trim();
603
- const configuredLimit = params.textLimit ?? resolveTextChunkLimit(params.cfg, "slack", params.accountId, { fallbackLimit: 8e3 });
604
- const chunkLimit = Math.min(configuredLimit, SLACK_TEXT_LIMIT);
702
+ const chunkLimit = resolveSlackTextChunkLimit(params);
605
703
  if (params.preservePlainText) {
606
704
  const chunks = [];
607
705
  let remaining = text;
@@ -867,7 +965,7 @@ async function scanSlackConversationForDelivery(params) {
867
965
  evidence: deliveryParts.size > 0 ? "partial" : "none"
868
966
  };
869
967
  }
870
- async function reconcileSlackUnknownSend(ctx, opts) {
968
+ async function reconcileSlackUnknownSend(ctx) {
871
969
  const account = resolveSlackAccount({
872
970
  cfg: requireRuntimeConfig(ctx.cfg, "Slack delivery reconciliation"),
873
971
  accountId: ctx.accountId ?? void 0
@@ -878,13 +976,22 @@ async function reconcileSlackUnknownSend(ctx, opts) {
878
976
  error: "Slack unknown-send reconciliation requires a durable delivery id",
879
977
  retryable: false
880
978
  };
979
+ const recipient = parseRecipient(ctx.to);
980
+ try {
981
+ assertSlackDetachedTargetAllowed(account.accountId, recipient.teamId);
982
+ } catch (error) {
983
+ return {
984
+ status: "unresolved",
985
+ error: error instanceof Error ? error.message : String(error),
986
+ retryable: false
987
+ };
988
+ }
881
989
  const readToken = resolveSlackOperationToken(account, "read");
882
990
  if (!readToken) return {
883
991
  status: "unresolved",
884
992
  error: `Slack read token missing for account "${account.accountId}"`,
885
993
  retryable: false
886
994
  };
887
- const recipient = parseRecipient(ctx.to);
888
995
  const userRecipient = isSlackUserRecipient(recipient);
889
996
  const writeToken = resolveSlackOperationToken(account, "write");
890
997
  if (userRecipient && !writeToken) return {
@@ -892,8 +999,8 @@ async function reconcileSlackUnknownSend(ctx, opts) {
892
999
  error: `Slack write token missing for direct-message reconciliation on account "${account.accountId}"`,
893
1000
  retryable: false
894
1001
  };
895
- const readClient = opts?.client ?? createSlackReadClient(readToken);
896
- const writeClient = opts?.client ?? (writeToken ? getSlackWriteClient(writeToken) : void 0);
1002
+ const readClient = createSlackReadClient(readToken, { teamId: recipient.teamId });
1003
+ const writeClient = writeToken ? getSlackWriteClient(writeToken, { teamId: recipient.teamId }) : void 0;
897
1004
  const payloadReplyToId = ctx.payloads[0]?.replyToId;
898
1005
  const threadTs = resolveSlackThreadTsValue({
899
1006
  replyToId: Object.hasOwn(ctx, "effectiveReplyToId") ? normalizeOptionalString(ctx.effectiveReplyToId) : payloadReplyToId != null ? normalizeOptionalString(payloadReplyToId) : ctx.replyToMode === "off" ? void 0 : normalizeOptionalString(ctx.replyToId),
@@ -910,7 +1017,7 @@ async function reconcileSlackUnknownSend(ctx, opts) {
910
1017
  accountId: account.accountId,
911
1018
  token: channelToken
912
1019
  });
913
- const lookupClients = opts?.client ? [opts.client] : [readClient, ...writeClient && writeToken !== readToken ? [writeClient] : []];
1020
+ const lookupClients = [readClient, ...writeClient && writeClient !== readClient && writeToken !== readToken ? [writeClient] : []];
914
1021
  let lookupError;
915
1022
  let bestUnresolvedScan;
916
1023
  for (const lookupClient of lookupClients) try {
@@ -947,15 +1054,9 @@ async function sendMessageSlack(to, message, opts) {
947
1054
  cfg,
948
1055
  accountId: opts.accountId
949
1056
  });
950
- const enterpriseEventScope = resolveEnterpriseEventScope({
951
- account,
952
- opts
953
- });
954
- const enterpriseDelivery = enterpriseEventScope ? Object.freeze({
955
- client: enterpriseEventScope.client,
956
- teamId: enterpriseEventScope.teamId,
957
- ...enterpriseEventScope.uploadCompletionClient ? { uploadCompletionClient: enterpriseEventScope.uploadCompletionClient } : {}
958
- }) : void 0;
1057
+ const eventScope = resolveSlackSendEventScope({ opts });
1058
+ const recipient = eventScope ? parseEnterpriseEventRecipient(to) : parseRecipient(to);
1059
+ if (!eventScope) assertSlackDetachedTargetAllowed(account.accountId, recipient.teamId);
959
1060
  if (isSilentReplyText(normalizedMessage) && !opts.mediaUrl && !opts.blocks) {
960
1061
  logVerbose("slack send: suppressed NO_REPLY token before API call");
961
1062
  return {
@@ -969,37 +1070,29 @@ async function sendMessageSlack(to, message, opts) {
969
1070
  }
970
1071
  const blocks = opts.blocks == null ? void 0 : validateSlackBlocksArray(opts.blocks);
971
1072
  if (!normalizedMessage && !opts.mediaUrl && !blocks) throw new Error("Slack send requires text, blocks, or media");
972
- const token = enterpriseDelivery ? SLACK_ENTERPRISE_LISTENER_QUEUE_CREDENTIAL : resolveToken({
973
- explicit: opts.token,
974
- accountId: account.accountId,
975
- fallbackToken: resolveSlackOperationToken(account, "write"),
976
- fallbackSource: account.identity === "user" ? account.userTokenSource : account.botTokenSource
1073
+ const queuedOpts = Object.freeze({ ...opts });
1074
+ const delivery = resolveSlackDelivery({
1075
+ account,
1076
+ eventScope,
1077
+ opts: queuedOpts,
1078
+ recipient
977
1079
  });
978
- const recipient = enterpriseDelivery ? parseEnterpriseEventRecipient(to) : parseRecipient(to);
979
- const queueKey = createSlackSendQueueKey({
1080
+ const result = await runQueuedSlackSend(createSlackSendQueueKey({
980
1081
  accountId: account.accountId,
981
- token,
982
- recipient,
1082
+ token: delivery.credential,
1083
+ recipient: delivery.recipient,
983
1084
  threadTs: opts.threadTs,
984
- ...enterpriseDelivery ? { teamId: enterpriseDelivery.teamId } : {}
985
- });
986
- const queuedOpts = enterpriseDelivery ? Object.freeze({
987
- ...opts,
988
- client: enterpriseDelivery.client
989
- }) : opts;
990
- const result = await runQueuedSlackSend(queueKey, () => sendMessageSlackQueued({
1085
+ teamId: delivery.teamId
1086
+ }), () => sendMessageSlackQueued({
991
1087
  trimmedMessage,
992
1088
  opts: queuedOpts,
993
1089
  cfg,
994
1090
  account,
995
- token,
996
- recipient,
997
1091
  blocks,
998
- ...enterpriseDelivery ? { enterpriseDelivery } : {}
1092
+ delivery
999
1093
  }));
1000
1094
  const threadTs = result.threadTs ?? normalizeSlackThreadTsCandidate(queuedOpts.threadTs);
1001
- if (threadTs && result.channelId && account.accountId) if (enterpriseDelivery) recordSlackThreadParticipation(account.accountId, result.channelId, threadTs, { teamId: enterpriseDelivery.teamId });
1002
- else recordSlackThreadParticipation(account.accountId, result.channelId, threadTs);
1095
+ if (threadTs && result.channelId && account.accountId) recordSlackThreadParticipation(account.accountId, result.channelId, threadTs, { teamId: delivery.teamId });
1003
1096
  return result;
1004
1097
  }
1005
1098
  async function sendMessageSlackQueued(params) {
@@ -1010,17 +1103,9 @@ async function sendMessageSlackQueued(params) {
1010
1103
  }
1011
1104
  }
1012
1105
  async function sendMessageSlackQueuedInner(params) {
1013
- const { opts, cfg, account, token, recipient, blocks, trimmedMessage, enterpriseDelivery } = params;
1014
- const client = enterpriseDelivery?.client ?? opts.client ?? getSlackWriteClient(token);
1015
- const identity = enterpriseDelivery ? normalizeSlackSendIdentity(opts.identity) : resolveSlackSendIdentity({
1016
- accountId: account.accountId,
1017
- explicit: opts.identity
1018
- });
1106
+ const { opts, cfg, account, blocks, trimmedMessage, delivery } = params;
1107
+ const { client, identity, recipient, unfurl } = delivery;
1019
1108
  if (opts.replyBroadcast && opts.mediaUrl) throw new Error("Slack replyBroadcast is only supported for text or block thread replies.");
1020
- const unfurl = enterpriseDelivery ? { unfurlMedia: account.config.unfurlMedia } : {
1021
- unfurlLinks: account.config.unfurlLinks,
1022
- unfurlMedia: account.config.unfurlMedia
1023
- };
1024
1109
  const directUserPostChannelId = opts.deliveryQueueId ? void 0 : resolveDirectUserPostChannelId({
1025
1110
  recipient,
1026
1111
  hasMedia: Boolean(opts.mediaUrl),
@@ -1028,11 +1113,20 @@ async function sendMessageSlackQueuedInner(params) {
1028
1113
  });
1029
1114
  const { channelId } = directUserPostChannelId ? { channelId: directUserPostChannelId } : await resolveChannelId(client, recipient, {
1030
1115
  accountId: account.accountId,
1031
- token
1116
+ token: delivery.credential
1032
1117
  });
1033
- const reportDelivery = async (result) => {
1034
- await opts.onDeliveryResult?.(result);
1035
- return result;
1118
+ const reportDelivery = async (result, deliveredBlocks) => {
1119
+ const slackQuestionActionIds = resolveSlackQuestionActionIds(deliveredBlocks);
1120
+ const deliveryResult = slackQuestionActionIds.length ? {
1121
+ ...result,
1122
+ meta: {
1123
+ ...result.meta,
1124
+ slackQuestionActionIds,
1125
+ [SLACK_QUESTION_FINALIZATION_BLOCKS]: deliveredBlocks.filter((block) => block.type !== "actions")
1126
+ }
1127
+ } : result;
1128
+ await opts.onDeliveryResult?.(deliveryResult);
1129
+ return deliveryResult;
1036
1130
  };
1037
1131
  let didDispatch = false;
1038
1132
  const dispatchOnce = async () => {
@@ -1044,10 +1138,16 @@ async function sendMessageSlackQueuedInner(params) {
1044
1138
  const authoredTextPlacement = opts.authoredTextPlacement ?? "outside-blocks";
1045
1139
  const nativeDataFallbackBase = blocks && authoredTextPlacement === "outside-blocks" ? explicitNativeDataFallbackBase ?? trimmedMessage : "";
1046
1140
  const hasNativeData = Boolean(blocks && hasSlackNativeDataBlock(blocks));
1141
+ const textChunkLimit = resolveSlackTextChunkLimit({
1142
+ cfg,
1143
+ accountId: account.accountId,
1144
+ ...opts.textLimit !== void 0 ? { textLimit: opts.textLimit } : {}
1145
+ });
1047
1146
  const usesOrderedBlockAccessibility = Boolean(blocks && (hasNativeData || opts.authoredTextPlacement !== void 0));
1048
1147
  const orderedBlockDeliveryPlan = blocks && usesOrderedBlockAccessibility ? buildSlackNativeDataDeliveryPlan({
1049
1148
  baseText: nativeDataFallbackBase,
1050
- blocks
1149
+ blocks,
1150
+ textLimit: textChunkLimit
1051
1151
  }) : void 0;
1052
1152
  const orderedBlockAccessibilityText = blocks && usesOrderedBlockAccessibility ? orderedBlockDeliveryPlan?.accessibilityText ?? (buildSlackNativeDataAccessibilityText(nativeDataFallbackBase, blocks) || "Slack could not render this Block Kit message.") : void 0;
1053
1153
  const completeBlockFallbackText = blocks ? buildSlackCompleteBlocksFallbackText(blocks) : "";
@@ -1085,7 +1185,7 @@ async function sendMessageSlackQueuedInner(params) {
1085
1185
  ...usesOrderedBlockAccessibility ? { mrkdwn: false } : {},
1086
1186
  unfurl
1087
1187
  });
1088
- if (enterpriseDelivery && (!response.ok || !response.ts)) throw new Error(response.ok ? "Slack chat.postMessage returned no message timestamp" : `Slack chat.postMessage failed: ${response.error ?? "unknown error"}`);
1188
+ assertSlackPostMessageResponse(response, delivery.requireMessageTimestamp);
1089
1189
  const messageId = response.ts ?? "unknown";
1090
1190
  deliveredChannelId = resolvePostedMessageChannelId(response, channelId);
1091
1191
  const deliveredThreadTs = resolvePostedMessageThreadTs(response) ?? normalizeSlackThreadTsCandidate(opts.threadTs);
@@ -1099,7 +1199,7 @@ async function sendMessageSlackQueuedInner(params) {
1099
1199
  kind: "card",
1100
1200
  threadTs: deliveredThreadTs
1101
1201
  })
1102
- });
1202
+ }, blocks);
1103
1203
  } catch (error) {
1104
1204
  if (!hasNativeData || !isSlackInvalidBlocksError(error)) throw error;
1105
1205
  logVerbose("slack send: native data rejected, delivering complete text fallback");
@@ -1108,6 +1208,7 @@ async function sendMessageSlackQueuedInner(params) {
1108
1208
  }
1109
1209
  if (pendingBlockFallback) {
1110
1210
  const fallbackMessages = pendingBlockFallback.fallbackMessages;
1211
+ let questionDelivery;
1111
1212
  for (const [partIndex, fallback] of fallbackMessages.entries()) {
1112
1213
  const metadata = withSlackDeliveryMetadata(partIndex === 0 ? opts.metadata : void 0, {
1113
1214
  queueId: opts.deliveryQueueId,
@@ -1130,7 +1231,7 @@ async function sendMessageSlackQueuedInner(params) {
1130
1231
  unfurl
1131
1232
  });
1132
1233
  const response = posted.response;
1133
- if (enterpriseDelivery && (!response.ok || !response.ts)) throw new Error(response.ok ? "Slack chat.postMessage returned no message timestamp" : `Slack chat.postMessage failed: ${response.error ?? "unknown error"}`);
1234
+ assertSlackPostMessageResponse(response, delivery.requireMessageTimestamp);
1134
1235
  sendIdentity = posted.identity;
1135
1236
  lastMessageId = response.ts ?? lastMessageId;
1136
1237
  deliveredChannelId = resolvePostedMessageChannelId(response, deliveredChannelId);
@@ -1138,7 +1239,7 @@ async function sendMessageSlackQueuedInner(params) {
1138
1239
  if (!response.ts) continue;
1139
1240
  sentMessageIds.push(response.ts);
1140
1241
  const deliveredThreadTs = resolvePostedMessageThreadTs(response) ?? normalizeSlackThreadTsCandidate(opts.threadTs);
1141
- await reportDelivery({
1242
+ const fallbackDelivery = await reportDelivery({
1142
1243
  messageId: response.ts,
1143
1244
  channelId: deliveredChannelId,
1144
1245
  threadTs: deliveredThreadTs,
@@ -1148,7 +1249,8 @@ async function sendMessageSlackQueuedInner(params) {
1148
1249
  kind: fallback.blocks ? "card" : "text",
1149
1250
  threadTs: deliveredThreadTs
1150
1251
  })
1151
- });
1252
+ }, fallback.blocks);
1253
+ if (fallbackDelivery.meta?.slackQuestionActionIds.length) questionDelivery = fallbackDelivery;
1152
1254
  }
1153
1255
  const messageId = lastMessageId || "unknown";
1154
1256
  const deliveredThreadTs = canonicalDeliveredThreadTs ?? normalizeSlackThreadTsCandidate(opts.threadTs);
@@ -1156,6 +1258,10 @@ async function sendMessageSlackQueuedInner(params) {
1156
1258
  messageId,
1157
1259
  channelId: deliveredChannelId,
1158
1260
  threadTs: deliveredThreadTs,
1261
+ ...questionDelivery?.meta ? { meta: {
1262
+ ...questionDelivery.meta,
1263
+ slackQuestionMessageId: questionDelivery.messageId
1264
+ } } : {},
1159
1265
  receipt: createSlackSendReceipt({
1160
1266
  platformMessageIds: sentMessageIds.length ? sentMessageIds : [messageId],
1161
1267
  channelId: deliveredChannelId,
@@ -1169,18 +1275,17 @@ async function sendMessageSlackQueuedInner(params) {
1169
1275
  cfg,
1170
1276
  accountId: account.accountId,
1171
1277
  text: trimmedMessage,
1172
- ...opts.textLimit !== void 0 ? { textLimit: opts.textLimit } : {},
1278
+ textLimit: textChunkLimit,
1173
1279
  ...opts.textIsSlackMrkdwn ? { textIsSlackMrkdwn: true } : {},
1174
1280
  ...opts.textIsSlackPlainText ? { preservePlainText: true } : {}
1175
1281
  });
1176
1282
  const mediaMaxBytes = opts.mediaMaxBytes ?? (typeof account.config.mediaMaxMb === "number" ? account.config.mediaMaxMb * 1024 * 1024 : void 0);
1177
1283
  let chunksToPost;
1178
1284
  if (opts.mediaUrl) {
1179
- if (enterpriseDelivery && !enterpriseDelivery.uploadCompletionClient) throw new Error("missing_enterprise_slack_upload_completion_client");
1180
1285
  const [firstChunk, ...rest] = resolvedChunks;
1181
1286
  lastMessageId = await uploadSlackFile({
1182
1287
  client,
1183
- ...enterpriseDelivery?.uploadCompletionClient ? { completionClient: enterpriseDelivery.uploadCompletionClient } : {},
1288
+ ...delivery.upload ? { completionClient: delivery.upload.completionClient } : {},
1184
1289
  channelId,
1185
1290
  mediaUrl: opts.mediaUrl,
1186
1291
  mediaAccess: opts.mediaAccess,
@@ -1191,8 +1296,9 @@ async function sendMessageSlackQueuedInner(params) {
1191
1296
  caption: firstChunk,
1192
1297
  threadTs: opts.threadTs,
1193
1298
  maxBytes: mediaMaxBytes,
1299
+ ...opts.forceDocument ? { optimizeImages: false } : {},
1194
1300
  onPlatformSendDispatch: dispatchOnce,
1195
- ...enterpriseDelivery ? { auditContext: "slack-enterprise-immediate-upload" } : {}
1301
+ ...delivery.upload ? { auditContext: delivery.upload.auditContext } : {}
1196
1302
  });
1197
1303
  sentMessageIds.push(lastMessageId);
1198
1304
  await reportDelivery({
@@ -1231,7 +1337,7 @@ async function sendMessageSlackQueuedInner(params) {
1231
1337
  unfurl
1232
1338
  });
1233
1339
  const response = posted.response;
1234
- if (enterpriseDelivery && (!response.ok || !response.ts)) throw new Error(response.ok ? "Slack chat.postMessage returned no message timestamp" : `Slack chat.postMessage failed: ${response.error ?? "unknown error"}`);
1340
+ assertSlackPostMessageResponse(response, delivery.requireMessageTimestamp);
1235
1341
  sendIdentity = posted.identity;
1236
1342
  lastMessageId = response.ts ?? lastMessageId;
1237
1343
  deliveredChannelId = resolvePostedMessageChannelId(response, deliveredChannelId);
@@ -1266,4 +1372,4 @@ async function sendMessageSlackQueuedInner(params) {
1266
1372
  };
1267
1373
  }
1268
1374
  //#endregion
1269
- export { updateMessageSlack as a, hasSlackThreadParticipationWithPersistence as c, chunkSlackTextAtHardLimit as d, setSlackDefaultSendIdentity as i, recordSlackThreadParticipation as l, resolveSlackDmChannelId as n, clearSlackThreadParticipationCache as o, sendMessageSlack as r, hasSlackThreadParticipation as s, reconcileSlackUnknownSend as t, buildSlackNativeDataDeliveryPlan as u };
1375
+ export { updateMessageSlack as a, hasSlackThreadFailureNotice as c, recordSlackThreadFailureNotice as d, recordSlackThreadParticipation as f, setSlackDefaultSendIdentity as i, hasSlackThreadParticipation as l, chunkSlackTextAtHardLimit as m, resolveSlackDmChannelId as n, clearSlackThreadFailureNotice as o, buildSlackNativeDataDeliveryPlan as p, sendMessageSlack as r, clearSlackThreadParticipationCache as s, reconcileSlackUnknownSend as t, hasSlackThreadParticipationWithPersistence as u };
@@ -1,2 +1,2 @@
1
- import { a as updateMessageSlack, n as resolveSlackDmChannelId, r as sendMessageSlack, t as reconcileSlackUnknownSend } from "./send-DsLeZpST.js";
1
+ import { a as updateMessageSlack, n as resolveSlackDmChannelId, r as sendMessageSlack, t as reconcileSlackUnknownSend } from "./send-Nor0iBwY.js";
2
2
  export { reconcileSlackUnknownSend, resolveSlackDmChannelId, sendMessageSlack, updateMessageSlack };
@@ -1,5 +1,3 @@
1
- import { t as registerSlackPluginHttpRoutes } from "./plugin-routes-CLp4obpN.js";
2
- import "./http-routes-api.js";
3
1
  import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
4
2
  //#region extensions/slack/setup-entry.ts
5
3
  var setup_entry_default = defineBundledChannelSetupEntry({
@@ -15,8 +13,7 @@ var setup_entry_default = defineBundledChannelSetupEntry({
15
13
  runtime: {
16
14
  specifier: "./runtime-setter-api.js",
17
15
  exportName: "setSlackRuntime"
18
- },
19
- registerSetupRuntime: registerSlackPluginHttpRoutes
16
+ }
20
17
  });
21
18
  //#endregion
22
19
  export { setup_entry_default as default };
@@ -1,2 +1,2 @@
1
- import { t as slackSetupPlugin } from "./channel.setup-CLP5oTvh.js";
1
+ import { t as slackSetupPlugin } from "./channel.setup-Bch9dYmA.js";
2
2
  export { slackSetupPlugin };
@@ -1,9 +1,9 @@
1
- import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom } from "./accounts-CHAeNZOX.js";
2
- import { t as inspectSlackAccount } from "./account-inspect-DEKpg9Ip.js";
3
- import "./shared-DgIN3Dcr.js";
4
- import { n as createSlackSetupWizardBase, o as SLACK_CHANNEL } from "./config-adapter-CxBQH8fq.js";
5
- import { t as resolveSlackChannelAllowlist } from "./resolve-channels-yEqmM-3I.js";
6
- import { t as resolveSlackUserAllowlist } from "./resolve-users-BOrt5K-5.js";
1
+ import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom } from "./accounts-CK4AVI2_.js";
2
+ import { t as inspectSlackAccount } from "./account-inspect-Drw2gAiN.js";
3
+ import "./shared-zdT5AMp-.js";
4
+ import { o as SLACK_CHANNEL, r as createSlackSetupWizardBase } from "./channel.setup-Bch9dYmA.js";
5
+ import { t as resolveSlackChannelAllowlist } from "./resolve-channels-CNPrxaXY.js";
6
+ import { t as resolveSlackUserAllowlist } from "./resolve-users-Dzomuwnr.js";
7
7
  import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { resolveBasicAllowFromEntries } from "openclaw/plugin-sdk/allow-from";
9
9
  import { createSetupTranslator, noteChannelLookupFailure, noteChannelLookupSummary, parseMentionOrPrefixedId, patchChannelConfigForAccount, promptResolvedAllowFrom, resolveEntriesWithOptionalToken, resolveSetupAccountId, splitSetupEntries } from "openclaw/plugin-sdk/setup-runtime";