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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/{account-inspect-Drw2gAiN.js → account-inspect-YJvFBbCR.js} +1 -1
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{accounts-CK4AVI2_.js → accounts-BlzxuYle.js} +5 -1
  4. package/dist/{accounts.runtime-Cb7QwWBz.js → accounts.runtime-CbabBL8x.js} +1 -1
  5. package/dist/{action-runtime-BkGe7ny_.js → action-runtime-D6jg2CQd.js} +64 -68
  6. package/dist/action-runtime.runtime-JtoOK9l5.js +2 -0
  7. package/dist/{actions-BTDXwwE3.js → actions-DFk0ANVB.js} +52 -212
  8. package/dist/{actions.runtime-DLFyUkvg.js → actions.runtime-CYLsYRai.js} +1 -1
  9. package/dist/api.js +14 -14
  10. package/dist/{approval-handler.runtime-CJaNzAq2.js → approval-handler.runtime-BNvAoKdK.js} +4 -2
  11. package/dist/{channel-D_tovcUL.js → channel-CA5w7qDF.js} +78 -39
  12. package/dist/channel-config-api.js +1 -1
  13. package/dist/channel-plugin-api.js +1 -1
  14. package/dist/{channel-type-B9MSdoGN.js → channel-type-CZWv55Wu.js} +3 -7
  15. package/dist/{channel.setup-Bch9dYmA.js → channel.setup-CpyYsEXH.js} +4 -4
  16. package/dist/{config-schema-xto5jFIx.js → config-schema-CN3XZRX5.js} +23 -7
  17. package/dist/conversation-binding-route-DFVLUdYF.js +115 -0
  18. package/dist/{directory-config-CNBz8lJa.js → directory-config-BGYyuzWh.js} +1 -1
  19. package/dist/directory-contract-api.js +1 -1
  20. package/dist/{directory-live-CFKUtW9E.js → directory-live-DjUJQLbq.js} +2 -2
  21. package/dist/{group-policy-c4RP9bjc.js → group-policy-DyfB_ZIE.js} +38 -24
  22. package/dist/{message-tool-api-BykQB4AU.js → message-tool-api-CqMr5Rmc.js} +2 -2
  23. package/dist/message-tool-api.js +1 -1
  24. package/dist/{monitor-1nF1NtqT.js → monitor-Chrecrb9.js} +3 -3
  25. package/dist/{outbound-adapter-S81tsswN.js → outbound-adapter-DuRqAQXK.js} +18 -8
  26. package/dist/{pipeline.runtime-BvYsM5JO.js → pipeline.runtime-Bbfd5VFW.js} +376 -324
  27. package/dist/{policy-TapwbeaT.js → policy-BKXSxrIS.js} +1 -1
  28. package/dist/{probe-HoEg_WxB.js → probe-BVA65leh.js} +1 -1
  29. package/dist/{provider-CDNvBXUi.js → provider-CUUiwsg2.js} +65 -44
  30. package/dist/{relay-source-C9leF11u.js → relay-source-mhpMMRG-.js} +1 -1
  31. package/dist/{replies-CeOfv82I.js → replies-SnWyXcsL.js} +36 -25
  32. package/dist/{resolve-channels-CNPrxaXY.js → resolve-channels-BSpqC8jU.js} +1 -1
  33. package/dist/{resolve-users-Dzomuwnr.js → resolve-users-Dvz9pDe0.js} +1 -1
  34. package/dist/{runtime-api-Cj9nxBNv.js → runtime-api-DBi7xc_g.js} +2 -2
  35. package/dist/runtime-api.js +11 -11
  36. package/dist/{scopes-cYXKkrRD.js → scopes-BSk4GZvZ.js} +1 -1
  37. package/dist/security-contract-api.js +1 -1
  38. package/dist/{send-Nor0iBwY.js → send-CtnOxKCc.js} +58 -78
  39. package/dist/{send.runtime-BmgNe6S9.js → send.runtime-kYctMHSd.js} +1 -1
  40. package/dist/setup-plugin-api.js +1 -1
  41. package/dist/{setup-surface-CbX1-Knh.js → setup-surface-BPFfp6So.js} +6 -6
  42. package/dist/{shared-zdT5AMp-.js → shared-DJBaslN7.js} +13 -7
  43. package/dist/{block-text-YtiNkqmx.js → slack-client-kind-BXyOOICI.js} +17 -2
  44. package/dist/{slash-dispatch.runtime-Bnr9GR1S.js → slash-dispatch.runtime-Cf2FTrnf.js} +2 -2
  45. package/openclaw.plugin.json +43 -1
  46. package/package.json +4 -6
  47. package/dist/account-reply-mode-DrUXogvO.js +0 -14
  48. package/dist/action-runtime.runtime-D9I6uc0Q.js +0 -2
  49. package/node_modules/p-map/index.d.ts +0 -155
  50. package/node_modules/p-map/index.js +0 -285
  51. package/node_modules/p-map/license +0 -9
  52. package/node_modules/p-map/package.json +0 -57
  53. package/node_modules/p-map/readme.md +0 -190
  54. package/dist/{security-audit-DR097212.js → security-audit-B_yKr7MW.js} +1 -1
@@ -1,20 +1,20 @@
1
- import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, l as resolveSlackOperationToken, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom } from "./accounts-CK4AVI2_.js";
2
- import { t as resolveSlackReplyToMode } from "./account-reply-mode-DrUXogvO.js";
1
+ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, l as resolveSlackOperationToken, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom } from "./accounts-BlzxuYle.js";
2
+ import { n as resolveSlackConversationBindingRoute, r as resolveSlackReplyToMode, t as normalizeSlackRouteBindingConfig } from "./conversation-binding-route-DFVLUdYF.js";
3
3
  import { a as parseSlackTarget, i as normalizeSlackMessagingTarget, n as formatSlackTarget, o as resolveSlackChannelId, r as looksLikeSlackTargetId, t as canonicalizeSlackApiTargetId } from "./target-parsing-BnMD2ZqZ.js";
4
4
  import { t as slackContextTargetsMatch } from "./targets-Cx5W_n3W.js";
5
- import { B as SLACK_TEXT_LIMIT, Ct as isSlackWorkspaceInstallation, Dt as getSlackExecApprovalApprovers, Et as isSlackApprovalAuthorizedSender, H as buildSlackPresentationBlocks, L as SLACK_EDIT_TEXT_MAX_BYTES, Mt as shouldSuppressLocalSlackExecApprovalPrompt, Ot as isSlackExecApprovalAuthorizedSender, Tt as getSlackApprovalApprovers, U as canRenderSlackPresentation, W as countSlackTextUtf8Bytes, _ as resolveSlackReplyBlocks, _t as resolveSlackFallbackOriginTarget, bt as shouldHandleSlackPluginViaForwardingSession, dt as hasSlackPluginApprovers, ft as isSlackAnyNativeApprovalClientEnabled, g as resolveSlackReplyBlockResolution, gt as resolveSessionSlackOriginTarget, ht as resolveEnterpriseApprovalTeamId, i as resolveSlackGroupToolPolicy, it as renderSlackMessagePresentationFallbackText, jt as resolveSlackExecApprovalTarget, kt as isSlackExecApprovalClientEnabled, mt as normalizeSlackOriginTarget, p as assertSlackDetachedTargetAllowed, pt as normalizeSlackForwardTarget, r as resolveSlackGroupRequireMention, st as SLACK_PRESENTATION_CAPABILITIES, v as resolveSlackReplyDeliveryMessages, vt as resolveTurnSourceSlackOriginTarget, xt as slackTargetsMatch, yt as shouldHandleSlackNativeApprovalRequest } from "./group-policy-c4RP9bjc.js";
5
+ import { At as isSlackApprovalAuthorizedSender, B as SLACK_EDIT_TEXT_MAX_BYTES, Ct as shouldHandleSlackNativeApprovalRequest, Dt as isSlackWorkspaceInstallation, Et as getSlackInstallationKind, Ft as resolveSlackExecApprovalTarget, G as buildSlackPresentationBlocks, It as shouldSuppressLocalSlackExecApprovalPrompt, K as canRenderSlackPresentation, Mt as isSlackExecApprovalAuthorizedSender, Nt as isSlackExecApprovalClientEnabled, Rt as resolveSlackAutoThreadId, St as resolveTurnSourceSlackOriginTarget, Tt as slackTargetsMatch, U as SLACK_TEXT_LIMIT, _t as normalizeSlackForwardTarget, a as qualifySlackConversationId, b as resolveSlackReplyBlocks, bt as resolveSessionSlackOriginTarget, dt as SLACK_PRESENTATION_CAPABILITIES, g as assertSlackDetachedTargetAllowed, gt as isSlackAnyNativeApprovalClientEnabled, ht as hasSlackPluginApprovers, i as resolveSlackGroupToolPolicy, jt as getSlackExecApprovalApprovers, kt as getSlackApprovalApprovers, o as qualifySlackRoutePeerId, q as countSlackTextUtf8Bytes, r as resolveSlackGroupRequireMention, st as renderSlackMessagePresentationFallbackText, vt as normalizeSlackOriginTarget, wt as shouldHandleSlackPluginViaForwardingSession, x as resolveSlackReplyDeliveryMessages, xt as resolveSlackFallbackOriginTarget, y as resolveSlackReplyBlockResolution, yt as resolveEnterpriseApprovalTeamId } from "./group-policy-DyfB_ZIE.js";
6
6
  import { t as isSlackPluginAccountConfigured } from "./account-configured-BwfXBo_F.js";
7
7
  import { n as resolveSlackThreadTsValue, t as normalizeSlackThreadTsCandidate } from "./thread-ts-DUGhaYKq.js";
8
- import { n as extractSlackToolSend, t as describeSlackMessageTool } from "./message-tool-api-BykQB4AU.js";
9
- import { S as resolveConfiguredFromRequiredCredentialStatuses, d as getSlackWriteClient, r as formatSlackError, v as DEFAULT_ACCOUNT_ID$1, x as projectCredentialSnapshotFields, y as PAIRING_APPROVED_MESSAGE } from "./probe-HoEg_WxB.js";
10
- import { n as resolveSlackChannelType, r as resolveSlackConversationInfo } from "./channel-type-B9MSdoGN.js";
8
+ import { n as extractSlackToolSend, t as describeSlackMessageTool } from "./message-tool-api-CqMr5Rmc.js";
9
+ import { S as resolveConfiguredFromRequiredCredentialStatuses, d as getSlackWriteClient, r as formatSlackError, v as DEFAULT_ACCOUNT_ID$1, x as projectCredentialSnapshotFields, y as PAIRING_APPROVED_MESSAGE } from "./probe-BVA65leh.js";
10
+ import { n as resolveSlackChannelType, r as resolveSlackConversationInfo } from "./channel-type-CZWv55Wu.js";
11
11
  import { t as getOptionalSlackRuntime } from "./runtime-JSVZSWAj.js";
12
- import { n as slackConfigAdapter, r as slackSecurityAdapter, t as createSlackPluginBase } from "./shared-zdT5AMp-.js";
13
- import { a as slackSetupContract, i as createSlackSetupWizardProxy, o as SLACK_CHANNEL } from "./channel.setup-Bch9dYmA.js";
12
+ import { n as slackConfigAdapter, r as slackSecurityAdapter, t as createSlackPluginBase } from "./shared-DJBaslN7.js";
13
+ import { a as slackSetupContract, i as createSlackSetupWizardProxy, o as SLACK_CHANNEL } from "./channel.setup-CpyYsEXH.js";
14
14
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
15
15
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
16
16
  import { adaptScopedAccountAccessor } from "openclaw/plugin-sdk/channel-config-helpers";
17
- import { buildOutboundBaseSessionKey, normalizeMessageChannel } from "openclaw/plugin-sdk/routing";
17
+ import { buildOutboundBaseSessionKey, normalizeMessageChannel, resolveAgentRoute } from "openclaw/plugin-sdk/routing";
18
18
  import { buildLegacyDmAccountAllowlistAdapter, createAccountScopedAllowlistNameResolver, createFlatAllowlistOverrideResolver } from "openclaw/plugin-sdk/allowlist-config-edit";
19
19
  import { buildThreadAwareOutboundSessionRoute, createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
20
20
  import { createChannelMessageAdapterFromOutbound, createRuntimeOutboundDelegates, resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
@@ -24,7 +24,6 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
24
24
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
25
25
  import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
26
26
  import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
27
- import { isSingleUseReplyToMode } from "openclaw/plugin-sdk/reply-reference";
28
27
  import { createApproverRestrictedNativeApprovalCapability } from "openclaw/plugin-sdk/approval-delivery-runtime";
29
28
  import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
30
29
  import { createChannelNativeOriginTargetResolver, createNativeApprovalForwardingFallbackSuppressor } from "openclaw/plugin-sdk/approval-native-runtime";
@@ -32,20 +31,6 @@ import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
32
31
  import { resolveReactionMessageId } from "openclaw/plugin-sdk/channel-actions";
33
32
  import { normalizeLegacyInteractiveReply, normalizeMessagePresentation } from "openclaw/plugin-sdk/interactive-runtime";
34
33
  import { readPositiveIntegerParam, readStringParam } from "openclaw/plugin-sdk/param-readers";
35
- //#region extensions/slack/src/action-threading.ts
36
- function resolveSlackAutoThreadId(params) {
37
- const context = params.toolContext;
38
- if (!context?.currentChannelId && !context?.currentMessagingTarget) return;
39
- if (!slackContextTargetsMatch(params.to, context)) return;
40
- if (!context.currentThreadTs) {
41
- if (context.sameChannelThreadRequired) throw new Error("Slack thread context is required for same-channel replies from a threaded Slack turn. Set topLevel=true or threadId=null to post at the channel root.");
42
- return;
43
- }
44
- if (context.replyToMode !== "all" && !isSingleUseReplyToMode(context.replyToMode ?? "off")) return;
45
- if (isSingleUseReplyToMode(context.replyToMode ?? "off") && context.hasRepliedRef?.value) return;
46
- return context.currentThreadTs;
47
- }
48
- //#endregion
49
34
  //#region extensions/slack/src/approval-native.ts
50
35
  function resolveSlackNativeSuppressionAccountId({ target, request }) {
51
36
  return normalizeOptionalString(target.accountId) ?? normalizeOptionalString(request.request.turnSourceAccountId);
@@ -145,7 +130,7 @@ const baseSlackApprovalCapability = createApproverRestrictedNativeApprovalCapabi
145
130
  approvalKind,
146
131
  request
147
132
  }),
148
- load: async () => (await import("./approval-handler.runtime-CJaNzAq2.js")).slackApprovalNativeRuntime
133
+ load: async () => (await import("./approval-handler.runtime-BNvAoKdK.js")).slackApprovalNativeRuntime
149
134
  })
150
135
  });
151
136
  const baseSlackNativeAdapter = baseSlackApprovalCapability.native;
@@ -389,7 +374,7 @@ async function handleSlackMessageAction(params) {
389
374
  action: "uploadFile",
390
375
  to,
391
376
  filePath,
392
- initialComment: readStringParam(actionParams, "initialComment", { allowEmpty: true }) ?? readStringParam(actionParams, "message", { allowEmpty: true }) ?? "",
377
+ initialComment: readStringParam(actionParams, "initialComment", { allowEmpty: true }) ?? readStringParam(actionParams, "message", { allowEmpty: true }) ?? readStringParam(actionParams, "caption", { allowEmpty: true }) ?? "",
393
378
  filename: readStringParam(actionParams, "filename"),
394
379
  title: readStringParam(actionParams, "title"),
395
380
  threadTs: threadId ?? void 0,
@@ -411,7 +396,7 @@ const SLACK_TOOL_DELIVERY_ACTIONS = /* @__PURE__ */ new Set([
411
396
  "unpinMessage",
412
397
  "uploadFile"
413
398
  ]);
414
- const loadSlackActionRuntime$1 = createLazyRuntimeModule(() => import("./action-runtime.runtime-D9I6uc0Q.js"));
399
+ const loadSlackActionRuntime$1 = createLazyRuntimeModule(() => import("./action-runtime.runtime-JtoOK9l5.js"));
415
400
  function resolveSlackActionContext(ctx, toolContext) {
416
401
  if (!toolContext && !ctx.mediaAccess && !ctx.mediaLocalRoots && !ctx.mediaReadFile && !ctx.conversationReadOrigin && !ctx.requesterAccountId && !ctx.requesterSenderId) return;
417
402
  return {
@@ -426,6 +411,7 @@ function resolveSlackActionContext(ctx, toolContext) {
426
411
  }
427
412
  function createSlackActions(providerId, options) {
428
413
  return {
414
+ providerOwnedReadGates: true,
429
415
  describeMessageTool: describeSlackMessageTool,
430
416
  extractToolSend: ({ args }) => extractSlackToolSend(args),
431
417
  isToolDeliveryAction: ({ args }) => typeof args.action === "string" && SLACK_TOOL_DELIVERY_ACTIONS.has(args.action),
@@ -464,6 +450,58 @@ function shouldUseWorkspaceAwareSlackActionSend(rawTarget, context) {
464
450
  return false;
465
451
  }
466
452
  //#endregion
453
+ //#region extensions/slack/src/conversation-route-owner.ts
454
+ function inspectSlackConversationRouteOwner(params) {
455
+ const installationKind = getSlackInstallationKind(params.accountId);
456
+ const direct = params.conversation.kind === "direct";
457
+ const target = parseSlackTarget(params.conversation.peerId, { defaultKind: direct ? "user" : "channel" });
458
+ if (!target || target.kind !== (direct ? "user" : "channel")) return null;
459
+ const targetIsEnterprise = Boolean(target.teamId);
460
+ if (!targetIsEnterprise && (installationKind === "degraded" || !installationKind)) return { kind: "unavailable" };
461
+ if (targetIsEnterprise && installationKind === "workspace") return null;
462
+ const contextTeamId = params.conversation.context?.teamId?.trim();
463
+ if (contextTeamId && target.teamId && contextTeamId.toLowerCase() !== target.teamId.toLowerCase()) return null;
464
+ const teamId = contextTeamId ?? target.teamId;
465
+ if (!direct && params.conversation.nativeChannelId && params.conversation.nativeChannelId.toLowerCase() !== target.id.toLowerCase()) return null;
466
+ const enterpriseRoute = installationKind === "enterprise" || targetIsEnterprise;
467
+ if (enterpriseRoute && !teamId) return null;
468
+ const enterpriseScope = enterpriseRoute && teamId ? { teamId } : void 0;
469
+ const route = resolveAgentRoute({
470
+ cfg: normalizeSlackRouteBindingConfig(params.cfg),
471
+ channel: "slack",
472
+ accountId: params.accountId,
473
+ teamId,
474
+ peer: {
475
+ kind: params.conversation.kind,
476
+ id: qualifySlackRoutePeerId({
477
+ id: target.id,
478
+ kind: direct ? "user" : "channel",
479
+ eventScope: enterpriseScope
480
+ })
481
+ }
482
+ });
483
+ const baseConversationId = qualifySlackConversationId(direct ? `user:${target.id}` : target.id, enterpriseScope);
484
+ const bindingRoute = resolveSlackConversationBindingRoute({
485
+ cfg: params.cfg,
486
+ route,
487
+ accountId: params.accountId,
488
+ baseConversationId,
489
+ runtimeBindingThreadId: params.conversation.threadId,
490
+ bindingsEnabled: !enterpriseRoute,
491
+ touchBinding: false
492
+ });
493
+ if (!bindingRoute.runtimeRoute.bindingOwnerAvailable) return { kind: "unavailable" };
494
+ if (bindingRoute.runtimeRoute.pluginId) return {
495
+ kind: "plugin",
496
+ pluginId: bindingRoute.runtimeRoute.pluginId,
497
+ fallbackAgentId: route.agentId
498
+ };
499
+ return {
500
+ kind: "agent",
501
+ agentId: bindingRoute.runtimeRoute.boundAgentId ?? bindingRoute.configuredRoute?.boundAgentId ?? route.agentId
502
+ };
503
+ }
504
+ //#endregion
467
505
  //#region extensions/slack/src/threading-tool-context.ts
468
506
  function buildSlackThreadingToolContext(params) {
469
507
  const account = resolveSlackAccount({
@@ -500,23 +538,23 @@ const EXTENSION_SHARED_MODULE_ID = "openclaw/plugin-sdk/extension-shared";
500
538
  const TARGET_RESOLVER_RUNTIME_MODULE_ID = "openclaw/plugin-sdk/target-resolver-runtime";
501
539
  const loadExtensionSharedSdk = createLazyRuntimeModule(() => import(EXTENSION_SHARED_MODULE_ID));
502
540
  const loadTargetResolverRuntimeSdk = createLazyRuntimeModule(() => import(TARGET_RESOLVER_RUNTIME_MODULE_ID));
503
- const loadSlackSetupSurfaceModule = createLazyRuntimeModule(() => import("./setup-surface-CbX1-Knh.js"));
504
- const loadSlackScopesModule = createLazyRuntimeModule(() => import("./scopes-cYXKkrRD.js"));
505
- const loadSlackOutboundAdapterModule = createLazyRuntimeModule(() => import("./outbound-adapter-S81tsswN.js"));
541
+ const loadSlackSetupSurfaceModule = createLazyRuntimeModule(() => import("./setup-surface-BPFfp6So.js"));
542
+ const loadSlackScopesModule = createLazyRuntimeModule(() => import("./scopes-BSk4GZvZ.js"));
543
+ const loadSlackOutboundAdapterModule = createLazyRuntimeModule(() => import("./outbound-adapter-DuRqAQXK.js"));
506
544
  async function resolveSlackHandleAction() {
507
545
  return getOptionalSlackRuntime()?.channel?.slack?.handleSlackAction ?? (await loadSlackActionRuntime()).handleSlackAction;
508
546
  }
509
547
  function shouldTreatSlackDeliveredTextAsVisible(params) {
510
548
  return params.kind === "block" && typeof params.text === "string" && params.text.trim().length > 0;
511
549
  }
512
- const loadSlackDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-CNBz8lJa.js").then((n) => n.t));
513
- const loadSlackResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-CNPrxaXY.js").then((n) => n.n));
514
- const loadSlackResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-Dzomuwnr.js").then((n) => n.n));
515
- const loadSlackActionRuntime = createLazyRuntimeModule(() => import("./action-runtime.runtime-D9I6uc0Q.js"));
516
- const loadSlackSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-BmgNe6S9.js"));
517
- const loadSlackProbeModule = createLazyRuntimeModule(() => import("./probe-HoEg_WxB.js").then((n) => n.n));
518
- const loadSlackMonitorModule = createLazyRuntimeModule(() => import("./monitor-1nF1NtqT.js").then((n) => n.t));
519
- const loadSlackDirectoryLiveModule = createLazyRuntimeModule(() => import("./directory-live-CFKUtW9E.js").then((n) => n.t));
550
+ const loadSlackDirectoryConfigModule = createLazyRuntimeModule(() => import("./directory-config-BGYyuzWh.js").then((n) => n.t));
551
+ const loadSlackResolveChannelsModule = createLazyRuntimeModule(() => import("./resolve-channels-BSpqC8jU.js").then((n) => n.n));
552
+ const loadSlackResolveUsersModule = createLazyRuntimeModule(() => import("./resolve-users-Dvz9pDe0.js").then((n) => n.n));
553
+ const loadSlackActionRuntime = createLazyRuntimeModule(() => import("./action-runtime.runtime-JtoOK9l5.js"));
554
+ const loadSlackSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-kYctMHSd.js"));
555
+ const loadSlackProbeModule = createLazyRuntimeModule(() => import("./probe-BVA65leh.js").then((n) => n.n));
556
+ const loadSlackMonitorModule = createLazyRuntimeModule(() => import("./monitor-Chrecrb9.js").then((n) => n.t));
557
+ const loadSlackDirectoryLiveModule = createLazyRuntimeModule(() => import("./directory-live-DjUJQLbq.js").then((n) => n.t));
520
558
  async function resolveSlackSendContext(params) {
521
559
  const account = resolveSlackAccount({
522
560
  cfg: params.cfg,
@@ -886,6 +924,7 @@ const slackPlugin = createChatChannelPlugin({
886
924
  },
887
925
  conversationBindings: { isCurrentConversationBindingSupported: ({ accountId }) => isSlackWorkspaceInstallation(accountId) },
888
926
  messaging: {
927
+ resolveConversationRouteOwner: inspectSlackConversationRouteOwner,
889
928
  targetPrefixes: ["slack"],
890
929
  directTargetStyle: "user-prefixed",
891
930
  targetIdComparison: "lowercase",
@@ -1175,4 +1214,4 @@ const slackPlugin = createChatChannelPlugin({
1175
1214
  outbound: slackChannelOutbound
1176
1215
  });
1177
1216
  //#endregion
1178
- export { buildSlackThreadingToolContext as n, resolveSlackAutoThreadId as r, slackPlugin as t };
1217
+ export { buildSlackThreadingToolContext as n, slackPlugin as t };
@@ -1,2 +1,2 @@
1
- import { t as SlackChannelConfigSchema } from "./config-schema-xto5jFIx.js";
1
+ import { t as SlackChannelConfigSchema } from "./config-schema-CN3XZRX5.js";
2
2
  export { SlackChannelConfigSchema };
@@ -1,2 +1,2 @@
1
- import { t as slackPlugin } from "./channel-D_tovcUL.js";
1
+ import { t as slackPlugin } from "./channel-CA5w7qDF.js";
2
2
  export { slackPlugin };
@@ -1,13 +1,12 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { a as resolveSlackAccount, l as resolveSlackOperationToken } from "./accounts-CK4AVI2_.js";
3
- import { p as assertSlackDetachedTargetAllowed, s as normalizeAllowListLower } from "./group-policy-c4RP9bjc.js";
4
- import { a as createSlackReadClient, c as createSlackWebClient } from "./probe-HoEg_WxB.js";
2
+ import { a as resolveSlackAccount, l as resolveSlackOperationToken } from "./accounts-BlzxuYle.js";
3
+ import { g as assertSlackDetachedTargetAllowed, u as normalizeAllowListLower } from "./group-policy-DyfB_ZIE.js";
4
+ import { a as createSlackReadClient, c as createSlackWebClient } from "./probe-BVA65leh.js";
5
5
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { createHash } from "node:crypto";
7
7
  import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
8
8
  //#region extensions/slack/src/channel-type.ts
9
9
  var channel_type_exports = /* @__PURE__ */ __exportAll({
10
- resetSlackChannelTypeCacheForTest: () => resetSlackChannelTypeCacheForTest,
11
10
  resolveSlackChannelType: () => resolveSlackChannelType,
12
11
  resolveSlackConversationInfo: () => resolveSlackConversationInfo
13
12
  });
@@ -102,8 +101,5 @@ async function resolveSlackConversationInfo(params) {
102
101
  async function resolveSlackChannelType(params) {
103
102
  return (await resolveSlackConversationInfo(params)).type;
104
103
  }
105
- function resetSlackChannelTypeCacheForTest() {
106
- SLACK_CONVERSATION_INFO_CACHE.clear();
107
- }
108
104
  //#endregion
109
105
  export { resolveSlackChannelType as n, resolveSlackConversationInfo as r, channel_type_exports as t };
@@ -1,7 +1,7 @@
1
- import { a as resolveSlackAccount, c as resolveSlackConfigAccessorAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds } from "./accounts-CK4AVI2_.js";
2
- import { t as inspectSlackAccount } from "./account-inspect-Drw2gAiN.js";
1
+ import { a as resolveSlackAccount, c as resolveSlackConfigAccessorAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds } from "./accounts-BlzxuYle.js";
2
+ import { t as inspectSlackAccount } from "./account-inspect-YJvFBbCR.js";
3
3
  import { t as isSlackPluginAccountConfigured } from "./account-configured-BwfXBo_F.js";
4
- import { t as SlackChannelConfigSchema } from "./config-schema-xto5jFIx.js";
4
+ import { t as SlackChannelConfigSchema } from "./config-schema-CN3XZRX5.js";
5
5
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
6
6
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
@@ -570,7 +570,7 @@ const slackBaseConfigAdapter = createScopedChannelConfigAdapter({
570
570
  });
571
571
  //#endregion
572
572
  //#region extensions/slack/src/channel.setup.ts
573
- const slackSetupWizard = createSlackSetupWizardProxy(async () => ({ slackSetupWizard: (await import("./setup-surface-CbX1-Knh.js")).slackSetupWizard }));
573
+ const slackSetupWizard = createSlackSetupWizardProxy(async () => ({ slackSetupWizard: (await import("./setup-surface-BPFfp6So.js")).slackSetupWizard }));
574
574
  const slackSetupPlugin = {
575
575
  id: SLACK_CHANNEL,
576
576
  meta: {
@@ -32,7 +32,8 @@ const slackChannelConfigUiHints = {
32
32
  nativeTransport: "Enable native Slack text streaming (chat.startStream/chat.appendStream/chat.stopStream) when channels.slack.streaming.mode is partial (default: true). Native streaming and Slack assistant thread status require a reply thread target; top-level DMs can still use draft post-and-edit preview streaming.",
33
33
  "preview.toolProgress": "Show tool/progress activity in the live draft preview message (default: true). Set false to hide interim tool updates while the draft preview stays active.",
34
34
  "preview.commandText": "Command/exec detail in preview tool-progress lines: \"status\" is the safe default; \"raw\" opts into command text.",
35
- "progress.nativeTaskCards": "Slack native task-card progress updates when channels.slack.streaming.mode=\"progress\" and streaming.nativeTransport is enabled. Set false to fall back to the Block Kit progress card. Default: true."
35
+ "progress.style": "Slack progress presentation: \"card\" (default) uses structured task/session cards; \"compact\" keeps one editable text draft that the final answer replaces in place when Slack can safely edit it.",
36
+ "progress.nativeTaskCards": "Slack native task-card progress updates when channels.slack.streaming.mode=\"progress\", progress.style=\"card\", and streaming.nativeTransport is enabled. Set false to fall back to the Block Kit progress card. Default: true."
36
37
  },
37
38
  progress: { labels: "openclaw" }
38
39
  }),
@@ -104,10 +105,18 @@ const slackChannelConfigUiHints = {
104
105
  label: "Slack Presence Event Mode",
105
106
  help: "\"off\" disables polling; \"auto\" covers DMs, MPIMs, and recent threads with up to 8 observed people; \"on\" also covers larger threads and top-level channels."
106
107
  },
108
+ "presenceEvents.prompt": {
109
+ label: "Slack Presence Event Prompt",
110
+ help: "Replace the default greeting guidance appended after presence facts. Use an empty string to omit event-specific guidance and let workspace instructions such as AGENTS.md govern behavior. Maximum: 20,000 characters."
111
+ },
107
112
  "channels.*.presenceEvents.mode": {
108
113
  label: "Slack Channel Presence Event Mode",
109
114
  help: "Override presence events for one Slack channel. Use \"on\" to include large threads or top-level channel sessions."
110
115
  },
116
+ "channels.*.presenceEvents.prompt": {
117
+ label: "Slack Channel Presence Event Prompt",
118
+ help: "Override the account-level presence-event prompt for one Slack channel. Maximum: 20,000 characters."
119
+ },
111
120
  "execApprovals.enabled": {
112
121
  label: "Slack Exec Approvals Enabled",
113
122
  help: "Controls Slack native exec approvals for this account: unset or \"auto\" enables DM-first native approvals when approvers can be resolved, true forces native approvals on, and false disables them."
@@ -144,7 +153,11 @@ const slackChannelConfigUiHints = {
144
153
  //#endregion
145
154
  //#region extensions/slack/src/config-schema.ts
146
155
  const SecretInputSchema = buildSecretInputSchema();
147
- const SlackStreamingProgressSchema = ChannelStreamingProgressSchema.extend({ nativeTaskCards: z.boolean().optional() }).strict();
156
+ const SLACK_PRESENCE_EVENT_PROMPT_MAX_CHARS = 2e4;
157
+ const SlackStreamingProgressSchema = ChannelStreamingProgressSchema.extend({
158
+ style: z.enum(["card", "compact"]).optional(),
159
+ nativeTaskCards: z.boolean().optional()
160
+ }).strict();
148
161
  const SlackStreamingConfigSchema = ChannelPreviewStreamingConfigSchema.extend({
149
162
  nativeTransport: z.boolean().optional(),
150
163
  progress: SlackStreamingProgressSchema.optional()
@@ -154,11 +167,14 @@ const SlackDmSchema = z.object({
154
167
  groupEnabled: z.boolean().optional(),
155
168
  groupChannels: z.array(z.union([z.string(), z.number()])).optional()
156
169
  }).strict();
157
- const SlackPresenceEventsSchema = z.object({ mode: z.enum([
158
- "off",
159
- "auto",
160
- "on"
161
- ]).optional() }).strict();
170
+ const SlackPresenceEventsSchema = z.object({
171
+ mode: z.enum([
172
+ "off",
173
+ "auto",
174
+ "on"
175
+ ]).optional(),
176
+ prompt: z.string().max(SLACK_PRESENCE_EVENT_PROMPT_MAX_CHARS).optional()
177
+ }).strict();
162
178
  const SlackChannelSchema = buildGroupEntrySchema({
163
179
  ignoreOtherMentions: z.boolean().optional(),
164
180
  replyToMode: ReplyToModeSchema.optional(),
@@ -0,0 +1,115 @@
1
+ import { a as parseSlackTarget } from "./target-parsing-BnMD2ZqZ.js";
2
+ import "./targets-Cx5W_n3W.js";
3
+ import { resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
4
+ //#region extensions/slack/src/account-reply-mode.ts
5
+ function normalizeSlackChatType(raw) {
6
+ const value = raw?.trim().toLowerCase();
7
+ if (!value) return;
8
+ if (value === "direct" || value === "dm") return "direct";
9
+ if (value === "group" || value === "channel") return value;
10
+ }
11
+ function resolveSlackReplyToMode(account, chatType) {
12
+ const normalized = normalizeSlackChatType(chatType ?? void 0);
13
+ if (normalized && account.replyToModeByChatType?.[normalized] !== void 0) return account.replyToModeByChatType[normalized] ?? "off";
14
+ return account.replyToMode ?? "off";
15
+ }
16
+ //#endregion
17
+ //#region extensions/slack/src/conversation-binding-route.ts
18
+ const slackRouteBindingConfigCache = /* @__PURE__ */ new WeakMap();
19
+ function slackTargetDefaultKindForPeer(kind) {
20
+ return kind === "direct" ? "user" : "channel";
21
+ }
22
+ function slackTargetKindMatchesPeer(peerKind, targetKind) {
23
+ if (targetKind === "user") return peerKind === "direct";
24
+ return peerKind === "channel" || peerKind === "group";
25
+ }
26
+ function normalizeSlackRouteBindingPeer(peer) {
27
+ const rawId = peer.id.trim();
28
+ if (!rawId || rawId === "*") return peer;
29
+ const target = (() => {
30
+ try {
31
+ return parseSlackTarget(rawId, { defaultKind: slackTargetDefaultKindForPeer(peer.kind) });
32
+ } catch {
33
+ return;
34
+ }
35
+ })();
36
+ if (!target || !slackTargetKindMatchesPeer(peer.kind, target.kind)) return peer;
37
+ const normalizedId = target.teamId ? `team:${target.teamId}:${target.kind}:${target.id}` : target.id;
38
+ return normalizedId === peer.id ? peer : {
39
+ ...peer,
40
+ id: normalizedId
41
+ };
42
+ }
43
+ function normalizeSlackRouteBindingConfig(cfg) {
44
+ const bindings = cfg.bindings;
45
+ const cached = slackRouteBindingConfigCache.get(cfg);
46
+ if (cached && cached.bindingsRef === bindings) return cached.normalizedCfg;
47
+ if (!Array.isArray(bindings)) return cfg;
48
+ let changed = false;
49
+ const normalizedBindings = bindings.map((binding) => {
50
+ if (binding.type === "acp" || binding.match.channel.trim().toLowerCase() !== "slack") return binding;
51
+ const peer = binding.match.peer;
52
+ if (!peer) return binding;
53
+ const normalizedPeer = normalizeSlackRouteBindingPeer(peer);
54
+ if (normalizedPeer === peer) return binding;
55
+ changed = true;
56
+ return {
57
+ ...binding,
58
+ match: {
59
+ ...binding.match,
60
+ peer: normalizedPeer
61
+ }
62
+ };
63
+ });
64
+ const normalizedCfg = changed ? {
65
+ ...cfg,
66
+ bindings: normalizedBindings
67
+ } : cfg;
68
+ slackRouteBindingConfigCache.set(cfg, {
69
+ bindingsRef: bindings,
70
+ normalizedCfg
71
+ });
72
+ return normalizedCfg;
73
+ }
74
+ function resolveSlackConversationBindingRoute(params) {
75
+ const boundThreadRoute = params.bindingsEnabled && params.runtimeBindingThreadId ? resolveRuntimeConversationBindingRoute({
76
+ route: params.route,
77
+ touchBinding: params.touchBinding,
78
+ conversation: {
79
+ channel: "slack",
80
+ accountId: params.accountId,
81
+ conversationId: params.runtimeBindingThreadId,
82
+ parentConversationId: params.baseConversationId
83
+ }
84
+ }) : null;
85
+ const runtimeRoute = !params.bindingsEnabled ? {
86
+ bindingOwnerAvailable: true,
87
+ route: params.route,
88
+ bindingRecord: null,
89
+ boundSessionKey: void 0
90
+ } : boundThreadRoute?.boundSessionKey || boundThreadRoute?.bindingRecord ? boundThreadRoute : resolveRuntimeConversationBindingRoute({
91
+ route: params.route,
92
+ touchBinding: params.touchBinding,
93
+ conversation: {
94
+ channel: "slack",
95
+ accountId: params.accountId,
96
+ conversationId: params.baseConversationId
97
+ }
98
+ });
99
+ const configuredRoute = params.bindingsEnabled && !runtimeRoute.boundSessionKey && !runtimeRoute.bindingRecord ? resolveConfiguredBindingRoute({
100
+ cfg: params.cfg,
101
+ route: params.route,
102
+ conversation: {
103
+ channel: "slack",
104
+ accountId: params.accountId,
105
+ conversationId: params.baseConversationId
106
+ }
107
+ }) : null;
108
+ return {
109
+ runtimeRoute,
110
+ configuredRoute,
111
+ route: runtimeRoute.boundSessionKey ? runtimeRoute.route : configuredRoute?.route ?? params.route
112
+ };
113
+ }
114
+ //#endregion
115
+ export { resolveSlackConversationBindingRoute as n, resolveSlackReplyToMode as r, normalizeSlackRouteBindingConfig as t };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-CK4AVI2_.js";
2
+ import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-BlzxuYle.js";
3
3
  import { a as parseSlackTarget } from "./target-parsing-BnMD2ZqZ.js";
4
4
  import "./targets-Cx5W_n3W.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-CNBz8lJa.js";
1
+ import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-BGYyuzWh.js";
2
2
  export { listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig };
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { a as resolveSlackAccount } from "./accounts-CK4AVI2_.js";
3
- import { i as createSlackLookupClient } from "./probe-HoEg_WxB.js";
2
+ import { a as resolveSlackAccount } from "./accounts-BlzxuYle.js";
3
+ import { i as createSlackLookupClient } from "./probe-BVA65leh.js";
4
4
  import { t as collectSlackCursorPages } from "./cursor-pages-eX7p8Wwt.js";
5
5
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  //#region extensions/slack/src/directory-live.ts
@@ -1,12 +1,14 @@
1
- import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-CK4AVI2_.js";
1
+ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-BlzxuYle.js";
2
2
  import { a as parseSlackTarget, n as formatSlackTarget, t as canonicalizeSlackApiTargetId } from "./target-parsing-BnMD2ZqZ.js";
3
+ import { t as slackContextTargetsMatch } from "./targets-Cx5W_n3W.js";
3
4
  import { t as isSlackPluginAccountConfigured } from "./account-configured-BwfXBo_F.js";
4
5
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
5
6
  import { asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringifiedOptionalString, readNonBlankString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
7
  import { normalizeMessageChannel } from "openclaw/plugin-sdk/routing";
7
8
  import { FormatCapabilityProfile, chunkTextForOutbound, markdownToIR, renderMarkdownIRChunksWithinLimit, renderMarkdownWithMarkers } from "openclaw/plugin-sdk/text-chunking";
9
+ import { isSingleUseReplyToMode } from "openclaw/plugin-sdk/reply-reference";
8
10
  import { buildChannelKeyCandidates } from "openclaw/plugin-sdk/channel-targets";
9
- import { createNativeApprovalChannelRouteGates, doesApprovalRequestSelectChannelAccount, resolveApprovalRequestSessionConversation } from "openclaw/plugin-sdk/approval-native-runtime";
11
+ import { createNativeApprovalChannelRouteGates, doesApprovalRequestSelectChannelAccount, resolveApprovalKind, resolveApprovalRequestSessionConversation } from "openclaw/plugin-sdk/approval-native-runtime";
10
12
  import { createChannelApprovalAuth, resolveApprovalApprovers } from "openclaw/plugin-sdk/approval-auth-runtime";
11
13
  import { createChannelExecApprovalProfile, isChannelExecApprovalClientEnabledFromConfig, isChannelExecApprovalTargetRecipient, matchesApprovalRequestFilters } from "openclaw/plugin-sdk/approval-client-runtime";
12
14
  import { channelRouteTargetsMatchExact, stringifyRouteThreadId } from "openclaw/plugin-sdk/channel-route";
@@ -21,6 +23,21 @@ import { readResponseTextLimited } from "openclaw/plugin-sdk/provider-http";
21
23
  import { compileAllowlist, resolveCompiledAllowlistMatch } from "openclaw/plugin-sdk/allow-from";
22
24
  import { normalizeHyphenSlug, normalizeStringEntries as normalizeStringEntries$1, normalizeStringEntriesLower } from "openclaw/plugin-sdk/string-normalization-runtime";
23
25
  import { resolveScopeRequireMention, resolveScopeToolsPolicy } from "openclaw/plugin-sdk/channel-policy";
26
+ //#region extensions/slack/src/action-threading.ts
27
+ const SLACK_PRIVATE_ACTION_DELIVERY_RESULT = Symbol("slack.action.delivery-result");
28
+ function resolveSlackAutoThreadId(params) {
29
+ const context = params.toolContext;
30
+ if (!context?.currentChannelId && !context?.currentMessagingTarget) return;
31
+ if (!slackContextTargetsMatch(params.to, context)) return;
32
+ if (!context.currentThreadTs) {
33
+ if (context.sameChannelThreadRequired) throw new Error("Slack thread context is required for same-channel replies from a threaded Slack turn. Set topLevel=true or threadId=null to post at the channel root.");
34
+ return;
35
+ }
36
+ if (context.replyToMode !== "all" && !isSingleUseReplyToMode(context.replyToMode ?? "off")) return;
37
+ if (isSingleUseReplyToMode(context.replyToMode ?? "off") && context.hasRepliedRef?.value) return;
38
+ return context.currentThreadTs;
39
+ }
40
+ //#endregion
24
41
  //#region extensions/slack/src/exec-approvals.ts
25
42
  function normalizeSlackUserLikeId(value) {
26
43
  const upper = value.toUpperCase();
@@ -124,11 +141,6 @@ function isSlackWorkspaceInstallation(accountId) {
124
141
  const DEFAULT_APPROVAL_FORWARDING_MODE = "session";
125
142
  const SLACK_DM_CHANNEL_ID_RE = /^D[A-Z0-9]{8,}$/i;
126
143
  const SLACK_USER_ID_RE = /^[UW][A-Z0-9]{8,}$/i;
127
- function resolveSlackApprovalKind(request) {
128
- const isExec = "command" in request.request;
129
- if (isExec === ("title" in request.request && "description" in request.request)) throw new Error("Slack approval request payload does not identify exactly one owner");
130
- return isExec ? "exec" : "plugin";
131
- }
132
144
  function isSlackApprovalTransportEnabled(params) {
133
145
  return isSlackPluginAccountConfigured(resolveSlackAccount(params));
134
146
  }
@@ -343,7 +355,7 @@ function isSlackAnyNativeApprovalClientEnabled(params) {
343
355
  }
344
356
  function shouldHandleSlackNativeApprovalRequest(params) {
345
357
  if (getSlackInstallationKind(resolveSlackAccount(params).accountId) === "enterprise" && !resolveEnterpriseApprovalTeamId(params.request)) return false;
346
- if ((params.approvalKind ?? resolveSlackApprovalKind(params.request)) === "plugin") return shouldHandleSlackPluginViaNativeClientConfig(params) || shouldHandleSlackPluginViaForwarding(params);
358
+ if (resolveApprovalKind(params.request, params.approvalKind) === "plugin") return shouldHandleSlackPluginViaNativeClientConfig(params) || shouldHandleSlackPluginViaForwarding(params);
347
359
  const turnSourceChannel = normalizeMessageChannel(params.request.request.turnSourceChannel);
348
360
  if (turnSourceChannel && turnSourceChannel !== "slack") return false;
349
361
  if (!doesApprovalRequestSelectChannelAccount({
@@ -426,6 +438,7 @@ const SLACK_PRESENTATION_CAPABILITIES = {
426
438
  //#endregion
427
439
  //#region extensions/slack/src/approval-actions.ts
428
440
  const SLACK_APPROVAL_VALUE_PREFIX = "openclaw:approval:v1:";
441
+ const SLACK_APPROVAL_HEADER_BLOCK_ID = "openclaw_approval_header";
429
442
  function isApprovalDecision(value) {
430
443
  return value === "allow-once" || value === "allow-always" || value === "deny";
431
444
  }
@@ -1824,19 +1837,6 @@ function protectSlackAssistantTranscriptRoleHeaders(text) {
1824
1837
  if (!slackProjectionHasRoleHeader(tokenProjection) && !slackProjectionHasRoleHeader(fallbackProjection)) return text;
1825
1838
  return `${SLACK_ASSISTANT_TRANSCRIPT_PREFIX}${text}`;
1826
1839
  }
1827
- function hardSliceSlackToken(token, limit) {
1828
- const chunks = [];
1829
- let chunk = "";
1830
- for (const character of token) {
1831
- if (chunk && chunk.length + character.length > limit) {
1832
- chunks.push(chunk);
1833
- chunk = "";
1834
- }
1835
- chunk += character;
1836
- }
1837
- if (chunk) chunks.push(chunk);
1838
- return chunks;
1839
- }
1840
1840
  function buildSlackRenderOptions() {
1841
1841
  return {
1842
1842
  annotationMarkers: { assistant_transcript_role: {
@@ -1910,8 +1910,8 @@ function chunkSlackMrkdwnText(text, limit) {
1910
1910
  flush();
1911
1911
  const marker = wrapper();
1912
1912
  if (activeMarker && isAllowedSlackAngleToken(token)) {
1913
- if (marker) chunks.push(...hardSliceSlackToken(token, contentLimit).map((fragment) => `${marker}${fragment}${marker}`));
1914
- else chunks.push(...hardSliceSlackToken(escapeSlackMrkdwnSegment(token), limit));
1913
+ if (marker) chunks.push(...chunkTextForOutbound(token, Math.max(1, Math.floor(contentLimit)), { preserveWhitespace: true }).map((fragment) => `${marker}${fragment}${marker}`));
1914
+ else chunks.push(...chunkTextForOutbound(escapeSlackMrkdwnSegment(token), Math.max(1, Math.floor(limit)), { preserveWhitespace: true }));
1915
1915
  continue;
1916
1916
  }
1917
1917
  chunks.push(...token.length <= limit ? [token] : chunkTextForOutbound(token, limit));
@@ -2473,6 +2473,20 @@ function resolveSlackUserAllowListForTeam(params) {
2473
2473
  });
2474
2474
  }
2475
2475
  //#endregion
2476
+ //#region extensions/slack/src/monitor/workspace-routing.ts
2477
+ function resolveSlackEnterpriseMainDmSessionKey(params) {
2478
+ const accountId = encodeURIComponent(params.accountId).toLowerCase();
2479
+ const teamId = encodeURIComponent(params.eventScope.teamId).toLowerCase();
2480
+ return `${params.baseSessionKey}:account:${accountId}:team:${teamId}`;
2481
+ }
2482
+ function qualifySlackRoutePeerId(params) {
2483
+ if (!params.eventScope) return params.id;
2484
+ return `team:${encodeURIComponent(params.eventScope.teamId)}:${params.kind}:${encodeURIComponent(params.id)}`;
2485
+ }
2486
+ function qualifySlackConversationId(conversationId, eventScope) {
2487
+ return eventScope ? `team:${encodeURIComponent(eventScope.teamId)}:${conversationId}` : conversationId;
2488
+ }
2489
+ //#endregion
2476
2490
  //#region extensions/slack/src/group-policy.ts
2477
2491
  function buildSlackChannelIdCandidates(channelId, teamId, options) {
2478
2492
  const trimmedId = channelId?.trim();
@@ -2524,4 +2538,4 @@ function resolveSlackGroupToolPolicy(params) {
2524
2538
  });
2525
2539
  }
2526
2540
  //#endregion
2527
- export { isSlackCallbackActionId as $, chunkSlackMrkdwnText as A, normalizeSlackApproverId as At, SLACK_TEXT_LIMIT as B, buildSlackNativeDataAccessibilityText as C, isSlackWorkspaceInstallation as Ct, isSlackInvalidBlocksResponse as D, getSlackExecApprovalApprovers as Dt, isSlackInvalidBlocksError as E, isSlackApprovalAuthorizedSender as Et, renderSlackBlockFallbackText as F, truncateSlackText as G, buildSlackPresentationBlocks as H, resolveSlackAuthoredTextPlacement as I, SLACK_REPLY_BUTTON_ACTION_ID as J, truncateSlackTextByUtf8Bytes as K, SLACK_EDIT_TEXT_MAX_BYTES as L, normalizeSlackOutboundText as M, shouldSuppressLocalSlackExecApprovalPrompt as Mt, buildSlackBlocksFallbackText as N, isSlackNativeResponseUrlRejection as O, isSlackExecApprovalAuthorizedSender as Ot, buildSlackCompleteBlocksFallbackText as P, isSlackApprovalActionId as Q, SLACK_MESSAGE_TEXT_HARD_LIMIT as R, appendSlackNativeDataPlainTextFallback as S, getSlackInstallationKind as St, hasSlackNativeDataBlock as T, getSlackApprovalApprovers as Tt, canRenderSlackPresentation as U, buildSlackInteractiveBlocks as V, countSlackTextUtf8Bytes as W, SLACK_REPLY_SELECT_ACTION_ID as X, SLACK_REPLY_LINK_ACTION_ID as Y, SLACK_SESSION_LINK_ACTION_ID as Z, resolveSlackReplyBlocks as _, resolveSlackFallbackOriginTarget as _t, allowListMatches as a, escapeSlackMrkdwn as at, SLACK_MALFORMED_NATIVE_DATA_FALLBACK as b, shouldHandleSlackPluginViaForwardingSession as bt, normalizeSlackAllowOwnerEntry as c, SLACK_MAX_BLOCKS as ct, resolveSlackUserAllowListForTeam as d, hasSlackPluginApprovers as dt, isSlackQuestionActionId as et, resolveSlackUserAllowed as f, isSlackAnyNativeApprovalClientEnabled as ft, resolveSlackReplyBlockResolution as g, resolveSessionSlackOriginTarget as gt, parseSlackReplyBlockSegments as h, resolveEnterpriseApprovalTeamId as ht, resolveSlackGroupToolPolicy as i, renderSlackMessagePresentationFallbackText as it, markdownToSlackMrkdwnChunks as j, resolveSlackExecApprovalTarget as jt, stripSlackNativeDataBlocks as k, isSlackExecApprovalClientEnabled as kt, normalizeSlackSlug as l, parseSlackBlocksInput as lt, hasSlackReplyStructuredContent as m, normalizeSlackOriginTarget as mt, buildSlackChannelPolicyScope as n, decodeSlackQuestionAction as nt, normalizeAllowList as o, decodeSlackApprovalAction as ot, assertSlackDetachedTargetAllowed as p, normalizeSlackForwardTarget as pt, SLACK_QUESTION_FINALIZATION_BLOCKS as q, resolveSlackGroupRequireMention as r, resolveSlackQuestionAction as rt, normalizeAllowListLower as s, SLACK_PRESENTATION_CAPABILITIES as st, buildSlackChannelIdCandidates as t, resolveSlackQuestionActionIds as tt, resolveSlackAllowListMatch as u, validateSlackBlocksArray as ut, resolveSlackReplyDeliveryMessages as v, resolveTurnSourceSlackOriginTarget as vt, createSlackNativeDataBaseTextConsumer as w, registerSlackInstallationState as wt, appendSlackNativeDataFallbackText as x, slackTargetsMatch as xt, resolveSlackReplyRenderPlan as y, shouldHandleSlackNativeApprovalRequest as yt, SLACK_MESSAGE_TEXT_RECOMMENDED_LIMIT as z };
2541
+ export { SLACK_REPLY_SELECT_ACTION_ID as $, isSlackInvalidBlocksResponse as A, isSlackApprovalAuthorizedSender as At, SLACK_EDIT_TEXT_MAX_BYTES as B, SLACK_MALFORMED_NATIVE_DATA_FALLBACK as C, shouldHandleSlackNativeApprovalRequest as Ct, createSlackNativeDataBaseTextConsumer as D, isSlackWorkspaceInstallation as Dt, buildSlackNativeDataAccessibilityText as E, getSlackInstallationKind as Et, normalizeSlackOutboundText as F, resolveSlackExecApprovalTarget as Ft, buildSlackPresentationBlocks as G, SLACK_MESSAGE_TEXT_RECOMMENDED_LIMIT as H, buildSlackBlocksFallbackText as I, shouldSuppressLocalSlackExecApprovalPrompt as It, truncateSlackText as J, canRenderSlackPresentation as K, buildSlackCompleteBlocksFallbackText as L, SLACK_PRIVATE_ACTION_DELIVERY_RESULT as Lt, stripSlackNativeDataBlocks as M, isSlackExecApprovalAuthorizedSender as Mt, chunkSlackMrkdwnText as N, isSlackExecApprovalClientEnabled as Nt, hasSlackNativeDataBlock as O, registerSlackInstallationState as Ot, markdownToSlackMrkdwnChunks as P, normalizeSlackApproverId as Pt, SLACK_REPLY_LINK_ACTION_ID as Q, renderSlackBlockFallbackText as R, resolveSlackAutoThreadId as Rt, resolveSlackReplyRenderPlan as S, resolveTurnSourceSlackOriginTarget as St, appendSlackNativeDataPlainTextFallback as T, slackTargetsMatch as Tt, SLACK_TEXT_LIMIT as U, SLACK_MESSAGE_TEXT_HARD_LIMIT as V, buildSlackInteractiveBlocks as W, SLACK_QUESTION_FINALIZATION_BLOCKS as X, truncateSlackTextByUtf8Bytes as Y, SLACK_REPLY_BUTTON_ACTION_ID as Z, hasSlackReplyStructuredContent as _, normalizeSlackForwardTarget as _t, qualifySlackConversationId as a, decodeSlackQuestionAction as at, resolveSlackReplyBlocks as b, resolveSessionSlackOriginTarget as bt, allowListMatches as c, escapeSlackMrkdwn as ct, normalizeSlackAllowOwnerEntry as d, SLACK_PRESENTATION_CAPABILITIES as dt, SLACK_SESSION_LINK_ACTION_ID as et, normalizeSlackSlug as f, SLACK_MAX_BLOCKS as ft, assertSlackDetachedTargetAllowed as g, isSlackAnyNativeApprovalClientEnabled as gt, resolveSlackUserAllowed as h, hasSlackPluginApprovers as ht, resolveSlackGroupToolPolicy as i, resolveSlackQuestionActionIds as it, isSlackNativeResponseUrlRejection as j, getSlackExecApprovalApprovers as jt, isSlackInvalidBlocksError as k, getSlackApprovalApprovers as kt, normalizeAllowList as l, SLACK_APPROVAL_HEADER_BLOCK_ID as lt, resolveSlackUserAllowListForTeam as m, validateSlackBlocksArray as mt, buildSlackChannelPolicyScope as n, isSlackCallbackActionId as nt, qualifySlackRoutePeerId as o, resolveSlackQuestionAction as ot, resolveSlackAllowListMatch as p, parseSlackBlocksInput as pt, countSlackTextUtf8Bytes as q, resolveSlackGroupRequireMention as r, isSlackQuestionActionId as rt, resolveSlackEnterpriseMainDmSessionKey as s, renderSlackMessagePresentationFallbackText as st, buildSlackChannelIdCandidates as t, isSlackApprovalActionId as tt, normalizeAllowListLower as u, decodeSlackApprovalAction as ut, parseSlackReplyBlockSegments as v, normalizeSlackOriginTarget as vt, appendSlackNativeDataFallbackText as w, shouldHandleSlackPluginViaForwardingSession as wt, resolveSlackReplyDeliveryMessages as x, resolveSlackFallbackOriginTarget as xt, resolveSlackReplyBlockResolution as y, resolveEnterpriseApprovalTeamId as yt, resolveSlackAuthoredTextPlacement as z };
@@ -1,5 +1,5 @@
1
- import { n as listSlackAccountIds } from "./accounts-CK4AVI2_.js";
2
- import { t as inspectSlackAccount } from "./account-inspect-Drw2gAiN.js";
1
+ import { n as listSlackAccountIds } from "./accounts-BlzxuYle.js";
2
+ import { t as inspectSlackAccount } from "./account-inspect-YJvFBbCR.js";
3
3
  import { n as resolveSlackThreadTsValue, t as normalizeSlackThreadTsCandidate } from "./thread-ts-DUGhaYKq.js";
4
4
  import { createActionGate } from "openclaw/plugin-sdk/channel-actions";
5
5
  import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
@@ -1,2 +1,2 @@
1
- import { t as describeSlackMessageTool } from "./message-tool-api-BykQB4AU.js";
1
+ import { t as describeSlackMessageTool } from "./message-tool-api-CqMr5Rmc.js";
2
2
  export { describeSlackMessageTool as describeMessageTool };