@openclaw/slack 2026.5.12 → 2026.5.14-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 (87) hide show
  1. package/dist/{account-inspect-D7AZNs8C.js → account-inspect-BJyQLSkN.js} +1 -1
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{accounts-ClAPP5ry.js → accounts-yk5K3wQU.js} +2 -1
  4. package/dist/accounts.runtime-BhbEu1ZK.js +2 -0
  5. package/dist/{action-runtime-e2UhRsNx.js → action-runtime-CyE2jfW-.js} +4 -4
  6. package/dist/action-runtime.runtime-DLhfKw4B.js +2 -0
  7. package/dist/{media-D1XCd1uP.js → actions-BibhOXpJ.js} +339 -23
  8. package/dist/{actions.runtime-CO3OaTLb.js → actions.runtime-B9XQG6X4.js} +1 -1
  9. package/dist/api.js +18 -18
  10. package/dist/{approval-handler.runtime-CmeRr9qA.js → approval-handler.runtime-BjzVRaXN.js} +3 -4
  11. package/dist/{blocks-render-BIDw-Pom.js → blocks-render-BAVfd6r0.js} +1 -1
  12. package/dist/{channel-DRjHBTDB.js → channel-Dh07mU_K.js} +24 -52
  13. package/dist/channel-config-api.js +1 -1
  14. package/dist/channel-plugin-api.js +1 -1
  15. package/dist/{channel.setup-Cayn7afd.js → channel.setup-CmG37S2W.js} +4 -4
  16. package/dist/{client-CPe4GmDR.js → client-C_IaJbi5.js} +20 -1
  17. package/dist/{config-schema-D9B5LB_L.js → config-schema-CNRousxw.js} +21 -1
  18. package/dist/contract-api.js +4 -4
  19. package/dist/{directory-config-B3JiHeB7.js → directory-config-CMvFiswf.js} +1 -1
  20. package/dist/directory-contract-api.js +1 -1
  21. package/dist/{directory-live-Bf16GwDh.js → directory-live-CZPzpQZF.js} +2 -2
  22. package/dist/{doctor-contract-KUjHnkQm.js → doctor-contract-B8QIWMs1.js} +1 -1
  23. package/dist/doctor-contract-api.js +1 -1
  24. package/dist/http-routes-api.js +1 -1
  25. package/dist/inbound-contract-test-api.js +2 -2
  26. package/dist/{interactive-replies-qAIfuBor.js → interactive-replies-BSg5hXhj.js} +1 -1
  27. package/dist/interactive-replies-api.js +1 -1
  28. package/dist/{message-tool-api-6lowf9zE.js → message-tool-api-C7gc7goF.js} +2 -2
  29. package/dist/message-tool-api.js +1 -1
  30. package/dist/{monitor-a97o17G6.js → monitor-DDE5AI2O.js} +3 -3
  31. package/dist/{outbound-adapter-B_5sEhCg.js → outbound-adapter-BluPNDNi.js} +4 -5
  32. package/dist/outbound-payload-test-api.js +1 -1
  33. package/dist/{outbound-payload.test-harness-CVCamg1x.js → outbound-payload.test-harness-BNxnP6MC.js} +2 -2
  34. package/dist/{pipeline.runtime-DT0hLnq2.js → pipeline.runtime-Dft2-QU4.js} +48 -22
  35. package/dist/{plugin-routes-DtTPmga1.js → plugin-routes-CRnfsTTX.js} +2 -2
  36. package/dist/{prepare-D3YqV8jB.js → prepare-D0tMg4dt.js} +9 -10
  37. package/dist/{prepare.test-helpers-DVcjRhfG.js → prepare.test-helpers-CU1qB54Q.js} +1 -1
  38. package/dist/{probe-3eZf1FjI.js → probe-FL4sUJsH.js} +2 -2
  39. package/dist/{provider-D7uAN3Fq.js → provider-C6WxaFFf.js} +69 -30
  40. package/dist/{replies-Xe_jMR6o.js → replies-D0QXXSPP.js} +4 -4
  41. package/dist/reply-blocks-BFaJ_ejG.js +134 -0
  42. package/dist/{resolve-channels-BRYqyNVJ.js → resolve-channels-B_eKaOkE.js} +2 -2
  43. package/dist/{resolve-users-Bd_SdP8j.js → resolve-users-BzBAJwvq.js} +2 -2
  44. package/dist/{room-context-0vovmZPU.js → room-context-Cd8jFpS-.js} +4 -2
  45. package/dist/{runtime-api-Dd1xIV5v.js → runtime-api-B5HGOzX3.js} +2 -2
  46. package/dist/runtime-api.js +13 -13
  47. package/dist/runtime-setter-api.js +1 -1
  48. package/dist/{scopes-CDevO8jg.js → scopes-Bvg_ZzqZ.js} +2 -2
  49. package/dist/secret-contract-api.js +1 -1
  50. package/dist/security-contract-api.js +1 -1
  51. package/dist/{send-D_A9kL-C.js → send-Dg9zcyYT.js} +5 -6
  52. package/dist/send.runtime-CjjQ9StM.js +2 -0
  53. package/dist/send.runtime-E47jGN-2.js +2 -0
  54. package/dist/{setup-core-B9NetDkM.js → setup-core-WWQl-cE9.js} +2 -2
  55. package/dist/setup-plugin-api.js +1 -1
  56. package/dist/{setup-surface-D88QBVOW.js → setup-surface-BLoTgna4.js} +5 -5
  57. package/dist/{shared-D8U42xFL.js → shared-GoB-OuUq.js} +9 -9
  58. package/dist/{slash-dispatch.runtime-BJgT0jwV.js → slash-dispatch.runtime-Bz_OkRcR.js} +1 -1
  59. package/dist/test-api.js +7 -7
  60. package/dist/thread-ts-As_dcNbD.js +52 -0
  61. package/openclaw.plugin.json +116 -0
  62. package/package.json +9 -7
  63. package/dist/accounts.runtime-DDVcLJUI.js +0 -2
  64. package/dist/action-runtime.runtime-BFcqMbOm.js +0 -2
  65. package/dist/actions-CYLFK-Zy.js +0 -292
  66. package/dist/blocks-input-CwTFVImV.js +0 -29
  67. package/dist/channel-api-B_nZwosg.js +0 -20
  68. package/dist/exec-approvals-7xUNgLi9.js +0 -58
  69. package/dist/group-policy-CyLUK6My.js +0 -41
  70. package/dist/mrkdwn-Cax-eSfK.js +0 -6
  71. package/dist/reply-blocks-Z5l6_R6H.js +0 -14
  72. package/dist/send.runtime-BRE_ncCU.js +0 -2
  73. package/dist/send.runtime-_l76lUuL.js +0 -2
  74. package/dist/thread-ts-C2x7c5PP.js +0 -24
  75. /package/dist/{allow-list-BPnnlRPL.js → allow-list-nwXs_eCP.js} +0 -0
  76. /package/dist/{config-api-B_jq4NJW.js → config-api-CmgE_ORg.js} +0 -0
  77. /package/dist/{errors-BYFHR24f.js → errors-C_sW0Zgl.js} +0 -0
  78. /package/dist/{magic-string.es-BMaGRRZ1.js → magic-string.es-9lw4MGoF.js} +0 -0
  79. /package/dist/{registry-CeaoNfoP.js → registry-D2cWOLZV.js} +0 -0
  80. /package/dist/{resolve-allowlist-common-Bk3clYPK.js → resolve-allowlist-common-DLub2I2i.js} +0 -0
  81. /package/dist/{runtime-Bo-KHM-F.js → runtime-DQxkf7k2.js} +0 -0
  82. /package/dist/{secret-contract-Bo6lbSkh.js → secret-contract-0TL3L5Kb.js} +0 -0
  83. /package/dist/{security-audit-BtHGnD3d.js → security-audit-BJzADAw3.js} +0 -0
  84. /package/dist/{slash-commands.runtime-22kgyst2.js → slash-commands.runtime-bcDwsGnu.js} +0 -0
  85. /package/dist/{slash-plugin-commands.runtime-CF-n3MeP.js → slash-plugin-commands.runtime-DBHGUSj2.js} +0 -0
  86. /package/dist/{slash-skill-commands.runtime-BMs0VjTe.js → slash-skill-commands.runtime-rrY2hXvN.js} +0 -0
  87. /package/dist/{streaming-compat-RkZgTmQ2.js → streaming-compat-eu5Rj5gj.js} +0 -0
@@ -1,19 +1,16 @@
1
- import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, l as resolveSlackReplyToMode, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom } from "./accounts-ClAPP5ry.js";
1
+ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, l as resolveSlackReplyToMode, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom } from "./accounts-yk5K3wQU.js";
2
2
  import { i as resolveSlackChannelId, n as normalizeSlackMessagingTarget, r as parseSlackTarget, t as looksLikeSlackTargetId } from "./target-parsing-CQmv-iSm.js";
3
3
  import "./targets-B1tYCAr6.js";
4
- import { a as normalizeSlackApproverId, c as shouldSuppressLocalSlackExecApprovalPrompt, i as isSlackExecApprovalClientEnabled, o as resolveSlackExecApprovalTarget, r as isSlackExecApprovalAuthorizedSender, s as shouldHandleSlackExecApprovalRequest, t as getSlackExecApprovalApprovers } from "./exec-approvals-7xUNgLi9.js";
5
- import { n as buildSlackPresentationBlocks, r as resolveSlackInteractiveBlockOffsets, t as buildSlackInteractiveBlocks } from "./blocks-render-BIDw-Pom.js";
6
- import { n as resolveSlackThreadTsValue, r as SLACK_TEXT_LIMIT, t as normalizeSlackThreadTsCandidate } from "./thread-ts-C2x7c5PP.js";
7
- import { n as extractSlackToolSend, t as describeSlackMessageTool } from "./message-tool-api-6lowf9zE.js";
8
- import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-qAIfuBor.js";
9
- import { a as resolveConfiguredFromRequiredCredentialStatuses, i as projectCredentialSnapshotFields, n as PAIRING_APPROVED_MESSAGE, t as DEFAULT_ACCOUNT_ID } from "./channel-api-B_nZwosg.js";
10
- import { r as createSlackWebClient } from "./client-CPe4GmDR.js";
11
- import { r as normalizeAllowListLower } from "./allow-list-BPnnlRPL.js";
12
- import { n as resolveSlackGroupToolPolicy, t as resolveSlackGroupRequireMention } from "./group-policy-CyLUK6My.js";
13
- import { t as resolveSlackReplyBlocks } from "./reply-blocks-Z5l6_R6H.js";
14
- import { t as getOptionalSlackRuntime } from "./runtime-Bo-KHM-F.js";
15
- import { i as slackSecurityAdapter, n as isSlackPluginAccountConfigured, r as slackConfigAdapter, t as createSlackPluginBase } from "./shared-D8U42xFL.js";
16
- import { i as SLACK_CHANNEL, n as createSlackSetupWizardProxy, r as slackSetupAdapter } from "./setup-core-B9NetDkM.js";
4
+ import { a as getSlackExecApprovalApprovers, d as shouldSuppressLocalSlackExecApprovalPrompt, i as isSlackApprovalAuthorizedSender, l as resolveSlackExecApprovalTarget, n as resolveSlackGroupRequireMention, o as isSlackExecApprovalAuthorizedSender, r as resolveSlackGroupToolPolicy, s as isSlackExecApprovalClientEnabled, t as resolveSlackReplyBlocks, u as shouldHandleSlackExecApprovalRequest } from "./reply-blocks-BFaJ_ejG.js";
5
+ import { n as buildSlackPresentationBlocks, r as resolveSlackInteractiveBlockOffsets, t as buildSlackInteractiveBlocks } from "./blocks-render-BAVfd6r0.js";
6
+ import { n as resolveSlackThreadTsValue, o as SLACK_TEXT_LIMIT, t as normalizeSlackThreadTsCandidate } from "./thread-ts-As_dcNbD.js";
7
+ import { n as extractSlackToolSend, t as describeSlackMessageTool } from "./message-tool-api-C7gc7goF.js";
8
+ import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-BSg5hXhj.js";
9
+ import { d as PAIRING_APPROVED_MESSAGE, m as resolveConfiguredFromRequiredCredentialStatuses, p as projectCredentialSnapshotFields, r as createSlackWebClient, u as DEFAULT_ACCOUNT_ID } from "./client-C_IaJbi5.js";
10
+ import { r as normalizeAllowListLower } from "./allow-list-nwXs_eCP.js";
11
+ import { t as getOptionalSlackRuntime } from "./runtime-DQxkf7k2.js";
12
+ import { i as slackSecurityAdapter, n as isSlackPluginAccountConfigured, r as slackConfigAdapter, t as createSlackPluginBase } from "./shared-GoB-OuUq.js";
13
+ import { i as SLACK_CHANNEL, n as createSlackSetupWizardProxy, r as slackSetupAdapter } from "./setup-core-WWQl-cE9.js";
17
14
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
18
15
  import { adaptScopedAccountAccessor } from "openclaw/plugin-sdk/channel-config-helpers";
19
16
  import { buildOutboundBaseSessionKey } from "openclaw/plugin-sdk/routing";
@@ -31,7 +28,6 @@ import { createApproverRestrictedNativeApprovalCapability, splitChannelApprovalC
31
28
  import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
32
29
  import { createChannelApproverDmTargetResolver, createChannelNativeOriginTargetResolver, resolveApprovalRequestSessionConversation } from "openclaw/plugin-sdk/approval-native-runtime";
33
30
  import { channelRouteTargetsMatchExact, stringifyRouteThreadId } from "openclaw/plugin-sdk/channel-route";
34
- import { createResolvedApproverActionAuthAdapter, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
35
31
  import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
36
32
  import { normalizeInteractiveReply, normalizeMessagePresentation } from "openclaw/plugin-sdk/interactive-runtime";
37
33
  import { readNumberParam, readStringParam } from "openclaw/plugin-sdk/param-readers";
@@ -47,30 +43,6 @@ function resolveSlackAutoThreadId(params) {
47
43
  return context.currentThreadTs;
48
44
  }
49
45
  //#endregion
50
- //#region extensions/slack/src/approval-auth.ts
51
- function getSlackApprovalApprovers(params) {
52
- const account = resolveSlackAccount(params).config;
53
- return resolveApprovalApprovers({
54
- allowFrom: resolveSlackAccountAllowFrom(params),
55
- defaultTo: account.defaultTo,
56
- normalizeApprover: normalizeSlackApproverId,
57
- normalizeDefaultTo: normalizeSlackApproverId
58
- });
59
- }
60
- function isSlackApprovalAuthorizedSender(params) {
61
- const senderId = params.senderId ? normalizeSlackApproverId(params.senderId) : void 0;
62
- if (!senderId) return false;
63
- return getSlackApprovalApprovers(params).includes(senderId);
64
- }
65
- createResolvedApproverActionAuthAdapter({
66
- channelLabel: "Slack",
67
- resolveApprovers: ({ cfg, accountId }) => getSlackApprovalApprovers({
68
- cfg,
69
- accountId
70
- }),
71
- normalizeSenderId: (value) => normalizeSlackApproverId(value)
72
- });
73
- //#endregion
74
46
  //#region extensions/slack/src/approval-native.ts
75
47
  function extractSlackSessionKind(sessionKey) {
76
48
  if (!sessionKey) return null;
@@ -201,7 +173,7 @@ const slackApprovalCapability = createApproverRestrictedNativeApprovalCapability
201
173
  accountId,
202
174
  request
203
175
  }),
204
- load: async () => (await import("./approval-handler.runtime-CmeRr9qA.js")).slackApprovalNativeRuntime
176
+ load: async () => (await import("./approval-handler.runtime-BjzVRaXN.js")).slackApprovalNativeRuntime
205
177
  })
206
178
  });
207
179
  splitChannelApprovalCapability(slackApprovalCapability);
@@ -368,7 +340,7 @@ async function handleSlackMessageAction(params) {
368
340
  //#region extensions/slack/src/channel-actions.ts
369
341
  let slackActionRuntimePromise$1;
370
342
  async function loadSlackActionRuntime$1() {
371
- slackActionRuntimePromise$1 ??= import("./action-runtime.runtime-BFcqMbOm.js");
343
+ slackActionRuntimePromise$1 ??= import("./action-runtime.runtime-DLhfKw4B.js");
372
344
  return await slackActionRuntimePromise$1;
373
345
  }
374
346
  function resolveSlackActionContext(params) {
@@ -492,9 +464,9 @@ const EXTENSION_SHARED_MODULE_ID = "openclaw/plugin-sdk/extension-shared";
492
464
  const TARGET_RESOLVER_RUNTIME_MODULE_ID = "openclaw/plugin-sdk/target-resolver-runtime";
493
465
  const loadExtensionSharedSdk = createLazyRuntimeModule(() => import(EXTENSION_SHARED_MODULE_ID));
494
466
  const loadTargetResolverRuntimeSdk = createLazyRuntimeModule(() => import(TARGET_RESOLVER_RUNTIME_MODULE_ID));
495
- const loadSlackSetupSurfaceModule = createLazyRuntimeModule(() => import("./setup-surface-D88QBVOW.js"));
496
- const loadSlackScopesModule = createLazyRuntimeModule(() => import("./scopes-CDevO8jg.js"));
497
- const loadSlackOutboundAdapterModule = createLazyRuntimeModule(() => import("./outbound-adapter-B_5sEhCg.js").then((n) => n.t));
467
+ const loadSlackSetupSurfaceModule = createLazyRuntimeModule(() => import("./setup-surface-BLoTgna4.js"));
468
+ const loadSlackScopesModule = createLazyRuntimeModule(() => import("./scopes-Bvg_ZzqZ.js"));
469
+ const loadSlackOutboundAdapterModule = createLazyRuntimeModule(() => import("./outbound-adapter-BluPNDNi.js").then((n) => n.t));
498
470
  async function resolveSlackHandleAction() {
499
471
  return getOptionalSlackRuntime()?.channel?.slack?.handleSlackAction ?? (await loadSlackActionRuntime()).handleSlackAction;
500
472
  }
@@ -514,27 +486,27 @@ let slackSendRuntimePromise;
514
486
  let slackProbeModulePromise;
515
487
  let slackMonitorModulePromise;
516
488
  let slackDirectoryLiveModulePromise;
517
- const loadSlackDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-B3JiHeB7.js").then((n) => n.t));
518
- const loadSlackResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-BRYqyNVJ.js").then((n) => n.n));
519
- const loadSlackResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-Bd_SdP8j.js").then((n) => n.n));
489
+ const loadSlackDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-CMvFiswf.js").then((n) => n.t));
490
+ const loadSlackResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-B_eKaOkE.js").then((n) => n.n));
491
+ const loadSlackResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-BzBAJwvq.js").then((n) => n.n));
520
492
  async function loadSlackActionRuntime() {
521
- slackActionRuntimePromise ??= import("./action-runtime.runtime-BFcqMbOm.js");
493
+ slackActionRuntimePromise ??= import("./action-runtime.runtime-DLhfKw4B.js");
522
494
  return await slackActionRuntimePromise;
523
495
  }
524
496
  async function loadSlackSendRuntime() {
525
- slackSendRuntimePromise ??= import("./send.runtime-_l76lUuL.js");
497
+ slackSendRuntimePromise ??= import("./send.runtime-E47jGN-2.js");
526
498
  return await slackSendRuntimePromise;
527
499
  }
528
500
  async function loadSlackProbeModule() {
529
- slackProbeModulePromise ??= import("./probe-3eZf1FjI.js").then((n) => n.n);
501
+ slackProbeModulePromise ??= import("./probe-FL4sUJsH.js").then((n) => n.n);
530
502
  return await slackProbeModulePromise;
531
503
  }
532
504
  async function loadSlackMonitorModule() {
533
- slackMonitorModulePromise ??= import("./monitor-a97o17G6.js").then((n) => n.t);
505
+ slackMonitorModulePromise ??= import("./monitor-DDE5AI2O.js").then((n) => n.t);
534
506
  return await slackMonitorModulePromise;
535
507
  }
536
508
  async function loadSlackDirectoryLiveModule() {
537
- slackDirectoryLiveModulePromise ??= import("./directory-live-Bf16GwDh.js").then((n) => n.t);
509
+ slackDirectoryLiveModulePromise ??= import("./directory-live-CZPzpQZF.js").then((n) => n.t);
538
510
  return await slackDirectoryLiveModulePromise;
539
511
  }
540
512
  async function resolveSlackSendContext(params) {
@@ -1,2 +1,2 @@
1
- import { t as SlackChannelConfigSchema } from "./config-schema-D9B5LB_L.js";
1
+ import { t as SlackChannelConfigSchema } from "./config-schema-CNRousxw.js";
2
2
  export { SlackChannelConfigSchema };
@@ -1,2 +1,2 @@
1
- import { t as slackPlugin } from "./channel-DRjHBTDB.js";
1
+ import { t as slackPlugin } from "./channel-Dh07mU_K.js";
2
2
  export { slackPlugin };
@@ -1,10 +1,10 @@
1
- import { a as resolveSlackAccount, c as resolveSlackConfigAccessorAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds } from "./accounts-ClAPP5ry.js";
2
- import { a as describeSlackSetupAccount, i as SLACK_CHANNEL, n as createSlackSetupWizardProxy, o as isSlackSetupAccountConfigured, r as slackSetupAdapter } from "./setup-core-B9NetDkM.js";
3
- import { t as SlackChannelConfigSchema } from "./config-schema-D9B5LB_L.js";
1
+ import { a as resolveSlackAccount, c as resolveSlackConfigAccessorAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds } from "./accounts-yk5K3wQU.js";
2
+ import { a as describeSlackSetupAccount, i as SLACK_CHANNEL, n as createSlackSetupWizardProxy, o as isSlackSetupAccountConfigured, r as slackSetupAdapter } from "./setup-core-WWQl-cE9.js";
3
+ import { t as SlackChannelConfigSchema } from "./config-schema-CNRousxw.js";
4
4
  import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
5
5
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
6
6
  //#region extensions/slack/src/channel.setup.ts
7
- const slackSetupWizard = createSlackSetupWizardProxy(async () => ({ slackSetupWizard: (await import("./setup-surface-D88QBVOW.js")).slackSetupWizard }));
7
+ const slackSetupWizard = createSlackSetupWizardProxy(async () => ({ slackSetupWizard: (await import("./setup-surface-BLoTgna4.js")).slackSetupWizard }));
8
8
  const slackSetupConfigAdapter = createScopedChannelConfigAdapter({
9
9
  sectionKey: SLACK_CHANNEL,
10
10
  listAccountIds: listSlackAccountIds,
@@ -1,7 +1,26 @@
1
+ import "./target-parsing-CQmv-iSm.js";
2
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1 } from "openclaw/plugin-sdk/account-id";
3
+ import { PAIRING_APPROVED_MESSAGE, projectCredentialSnapshotFields, resolveConfiguredFromRequiredCredentialStatuses } from "openclaw/plugin-sdk/channel-status";
1
4
  import { createHash } from "node:crypto";
2
5
  import { WebClient } from "@slack/web-api";
3
6
  import { HttpsProxyAgent } from "https-proxy-agent";
4
7
  import { resolveEnvHttpProxyUrl } from "openclaw/plugin-sdk/fetch-runtime";
8
+ //#region extensions/slack/src/channel-api.ts
9
+ const SLACK_CHANNEL_META = {
10
+ id: "slack",
11
+ label: "Slack",
12
+ selectionLabel: "Slack",
13
+ docsPath: "/channels/slack",
14
+ docsLabel: "slack",
15
+ blurb: "supports bot + app tokens, channels, threads, and interactive replies.",
16
+ systemImage: "number.square",
17
+ markdownCapable: true
18
+ };
19
+ function getChatChannelMeta(id) {
20
+ if (id !== SLACK_CHANNEL_META.id) throw new Error(`Unsupported Slack channel meta lookup: ${id}`);
21
+ return SLACK_CHANNEL_META;
22
+ }
23
+ //#endregion
5
24
  //#region extensions/slack/src/client-options.ts
6
25
  const SLACK_DEFAULT_RETRY_OPTIONS = {
7
26
  retries: 2,
@@ -100,4 +119,4 @@ function clearSlackWriteClientCacheForTest() {
100
119
  slackWriteClientCache.clear();
101
120
  }
102
121
  //#endregion
103
- export { getSlackWriteClient as a, resolveSlackWebClientOptions as c, createSlackWriteClient as i, resolveSlackWriteClientOptions as l, createSlackTokenCacheKey as n, SLACK_DEFAULT_RETRY_OPTIONS as o, createSlackWebClient as r, SLACK_WRITE_RETRY_OPTIONS as s, clearSlackWriteClientCacheForTest as t };
122
+ export { getSlackWriteClient as a, resolveSlackWebClientOptions as c, PAIRING_APPROVED_MESSAGE as d, getChatChannelMeta as f, createSlackWriteClient as i, resolveSlackWriteClientOptions as l, resolveConfiguredFromRequiredCredentialStatuses as m, createSlackTokenCacheKey as n, SLACK_DEFAULT_RETRY_OPTIONS as o, projectCredentialSnapshotFields as p, createSlackWebClient as r, SLACK_WRITE_RETRY_OPTIONS as s, clearSlackWriteClientCacheForTest as t, DEFAULT_ACCOUNT_ID$1 as u };
@@ -1,4 +1,4 @@
1
- import { n as buildChannelConfigSchema, t as SlackConfigSchema } from "./config-api-B_jq4NJW.js";
1
+ import { n as buildChannelConfigSchema, t as SlackConfigSchema } from "./config-api-CmgE_ORg.js";
2
2
  //#endregion
3
3
  //#region extensions/slack/src/config-schema.ts
4
4
  const SlackChannelConfigSchema = buildChannelConfigSchema(SlackConfigSchema, { uiHints: {
@@ -30,6 +30,26 @@ const SlackChannelConfigSchema = buildChannelConfigSchema(SlackConfigSchema, { u
30
30
  label: "Slack Allow Bot Messages",
31
31
  help: "Allow bot-authored messages to trigger Slack replies (default: false)."
32
32
  },
33
+ botLoopProtection: {
34
+ label: "Slack Bot Loop Protection",
35
+ help: "Sliding-window guard for Slack bot-to-bot loops. Default is enabled whenever allowBots lets bot-authored messages reach dispatch."
36
+ },
37
+ "botLoopProtection.enabled": {
38
+ label: "Slack Bot Loop Protection Enabled",
39
+ help: "Enable the bot-pair loop guard. Defaults to true when allowBots is true or \"mentions\", and false when bot messages are ignored."
40
+ },
41
+ "botLoopProtection.maxEventsPerWindow": {
42
+ label: "Slack Bot Loop Events per Window",
43
+ help: "Maximum accepted bot-pair messages within the sliding window before suppression starts. Default: 20."
44
+ },
45
+ "botLoopProtection.windowSeconds": {
46
+ label: "Slack Bot Loop Window Seconds",
47
+ help: "Sliding window length for counting bot-pair messages. Default: 60."
48
+ },
49
+ "botLoopProtection.cooldownSeconds": {
50
+ label: "Slack Bot Loop Cooldown Seconds",
51
+ help: "How long to suppress the bot pair after it exceeds the budget. Default: 60."
52
+ },
33
53
  socketMode: {
34
54
  label: "Slack Socket Mode Transport",
35
55
  help: "Slack Socket Mode transport tuning passed to the Slack SDK. Use only when investigating ping/pong timeout or stale websocket behavior."
@@ -1,5 +1,5 @@
1
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-KUjHnkQm.js";
2
- import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-Bo6lbSkh.js";
3
- import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-B3JiHeB7.js";
4
- import { t as collectSlackSecurityAuditFindings } from "./security-audit-BtHGnD3d.js";
1
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-B8QIWMs1.js";
2
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-0TL3L5Kb.js";
3
+ import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-CMvFiswf.js";
4
+ import { t as collectSlackSecurityAuditFindings } from "./security-audit-BJzADAw3.js";
5
5
  export { collectRuntimeConfigAssignments, collectSlackSecurityAuditFindings, legacyConfigRules, listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig, normalizeCompatibilityConfig, secretTargetRegistryEntries };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-ClAPP5ry.js";
2
+ import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-yk5K3wQU.js";
3
3
  import { r as parseSlackTarget } from "./target-parsing-CQmv-iSm.js";
4
4
  import "./targets-B1tYCAr6.js";
5
5
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
@@ -1,2 +1,2 @@
1
- import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-B3JiHeB7.js";
1
+ import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-CMvFiswf.js";
2
2
  export { listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig };
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { a as resolveSlackAccount } from "./accounts-ClAPP5ry.js";
3
- import { r as createSlackWebClient } from "./client-CPe4GmDR.js";
2
+ import { a as resolveSlackAccount } from "./accounts-yk5K3wQU.js";
3
+ import { r as createSlackWebClient } from "./client-C_IaJbi5.js";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  //#region extensions/slack/src/directory-live.ts
6
6
  var directory_live_exports = /* @__PURE__ */ __exportAll({
@@ -1,4 +1,4 @@
1
- import { n as resolveSlackNativeStreaming, r as resolveSlackStreamingMode } from "./streaming-compat-RkZgTmQ2.js";
1
+ import { n as resolveSlackNativeStreaming, r as resolveSlackStreamingMode } from "./streaming-compat-eu5Rj5gj.js";
2
2
  import { asObjectRecord, hasLegacyAccountStreamingAliases, hasLegacyStreamingAliases, normalizeLegacyChannelAliases } from "openclaw/plugin-sdk/runtime-doctor";
3
3
  //#region extensions/slack/src/doctor-contract.ts
4
4
  function hasLegacySlackStreamingAliases(value) {
@@ -1,2 +1,2 @@
1
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-KUjHnkQm.js";
1
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-B8QIWMs1.js";
2
2
  export { legacyConfigRules, normalizeCompatibilityConfig };
@@ -1,2 +1,2 @@
1
- import { t as registerSlackPluginHttpRoutes } from "./plugin-routes-DtTPmga1.js";
1
+ import { t as registerSlackPluginHttpRoutes } from "./plugin-routes-CRnfsTTX.js";
2
2
  export { registerSlackPluginHttpRoutes };
@@ -1,3 +1,3 @@
1
- import { t as prepareSlackMessage } from "./prepare-D3YqV8jB.js";
2
- import { t as createInboundSlackTestContext } from "./prepare.test-helpers-DVcjRhfG.js";
1
+ import { t as prepareSlackMessage } from "./prepare-D0tMg4dt.js";
2
+ import { t as createInboundSlackTestContext } from "./prepare.test-helpers-CU1qB54Q.js";
3
3
  export { createInboundSlackTestContext, prepareSlackMessage };
@@ -1,4 +1,4 @@
1
- import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId } from "./accounts-ClAPP5ry.js";
1
+ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId } from "./accounts-yk5K3wQU.js";
2
2
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  //#region extensions/slack/src/interactive-replies.ts
4
4
  const SLACK_BUTTON_MAX_ITEMS = 5;
@@ -1,2 +1,2 @@
1
- import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-qAIfuBor.js";
1
+ import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-BSg5hXhj.js";
2
2
  export { compileSlackInteractiveReplies, isSlackInteractiveRepliesEnabled };
@@ -1,5 +1,5 @@
1
- import { a as resolveSlackAccount, t as listEnabledSlackAccounts } from "./accounts-ClAPP5ry.js";
2
- import { n as isSlackInteractiveRepliesEnabled } from "./interactive-replies-qAIfuBor.js";
1
+ import { a as resolveSlackAccount, t as listEnabledSlackAccounts } from "./accounts-yk5K3wQU.js";
2
+ import { n as isSlackInteractiveRepliesEnabled } from "./interactive-replies-BSg5hXhj.js";
3
3
  import { createActionGate } from "openclaw/plugin-sdk/channel-actions";
4
4
  import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
5
5
  import { Type } from "typebox";
@@ -1,2 +1,2 @@
1
- import { t as describeSlackMessageTool } from "./message-tool-api-6lowf9zE.js";
1
+ import { t as describeSlackMessageTool } from "./message-tool-api-C7gc7goF.js";
2
2
  export { describeSlackMessageTool as describeMessageTool };
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { D as buildSlackSlashCommandMatcher, p as isSlackChannelAllowedByPolicy } from "./room-context-0vovmZPU.js";
3
- import { t as monitorSlackProvider } from "./provider-D7uAN3Fq.js";
4
- import { o as resolveSlackThreadTs } from "./replies-Xe_jMR6o.js";
2
+ import { D as buildSlackSlashCommandMatcher, p as isSlackChannelAllowedByPolicy } from "./room-context-Cd8jFpS-.js";
3
+ import { t as monitorSlackProvider } from "./provider-C6WxaFFf.js";
4
+ import { o as resolveSlackThreadTs } from "./replies-D0QXXSPP.js";
5
5
  //#region extensions/slack/src/monitor.ts
6
6
  var monitor_exports = /* @__PURE__ */ __exportAll({
7
7
  buildSlackSlashCommandMatcher: () => buildSlackSlashCommandMatcher,
@@ -1,8 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { n as buildSlackPresentationBlocks, r as resolveSlackInteractiveBlockOffsets, t as buildSlackInteractiveBlocks } from "./blocks-render-BIDw-Pom.js";
3
- import { n as resolveSlackThreadTsValue, r as SLACK_TEXT_LIMIT } from "./thread-ts-C2x7c5PP.js";
4
- import { t as compileSlackInteractiveReplies } from "./interactive-replies-qAIfuBor.js";
5
- import { n as parseSlackBlocksInput } from "./blocks-input-CwTFVImV.js";
2
+ import { n as buildSlackPresentationBlocks, r as resolveSlackInteractiveBlockOffsets, t as buildSlackInteractiveBlocks } from "./blocks-render-BAVfd6r0.js";
3
+ import { i as parseSlackBlocksInput, n as resolveSlackThreadTsValue, o as SLACK_TEXT_LIMIT } from "./thread-ts-As_dcNbD.js";
4
+ import { t as compileSlackInteractiveReplies } from "./interactive-replies-BSg5hXhj.js";
6
5
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
6
  import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
8
7
  import { resolveOutboundSendDep } from "openclaw/plugin-sdk/outbound-send-deps";
@@ -13,7 +12,7 @@ var outbound_adapter_exports = /* @__PURE__ */ __exportAll({ slackOutbound: () =
13
12
  const SLACK_MAX_BLOCKS = 50;
14
13
  let slackSendRuntimePromise;
15
14
  async function loadSlackSendRuntime() {
16
- slackSendRuntimePromise ??= import("./send.runtime-_l76lUuL.js");
15
+ slackSendRuntimePromise ??= import("./send.runtime-E47jGN-2.js");
17
16
  return await slackSendRuntimePromise;
18
17
  }
19
18
  function resolveRenderedInteractiveBlocks(interactive, previousBlocks) {
@@ -1,2 +1,2 @@
1
- import { t as createSlackOutboundPayloadHarness } from "./outbound-payload.test-harness-CVCamg1x.js";
1
+ import { t as createSlackOutboundPayloadHarness } from "./outbound-payload.test-harness-BNxnP6MC.js";
2
2
  export { createSlackOutboundPayloadHarness };
@@ -1,4 +1,4 @@
1
- import { n as slackOutbound } from "./outbound-adapter-B_5sEhCg.js";
1
+ import { n as slackOutbound } from "./outbound-adapter-BluPNDNi.js";
2
2
  import { primeChannelOutboundSendMock } from "openclaw/plugin-sdk/channel-contract-testing";
3
3
  //#region node_modules/tinyrainbow/dist/index.js
4
4
  var b = {
@@ -10147,7 +10147,7 @@ function memo(fn) {
10147
10147
  };
10148
10148
  }
10149
10149
  async function saveInlineSnapshots(environment, snapshots) {
10150
- const MagicString = (await import("./magic-string.es-BMaGRRZ1.js")).default;
10150
+ const MagicString = (await import("./magic-string.es-9lw4MGoF.js")).default;
10151
10151
  const files = new Set(snapshots.map((i) => i.file));
10152
10152
  await Promise.all(Array.from(files).map(async (file) => {
10153
10153
  const snaps = snapshots.filter((i) => i.file === file);
@@ -1,24 +1,24 @@
1
- import { i as truncateSlackText, r as SLACK_TEXT_LIMIT } from "./thread-ts-C2x7c5PP.js";
2
- import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-qAIfuBor.js";
3
- import { i as normalizeSlackAllowOwnerEntry } from "./allow-list-BPnnlRPL.js";
4
- import "./blocks-input-CwTFVImV.js";
5
- import { n as resolveSlackNativeStreaming, r as resolveSlackStreamingMode, t as mapStreamingModeToSlackLegacyDraftStreamMode } from "./streaming-compat-RkZgTmQ2.js";
6
- import { a as recordSlackThreadParticipation, s as normalizeSlackOutboundText, t as sendMessageSlack } from "./send-D_A9kL-C.js";
7
- import { f as removeSlackReaction, h as buildSlackEditTextPayload, l as reactSlackMessage, r as editSlackMessage, t as deleteSlackMessage } from "./actions-CYLFK-Zy.js";
8
- import { t as formatSlackError } from "./errors-BYFHR24f.js";
9
- import { T as updateLastRoute, a as recordInboundSession, w as resolveStorePath } from "./room-context-0vovmZPU.js";
10
- import { t as escapeSlackMrkdwn } from "./mrkdwn-Cax-eSfK.js";
11
- import { n as resolveSlackThreadTargets, t as prepareSlackMessage } from "./prepare-D3YqV8jB.js";
12
- import { a as resolveDeliveredSlackReplyThreadTs, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, t as createSlackReplyDeliveryPlan } from "./replies-Xe_jMR6o.js";
1
+ import { o as SLACK_TEXT_LIMIT, s as truncateSlackText } from "./thread-ts-As_dcNbD.js";
2
+ import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-BSg5hXhj.js";
3
+ import { i as normalizeSlackAllowOwnerEntry } from "./allow-list-nwXs_eCP.js";
4
+ import { n as resolveSlackNativeStreaming, r as resolveSlackStreamingMode, t as mapStreamingModeToSlackLegacyDraftStreamMode } from "./streaming-compat-eu5Rj5gj.js";
5
+ import { a as recordSlackThreadParticipation, s as normalizeSlackOutboundText, t as sendMessageSlack } from "./send-Dg9zcyYT.js";
6
+ import { b as buildSlackEditTextPayload, f as removeSlackReaction, l as reactSlackMessage, r as editSlackMessage, t as deleteSlackMessage } from "./actions-BibhOXpJ.js";
7
+ import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
8
+ import { T as updateLastRoute, a as recordInboundSession, w as resolveStorePath } from "./room-context-Cd8jFpS-.js";
9
+ import { r as escapeSlackMrkdwn } from "./provider-C6WxaFFf.js";
10
+ import { n as resolveSlackThreadTargets, t as prepareSlackMessage } from "./prepare-D0tMg4dt.js";
11
+ import { a as resolveDeliveredSlackReplyThreadTs, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, t as createSlackReplyDeliveryPlan } from "./replies-D0QXXSPP.js";
13
12
  import { normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
14
13
  import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
15
14
  import { createChannelMessageReplyPipeline, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-message";
16
- import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelProgressDraftGate, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, resolveChannelProgressDraftLabel, resolveChannelProgressDraftMaxLines, resolveChannelProgressDraftRender, resolveChannelStreamingBlockEnabled, resolveChannelStreamingNativeTransport, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-streaming";
15
+ import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelProgressDraftGate, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, mergeChannelProgressDraftLine, resolveChannelProgressDraftLabel, resolveChannelProgressDraftMaxLines, resolveChannelProgressDraftRender, resolveChannelStreamingBlockEnabled, resolveChannelStreamingNativeTransport, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-streaming";
17
16
  import { danger, logVerbose, shouldLogVerbose, sleep } from "openclaw/plugin-sdk/runtime-env";
18
17
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
19
18
  import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
20
19
  import { clearHistoryEntriesIfEnabled } from "openclaw/plugin-sdk/reply-history";
21
20
  import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
21
+ import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
22
22
  import { resolvePinnedMainDmOwnerFromAllowlist } from "openclaw/plugin-sdk/security-runtime";
23
23
  import { DEFAULT_TIMING, createStatusReactionController, logAckFailure, logTypingFailure, removeAckReactionAfterReply } from "openclaw/plugin-sdk/channel-feedback";
24
24
  import { hasVisibleInboundReplyDispatch, runInboundReplyTurn } from "openclaw/plugin-sdk/inbound-reply-dispatch";
@@ -465,10 +465,34 @@ const UNICODE_TO_SLACK = {
465
465
  "⏳": "hourglass_flowing_sand",
466
466
  "⚠️": "warning",
467
467
  "✍": "writing_hand",
468
+ "🗜️": "compression",
469
+ "🗜": "compression",
468
470
  "🧠": "brain",
469
471
  "🛠️": "hammer_and_wrench",
470
472
  "💻": "computer"
471
473
  };
474
+ function resolveSlackMessageTimestampMs(message) {
475
+ const ts = message.event_ts ?? message.ts;
476
+ if (!ts) return;
477
+ const parsed = Number(ts);
478
+ return Number.isFinite(parsed) ? Math.trunc(parsed * 1e3) : void 0;
479
+ }
480
+ function resolveSlackBotLoopProtection(prepared) {
481
+ const senderBotId = prepared.message.bot_id;
482
+ if (!senderBotId) return;
483
+ const receiverBotId = prepared.ctx.botId || prepared.ctx.botUserId;
484
+ if (!receiverBotId || senderBotId === prepared.ctx.botId || prepared.message.user === prepared.ctx.botUserId) return;
485
+ return {
486
+ scopeId: prepared.route.accountId,
487
+ conversationId: prepared.message.channel,
488
+ senderId: senderBotId,
489
+ receiverId: receiverBotId,
490
+ config: mergePairLoopGuardConfig(prepared.account.config.botLoopProtection, prepared.channelConfig?.botLoopProtection),
491
+ defaultsConfig: prepared.ctx.cfg.channels?.defaults?.botLoopProtection,
492
+ defaultEnabled: true,
493
+ nowMs: resolveSlackMessageTimestampMs(prepared.message)
494
+ };
495
+ }
472
496
  function toSlackEmojiName(emoji) {
473
497
  let trimmed = emoji.trim();
474
498
  while (trimmed.startsWith(":")) trimmed = trimmed.slice(1);
@@ -1112,8 +1136,9 @@ async function dispatchPreparedSlackMessage(prepared) {
1112
1136
  }
1113
1137
  if (streamMode !== "status_final") {
1114
1138
  if (!previewToolProgressEnabled || previewToolProgressSuppressed) return;
1115
- if (previewToolProgressLines.at(-1)?.text === normalized) return;
1116
- previewToolProgressLines = [...previewToolProgressLines, line].slice(-resolveChannelProgressDraftMaxLines(account.config));
1139
+ const nextLines = mergeChannelProgressDraftLine(previewToolProgressLines, line, { maxLines: resolveChannelProgressDraftMaxLines(account.config) });
1140
+ if (nextLines === previewToolProgressLines) return;
1141
+ previewToolProgressLines = nextLines;
1117
1142
  draftStream.update(formatChannelProgressDraftText({
1118
1143
  entry: account.config,
1119
1144
  lines: previewToolProgressLines,
@@ -1123,9 +1148,7 @@ async function dispatchPreparedSlackMessage(prepared) {
1123
1148
  hasStreamedMessage = true;
1124
1149
  return;
1125
1150
  }
1126
- if (previewToolProgressEnabled && !previewToolProgressSuppressed) {
1127
- if (previewToolProgressLines.at(-1)?.text !== normalized) previewToolProgressLines = [...previewToolProgressLines, line].slice(-resolveChannelProgressDraftMaxLines(account.config));
1128
- }
1151
+ if (previewToolProgressEnabled && !previewToolProgressSuppressed) previewToolProgressLines = mergeChannelProgressDraftLine(previewToolProgressLines, line, { maxLines: resolveChannelProgressDraftMaxLines(account.config) });
1129
1152
  const alreadyStarted = progressDraftGate.hasStarted;
1130
1153
  await progressDraftGate.noteWork();
1131
1154
  if (alreadyStarted && progressDraftGate.hasStarted) renderProgressDraft();
@@ -1197,6 +1220,7 @@ async function dispatchPreparedSlackMessage(prepared) {
1197
1220
  ctxPayload: prepared.ctxPayload,
1198
1221
  recordInboundSession,
1199
1222
  record: prepared.turn.record,
1223
+ botLoopProtection: resolveSlackBotLoopProtection(prepared),
1200
1224
  onPreDispatchFailure: async () => {
1201
1225
  dispatchSettledBeforeStart = true;
1202
1226
  await settleReplyDispatcher({
@@ -1236,6 +1260,7 @@ async function dispatchPreparedSlackMessage(prepared) {
1236
1260
  onItemEvent: async (payload) => {
1237
1261
  await pushPreviewToolProgress(buildChannelProgressDraftLineForEntry(account.config, {
1238
1262
  event: "item",
1263
+ itemId: payload.itemId,
1239
1264
  itemKind: payload.kind,
1240
1265
  title: payload.title,
1241
1266
  name: payload.name,
@@ -1296,10 +1321,11 @@ async function dispatchPreparedSlackMessage(prepared) {
1296
1321
  })
1297
1322
  }
1298
1323
  });
1299
- if (!turnResult.dispatched) return;
1300
- const result = turnResult.dispatchResult;
1301
- queuedFinal = result.queuedFinal;
1302
- counts = result.counts;
1324
+ if (turnResult.dispatched) {
1325
+ const result = turnResult.dispatchResult;
1326
+ queuedFinal = result.queuedFinal;
1327
+ counts = result.counts;
1328
+ }
1303
1329
  } catch (err) {
1304
1330
  dispatchError = err;
1305
1331
  } finally {
@@ -1,5 +1,5 @@
1
- import { n as listSlackAccountIds, r as mergeSlackAccountConfig } from "./accounts-ClAPP5ry.js";
2
- import { r as normalizeSlackWebhookPath, t as handleSlackHttpRequest } from "./registry-CeaoNfoP.js";
1
+ import { n as listSlackAccountIds, r as mergeSlackAccountConfig } from "./accounts-yk5K3wQU.js";
2
+ import { r as normalizeSlackWebhookPath, t as handleSlackHttpRequest } from "./registry-D2cWOLZV.js";
3
3
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
4
4
  //#region extensions/slack/src/http/plugin-routes.ts
5
5
  function registerSlackPluginHttpRoutes(api) {
@@ -1,13 +1,12 @@
1
- import { l as resolveSlackReplyToMode } from "./accounts-ClAPP5ry.js";
1
+ import { l as resolveSlackReplyToMode } from "./accounts-yk5K3wQU.js";
2
2
  import { r as parseSlackTarget } from "./target-parsing-CQmv-iSm.js";
3
3
  import "./targets-B1tYCAr6.js";
4
- import { i as normalizeSlackAllowOwnerEntry, o as resolveSlackAllowListMatch, r as normalizeAllowListLower } from "./allow-list-BPnnlRPL.js";
5
- import { i as hasSlackThreadParticipationWithPersistence, t as sendMessageSlack } from "./send-D_A9kL-C.js";
6
- import { l as reactSlackMessage } from "./actions-CYLFK-Zy.js";
7
- import { i as resolveSlackThreadStarter, o as formatSlackFileReference, r as resolveSlackThreadHistory } from "./media-D1XCd1uP.js";
8
- import { t as formatSlackError } from "./errors-BYFHR24f.js";
9
- import { b as readSessionUpdatedAt, c as authorizeSlackBotRoomMessage, d as resolveSlackEffectiveAllowFrom, g as resolveSlackChannelConfig, h as resolveSlackChatType, k as stripSlackMentionsForCommandDetection, m as normalizeSlackChannelType, n as authorizeSlackDirectMessage, o as resolveConversationLabel$1, t as resolveSlackRoomContextHints, u as resolveSlackCommandIngress, w as resolveStorePath, x as resolveChannelContextVisibilityMode } from "./room-context-0vovmZPU.js";
10
- import "./send.runtime-BRE_ncCU.js";
4
+ import { i as normalizeSlackAllowOwnerEntry, o as resolveSlackAllowListMatch, r as normalizeAllowListLower } from "./allow-list-nwXs_eCP.js";
5
+ import { i as hasSlackThreadParticipationWithPersistence, t as sendMessageSlack } from "./send-Dg9zcyYT.js";
6
+ import { _ as resolveSlackThreadStarter, g as resolveSlackThreadHistory, l as reactSlackMessage, y as formatSlackFileReference } from "./actions-BibhOXpJ.js";
7
+ import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
8
+ import { b as readSessionUpdatedAt, c as authorizeSlackBotRoomMessage, d as resolveSlackEffectiveAllowFrom, g as resolveSlackChannelConfig, h as resolveSlackChatType, k as stripSlackMentionsForCommandDetection, m as normalizeSlackChannelType, n as authorizeSlackDirectMessage, o as resolveConversationLabel$1, t as resolveSlackRoomContextHints, u as resolveSlackCommandIngress, w as resolveStorePath, x as resolveChannelContextVisibilityMode } from "./room-context-Cd8jFpS-.js";
9
+ import "./send.runtime-CjjQ9StM.js";
11
10
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
12
11
  import { resolveAgentRoute, resolveInboundLastRouteSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
13
12
  import { resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-message";
@@ -29,7 +28,7 @@ const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
29
28
  const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
30
29
  let slackMediaModulePromise$1;
31
30
  function loadSlackMediaModule$1() {
32
- slackMediaModulePromise$1 ??= import("./media-D1XCd1uP.js").then((n) => n.t);
31
+ slackMediaModulePromise$1 ??= import("./actions-BibhOXpJ.js").then((n) => n.h);
33
32
  return slackMediaModulePromise$1;
34
33
  }
35
34
  function collectUniqueSlackMentionIds$1(texts) {
@@ -570,7 +569,7 @@ function formatSlackBotStarterThreadLabel(params) {
570
569
  //#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
571
570
  let slackMediaModulePromise;
572
571
  function loadSlackMediaModule() {
573
- slackMediaModulePromise ??= import("./media-D1XCd1uP.js").then((n) => n.t);
572
+ slackMediaModulePromise ??= import("./actions-BibhOXpJ.js").then((n) => n.h);
574
573
  return slackMediaModulePromise;
575
574
  }
576
575
  const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
@@ -1,4 +1,4 @@
1
- import { f as createSlackMonitorContext } from "./room-context-0vovmZPU.js";
1
+ import { f as createSlackMonitorContext } from "./room-context-Cd8jFpS-.js";
2
2
  import "openclaw/plugin-sdk/temp-path";
3
3
  //#region extensions/slack/src/monitor/message-handler/prepare.test-helpers.ts
4
4
  function createInboundSlackTestContext(params) {
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { r as createSlackWebClient } from "./client-CPe4GmDR.js";
3
- import { t as formatSlackError } from "./errors-BYFHR24f.js";
2
+ import { r as createSlackWebClient } from "./client-C_IaJbi5.js";
3
+ import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
4
4
  import { withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
5
5
  //#region extensions/slack/src/probe.ts
6
6
  var probe_exports = /* @__PURE__ */ __exportAll({ probeSlack: () => probeSlack });