@openclaw/slack 2026.7.2-beta.3 → 2026.7.2-beta.4

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 (152) hide show
  1. package/dist/account-inspect-api.js +1 -1
  2. package/dist/{account-inspect-Bvbtu3iH.js → account-inspect-jn1xLaVi.js} +2 -2
  3. package/dist/account-reply-mode-DrUXogvO.js +14 -0
  4. package/dist/{accounts-DQEbYKh9.js → accounts-BSr252c_.js} +6 -27
  5. package/dist/{accounts.runtime-BIKmJdtJ.js → accounts.runtime-CjULMLTa.js} +1 -1
  6. package/dist/{action-runtime-DqkRwO3Z.js → action-runtime-CFU52n4W.js} +7 -7
  7. package/dist/action-runtime.runtime-9-17zvKH.js +2 -0
  8. package/dist/{actions-CF0tUY5q.js → actions-D51foiwR.js} +5 -5
  9. package/dist/{actions.runtime-hCbx4RXg.js → actions.runtime-BMJwtf5C.js} +1 -1
  10. package/dist/api.js +15 -14
  11. package/dist/{approval-handler.runtime-Em8I1-8-.js → approval-handler.runtime-3b4-wxMl.js} +2 -2
  12. package/dist/{channel-4-TRi1D6.js → channel-Ds8NKvfr.js} +26 -24
  13. package/dist/channel-config-api.js +1 -1
  14. package/dist/channel-plugin-api.js +1 -1
  15. package/dist/{channel-type-Cu1yjNg2.js → channel-type-DXkUajFP.js} +3 -3
  16. package/dist/{channel.setup-CgkADtZg.js → channel.setup-DOSTEDfA.js} +6 -5
  17. package/dist/{config-schema-XjJGfwQC.js → config-schema-B4j4tCOI.js} +231 -26
  18. package/dist/{directory-config-Bv0lcUlH.js → directory-config-B08pm5ZT.js} +1 -1
  19. package/dist/directory-contract-api.js +1 -1
  20. package/dist/{directory-live-CzUIB7th.js → directory-live-DpPKzPrn.js} +2 -2
  21. package/dist/{doctor-contract-DKpe5VBr.js → doctor-contract-U6oVntbM.js} +60 -89
  22. package/dist/doctor-contract-api.js +1 -1
  23. package/dist/{group-policy-Bw-65m3V.js → group-policy-CdnQzQBI.js} +32 -5
  24. package/dist/{interactive-replies-Dm_t2R9S.js → interactive-replies-C3ffk6oN.js} +1 -1
  25. package/dist/interactive-replies-api.js +1 -1
  26. package/dist/{message-tool-api-C2pcf5du.js → message-tool-api-ByVyIVOh.js} +2 -2
  27. package/dist/message-tool-api.js +1 -1
  28. package/dist/{monitor-CNFeF30h.js → monitor-CnB_WKvF.js} +3 -3
  29. package/dist/{outbound-adapter-CVi2uok0.js → outbound-adapter-DuPz2HHt.js} +3 -3
  30. package/dist/{pipeline.runtime-CTvokbty.js → pipeline.runtime-5rRYZuX5.js} +110 -77
  31. package/dist/{policy-b_dOPDCq.js → policy-C31RYSuT.js} +1 -1
  32. package/dist/{probe-Borhn9PQ.js → probe-CVRuArHA.js} +1 -1
  33. package/dist/{provider-B-HVL5ZE.js → provider-htuIJGFD.js} +365 -200
  34. package/dist/{relay-source-Ea_P9VcO.js → relay-source-Df9EaiTF.js} +1 -1
  35. package/dist/{replies-B4bOdrYb.js → replies-Cgr2Gli4.js} +3 -3
  36. package/dist/{resolve-channels-KTc568SU.js → resolve-channels-DodP2TFx.js} +1 -1
  37. package/dist/{resolve-users-DeGJf1yp.js → resolve-users-M9eF8891.js} +1 -1
  38. package/dist/{runtime-api-BFfNpzDe.js → runtime-api-D5XYMMsf.js} +3 -2
  39. package/dist/runtime-api.js +11 -11
  40. package/dist/{scopes-lx08L56K.js → scopes-CJRpHkDC.js} +1 -1
  41. package/dist/{security-audit-CikQhBUY.js → security-audit-Cz6erklv.js} +0 -10
  42. package/dist/security-contract-api.js +1 -1
  43. package/dist/{send-KuTDky7i.js → send-BZ1tPv7-.js} +4 -4
  44. package/dist/{send.runtime-CXyxws1D.js → send.runtime-a2pilFor.js} +1 -1
  45. package/dist/{setup-core-CeiAVwQ3.js → setup-core-tPxMuFez.js} +138 -40
  46. package/dist/setup-plugin-api.js +1 -1
  47. package/dist/{setup-surface-DLA0vHXp.js → setup-surface-wV-S1dE_.js} +43 -27
  48. package/dist/{shared-C4yVB0Q-.js → shared-BfMskaMx.js} +9 -8
  49. package/dist/{slash-dispatch.runtime-BT-mMm-f.js → slash-dispatch.runtime-lfeIsXTX.js} +1 -1
  50. package/node_modules/@types/node/README.md +1 -1
  51. package/node_modules/@types/node/fs/promises.d.ts +16 -6
  52. package/node_modules/@types/node/package.json +2 -2
  53. package/node_modules/agent-base/README.md +145 -0
  54. package/node_modules/agent-base/dist/src/index.d.ts +78 -0
  55. package/node_modules/agent-base/dist/src/index.js +203 -0
  56. package/node_modules/agent-base/dist/src/index.js.map +1 -0
  57. package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
  58. package/node_modules/agent-base/dist/src/promisify.js +18 -0
  59. package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
  60. package/node_modules/agent-base/package.json +64 -0
  61. package/node_modules/agent-base/src/index.ts +345 -0
  62. package/node_modules/agent-base/src/promisify.ts +33 -0
  63. package/node_modules/axios/CHANGELOG.md +197 -1
  64. package/node_modules/axios/README.md +424 -256
  65. package/node_modules/axios/dist/axios.js +589 -204
  66. package/node_modules/axios/dist/axios.min.js +3 -3
  67. package/node_modules/axios/dist/axios.min.js.map +1 -1
  68. package/node_modules/axios/dist/browser/axios.cjs +630 -185
  69. package/node_modules/axios/dist/esm/axios.js +630 -185
  70. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  71. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  72. package/node_modules/axios/dist/node/axios.cjs +949 -301
  73. package/node_modules/axios/index.d.cts +28 -5
  74. package/node_modules/axios/index.d.ts +24 -3
  75. package/node_modules/axios/lib/adapters/adapters.js +1 -1
  76. package/node_modules/axios/lib/adapters/fetch.js +223 -49
  77. package/node_modules/axios/lib/adapters/http.js +408 -193
  78. package/node_modules/axios/lib/adapters/xhr.js +3 -1
  79. package/node_modules/axios/lib/core/Axios.js +4 -2
  80. package/node_modules/axios/lib/core/AxiosError.js +13 -1
  81. package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
  82. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  83. package/node_modules/axios/lib/core/mergeConfig.js +35 -0
  84. package/node_modules/axios/lib/defaults/transitional.js +2 -0
  85. package/node_modules/axios/lib/env/data.js +1 -1
  86. package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -3
  87. package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
  88. package/node_modules/axios/lib/helpers/buildURL.js +7 -4
  89. package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
  90. package/node_modules/axios/lib/helpers/cookies.js +5 -1
  91. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  92. package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
  93. package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
  94. package/node_modules/axios/lib/helpers/fromDataURI.js +20 -5
  95. package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
  96. package/node_modules/axios/lib/helpers/resolveConfig.js +26 -13
  97. package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
  98. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  99. package/node_modules/axios/lib/helpers/toFormData.js +48 -12
  100. package/node_modules/axios/lib/helpers/validator.js +1 -1
  101. package/node_modules/axios/lib/utils.js +105 -19
  102. package/node_modules/axios/package.json +31 -13
  103. package/node_modules/https-proxy-agent/README.md +137 -0
  104. package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
  105. package/node_modules/https-proxy-agent/dist/agent.js +177 -0
  106. package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
  107. package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
  108. package/node_modules/https-proxy-agent/dist/index.js +14 -0
  109. package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
  110. package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
  111. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
  112. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
  113. package/node_modules/https-proxy-agent/package.json +56 -0
  114. package/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
  115. package/node_modules/iconv-lite/encodings/utf32.js +10 -3
  116. package/node_modules/iconv-lite/package.json +2 -2
  117. package/node_modules/iconv-lite/types/encodings.d.ts +2 -0
  118. package/node_modules/path-to-regexp/Readme.md +3 -3
  119. package/node_modules/path-to-regexp/dist/index.js +135 -158
  120. package/node_modules/path-to-regexp/dist/index.js.map +1 -1
  121. package/node_modules/path-to-regexp/package.json +2 -2
  122. package/node_modules/qs/CHANGELOG.md +11 -0
  123. package/node_modules/qs/dist/qs.js +17 -17
  124. package/node_modules/qs/lib/parse.js +19 -8
  125. package/node_modules/qs/lib/utils.js +47 -8
  126. package/node_modules/qs/package.json +6 -5
  127. package/node_modules/qs/test/parse.js +230 -0
  128. package/node_modules/qs/test/utils.js +194 -0
  129. package/node_modules/typebox/build/compile/validator.d.mts +1 -4
  130. package/node_modules/typebox/build/guard/guard.d.mts +1 -1
  131. package/node_modules/typebox/build/guard/guard.mjs +5 -2
  132. package/node_modules/typebox/build/guard/string.mjs +16 -4
  133. package/node_modules/typebox/build/schema/engine/_functions.mjs +34 -15
  134. package/node_modules/typebox/build/type/action/readonly_object.d.mts +5 -0
  135. package/node_modules/typebox/build/type/action/readonly_object.mjs +8 -0
  136. package/node_modules/typebox/build/typebox.d.mts +1 -1
  137. package/node_modules/typebox/build/typebox.mjs +1 -1
  138. package/node_modules/typebox/package.json +1 -1
  139. package/node_modules/typebox/readme.md +29 -32
  140. package/node_modules/ws/lib/receiver.js +15 -32
  141. package/node_modules/ws/lib/websocket-server.js +4 -4
  142. package/node_modules/ws/lib/websocket.js +4 -4
  143. package/node_modules/ws/package.json +5 -1
  144. package/npm-shrinkwrap.json +54 -27
  145. package/openclaw.plugin.json +1759 -1908
  146. package/package.json +92 -14
  147. package/dist/action-runtime.runtime-DEWOcFM4.js +0 -2
  148. package/dist/config-api-Df9a1B8C.js +0 -3
  149. package/node_modules/axios/dist/axios.js.map +0 -1
  150. package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
  151. package/node_modules/axios/dist/esm/axios.js.map +0 -1
  152. package/node_modules/axios/dist/node/axios.cjs.map +0 -1
@@ -1,8 +1,9 @@
1
- import { n as buildChannelConfigSchema, t as SlackConfigSchema } from "./config-api-Df9a1B8C.js";
1
+ import { buildSecretInputSchema, hasConfiguredSecretInput } from "openclaw/plugin-sdk/secret-input";
2
2
  import { createChannelConfigUiHints } from "openclaw/plugin-sdk/channel-core";
3
- //#endregion
4
- //#region extensions/slack/src/config-schema.ts
5
- const SlackChannelConfigSchema = buildChannelConfigSchema(SlackConfigSchema, { uiHints: {
3
+ import { ChannelBotLoopProtectionSchema, ChannelDangerouslyAllowNameMatchingSchema, ChannelImplicitMentionsSchema, ChannelPreviewStreamingConfigSchema, ChannelStreamingProgressSchema, GroupPolicySchema, ProviderCommandsSchema, ReplyToModeSchema, buildChannelAllowBotsSchema, buildChannelConfigSchema, buildChannelExecApprovalsSchema, buildChannelReactionShape, buildCommonChannelAccountShape, buildGroupEntrySchema, requireAllowlistAllowFrom, requireOpenAllowFrom } from "openclaw/plugin-sdk/channel-config-schema";
4
+ import { z } from "zod";
5
+ //#region extensions/slack/src/config-ui-hints.ts
6
+ const slackChannelConfigUiHints = {
6
7
  "": {
7
8
  label: "Slack",
8
9
  help: "Slack channel provider configuration for bot/app tokens, streaming behavior, and DM policy controls. Keep token handling and thread behavior explicit to avoid noisy workspace interactions."
@@ -11,16 +12,13 @@ const SlackChannelConfigSchema = buildChannelConfigSchema(SlackConfigSchema, { u
11
12
  label: "Slack Enterprise Grid Org Install",
12
13
  help: "Enable only for an Enterprise Grid org-wide bot installation. OpenClaw verifies the token with Slack auth.test at startup; DMs must be disabled or use dmPolicy=\"open\" with allowFrom=[\"*\"]."
13
14
  },
14
- identity: {
15
+ postAs: {
15
16
  label: "Slack Identity",
16
17
  help: "Select \"bot\" (default) for the classic Slack app/bot identity or \"user\" to post as the authorizing human through a user token while the app carries event transport."
17
18
  },
18
19
  ...createChannelConfigUiHints({
19
20
  channelLabel: "Slack",
20
- dmPolicy: {
21
- channelKey: "slack",
22
- includeLegacyNestedPolicy: true
23
- },
21
+ dmPolicy: { channelKey: "slack" },
24
22
  configWrites: true,
25
23
  mentionPatterns: {
26
24
  targetDescription: "Slack channel IDs",
@@ -54,22 +52,6 @@ const SlackChannelConfigSchema = buildChannelConfigSchema(SlackConfigSchema, { u
54
52
  label: "Slack Bot Loop Cooldown Seconds",
55
53
  help: "How long to suppress the bot pair after it exceeds the budget. Default: 60."
56
54
  },
57
- socketMode: {
58
- label: "Slack Socket Mode Transport",
59
- help: "Slack Socket Mode transport tuning passed to the Slack SDK. Use only when investigating ping/pong timeout or stale websocket behavior."
60
- },
61
- "socketMode.clientPingTimeout": {
62
- label: "Slack Socket Mode Pong Timeout",
63
- help: "Milliseconds the Slack SDK waits for a pong after its client ping before treating the websocket as stale (OpenClaw default: 15000). Increase on hosts with event-loop starvation or slow network scheduling."
64
- },
65
- "socketMode.serverPingTimeout": {
66
- label: "Slack Socket Mode Server Ping Timeout",
67
- help: "Milliseconds the Slack SDK waits for Slack server pings before treating the websocket as stale."
68
- },
69
- "socketMode.pingPongLoggingEnabled": {
70
- label: "Slack Socket Mode Ping/Pong Logging",
71
- help: "Enable Slack SDK ping/pong transport logs while debugging Socket Mode websocket health."
72
- },
73
55
  relay: {
74
56
  label: "Slack Relay Mode",
75
57
  help: "Relay-delivered Slack events. Use with mode=\"relay\" when openclaw-slack-router owns the Slack Socket Mode connection."
@@ -218,6 +200,229 @@ const SlackChannelConfigSchema = buildChannelConfigSchema(SlackConfigSchema, { u
218
200
  label: "Slack Thread Initial History Limit",
219
201
  help: "Maximum number of existing Slack thread messages to fetch when starting a new thread session (default: 20, set to 0 to disable)."
220
202
  }
221
- } });
203
+ };
204
+ //#endregion
205
+ //#region extensions/slack/src/config-schema.ts
206
+ const SecretInputSchema = buildSecretInputSchema();
207
+ const SlackStreamingProgressSchema = ChannelStreamingProgressSchema.extend({ nativeTaskCards: z.boolean().optional() }).strict();
208
+ const SlackStreamingConfigSchema = ChannelPreviewStreamingConfigSchema.extend({
209
+ nativeTransport: z.boolean().optional(),
210
+ progress: SlackStreamingProgressSchema.optional()
211
+ }).strict();
212
+ const SlackCapabilitiesSchema = z.union([z.array(z.string()), z.object({ interactiveReplies: z.boolean().optional() }).strict()]);
213
+ const SlackDmSchema = z.object({
214
+ enabled: z.boolean().optional(),
215
+ groupEnabled: z.boolean().optional(),
216
+ groupChannels: z.array(z.union([z.string(), z.number()])).optional()
217
+ }).strict();
218
+ const SlackPresenceEventsSchema = z.object({ mode: z.enum([
219
+ "off",
220
+ "auto",
221
+ "on"
222
+ ]).optional() }).strict();
223
+ const SlackChannelSchema = buildGroupEntrySchema({
224
+ ignoreOtherMentions: z.boolean().optional(),
225
+ replyToMode: ReplyToModeSchema.optional(),
226
+ allowBots: buildChannelAllowBotsSchema({ allowMentions: true }),
227
+ botLoopProtection: ChannelBotLoopProtectionSchema.optional(),
228
+ users: z.array(z.union([z.string(), z.number()])).optional(),
229
+ presenceEvents: SlackPresenceEventsSchema.optional()
230
+ }, { omit: ["allowFrom"] });
231
+ const SlackThreadSchema = z.object({
232
+ historyScope: z.enum(["thread", "channel"]).optional(),
233
+ inheritParent: z.boolean().optional(),
234
+ initialHistoryLimit: z.number().int().min(0).optional()
235
+ }).strict();
236
+ const ReplyToModeByChatTypeSchema = z.object({
237
+ direct: ReplyToModeSchema.optional(),
238
+ group: ReplyToModeSchema.optional(),
239
+ channel: ReplyToModeSchema.optional()
240
+ }).strict();
241
+ const SlackRelaySchema = z.object({
242
+ url: z.string().optional(),
243
+ authToken: SecretInputSchema.optional(),
244
+ gatewayId: z.string().optional()
245
+ }).strict();
246
+ const SlackIdentitySchema = z.enum(["bot", "user"]);
247
+ const SlackAccountSchema = z.object({
248
+ ...buildCommonChannelAccountShape({
249
+ omit: ["groupAllowFrom"],
250
+ capabilities: SlackCapabilitiesSchema.optional(),
251
+ streaming: SlackStreamingConfigSchema.optional()
252
+ }),
253
+ postAs: SlackIdentitySchema.default("bot"),
254
+ mode: z.enum([
255
+ "socket",
256
+ "http",
257
+ "relay"
258
+ ]).optional(),
259
+ enterpriseOrgInstall: z.boolean().optional(),
260
+ relay: SlackRelaySchema.optional(),
261
+ signingSecret: SecretInputSchema.optional(),
262
+ webhookPath: z.string().optional(),
263
+ execApprovals: buildChannelExecApprovalsSchema(z.union([z.string(), z.number()])),
264
+ commands: ProviderCommandsSchema,
265
+ botToken: SecretInputSchema.optional(),
266
+ appToken: SecretInputSchema.optional(),
267
+ userToken: SecretInputSchema.optional(),
268
+ userTokenReadOnly: z.boolean().optional().default(true),
269
+ allowBots: buildChannelAllowBotsSchema({ allowMentions: true }),
270
+ botLoopProtection: ChannelBotLoopProtectionSchema.optional(),
271
+ dangerouslyAllowNameMatching: ChannelDangerouslyAllowNameMatchingSchema,
272
+ requireMention: z.boolean().optional(),
273
+ implicitMentions: ChannelImplicitMentionsSchema.optional(),
274
+ unfurlLinks: z.boolean().optional(),
275
+ unfurlMedia: z.boolean().optional(),
276
+ ...buildChannelReactionShape({
277
+ notificationModes: [
278
+ "off",
279
+ "own",
280
+ "all",
281
+ "allowlist"
282
+ ],
283
+ reactionAllowlist: true,
284
+ ackReaction: z.string().optional()
285
+ }),
286
+ replyToModeByChatType: ReplyToModeByChatTypeSchema.optional(),
287
+ thread: SlackThreadSchema.optional(),
288
+ presenceEvents: SlackPresenceEventsSchema.optional(),
289
+ actions: z.object({
290
+ reactions: z.boolean().optional(),
291
+ messages: z.boolean().optional(),
292
+ pins: z.boolean().optional(),
293
+ search: z.boolean().optional(),
294
+ permissions: z.boolean().optional(),
295
+ memberInfo: z.boolean().optional(),
296
+ channelInfo: z.boolean().optional(),
297
+ emojiList: z.boolean().optional()
298
+ }).strict().optional(),
299
+ slashCommand: z.object({
300
+ enabled: z.boolean().optional(),
301
+ name: z.string().optional(),
302
+ sessionPrefix: z.string().optional(),
303
+ ephemeral: z.boolean().optional()
304
+ }).strict().optional(),
305
+ dm: SlackDmSchema.optional(),
306
+ channels: z.record(z.string(), SlackChannelSchema.optional()).optional(),
307
+ typingReaction: z.string().optional()
308
+ }).strict();
309
+ const SlackAccountEntrySchema = SlackAccountSchema.extend({ postAs: SlackIdentitySchema.optional() });
310
+ function validateSlackSigningSecretRequirements(value, ctx) {
311
+ const resolveMode = (mode) => mode === "http" || mode === "socket" || mode === "relay" ? mode : void 0;
312
+ const baseMode = resolveMode(value.mode) ?? "socket";
313
+ if (baseMode === "http" && !hasConfiguredSecretInput(value.signingSecret)) ctx.addIssue({
314
+ code: z.ZodIssueCode.custom,
315
+ message: "channels.slack.mode=\"http\" requires channels.slack.signingSecret",
316
+ path: ["signingSecret"]
317
+ });
318
+ for (const [accountId, account] of Object.entries(value.accounts ?? {})) {
319
+ if (!account || account.enabled === false) continue;
320
+ if ((resolveMode(account.mode) ?? baseMode) !== "http") continue;
321
+ if (!hasConfiguredSecretInput(account.signingSecret ?? value.signingSecret)) ctx.addIssue({
322
+ code: z.ZodIssueCode.custom,
323
+ message: "channels.slack.accounts.*.mode=\"http\" requires channels.slack.signingSecret or channels.slack.accounts.*.signingSecret",
324
+ path: [
325
+ "accounts",
326
+ accountId,
327
+ "signingSecret"
328
+ ]
329
+ });
330
+ }
331
+ }
332
+ const SlackChannelConfigSchema = buildChannelConfigSchema(SlackAccountSchema.safeExtend({
333
+ mode: z.enum([
334
+ "socket",
335
+ "http",
336
+ "relay"
337
+ ]).optional().default("socket"),
338
+ signingSecret: SecretInputSchema.optional(),
339
+ webhookPath: z.string().optional().default("/slack/events"),
340
+ groupPolicy: GroupPolicySchema.optional().default("allowlist"),
341
+ accounts: z.record(z.string(), SlackAccountEntrySchema.optional()).optional(),
342
+ defaultAccount: z.string().optional()
343
+ }).superRefine((value, ctx) => {
344
+ const dmPolicy = value.dmPolicy ?? "pairing";
345
+ const allowFrom = value.allowFrom;
346
+ requireOpenAllowFrom({
347
+ policy: dmPolicy,
348
+ allowFrom,
349
+ ctx,
350
+ path: ["allowFrom"],
351
+ message: "channels.slack.dmPolicy=\"open\" requires channels.slack.allowFrom to include \"*\""
352
+ });
353
+ requireAllowlistAllowFrom({
354
+ policy: dmPolicy,
355
+ allowFrom,
356
+ ctx,
357
+ path: ["allowFrom"],
358
+ message: "channels.slack.dmPolicy=\"allowlist\" requires channels.slack.allowFrom to contain at least one sender ID"
359
+ });
360
+ const requireRelayConfig = (relay, path) => {
361
+ if (typeof relay?.url !== "string" || !relay.url.trim()) ctx.addIssue({
362
+ code: z.ZodIssueCode.custom,
363
+ message: "channels.slack.mode=\"relay\" requires relay.url",
364
+ path: [...path, "url"]
365
+ });
366
+ if (!hasConfiguredSecretInput(relay?.authToken)) ctx.addIssue({
367
+ code: z.ZodIssueCode.custom,
368
+ message: "channels.slack.mode=\"relay\" requires relay.authToken",
369
+ path: [...path, "authToken"]
370
+ });
371
+ if (typeof relay?.gatewayId !== "string" || !relay.gatewayId.trim()) ctx.addIssue({
372
+ code: z.ZodIssueCode.custom,
373
+ message: "channels.slack.mode=\"relay\" requires relay.gatewayId",
374
+ path: [...path, "gatewayId"]
375
+ });
376
+ };
377
+ const baseMode = value.mode ?? "socket";
378
+ const accountIds = value.accounts ? Object.keys(value.accounts) : [];
379
+ if (!value.accounts) {
380
+ if (baseMode === "relay") requireRelayConfig(value.relay, ["relay"]);
381
+ validateSlackSigningSecretRequirements(value, ctx);
382
+ return;
383
+ }
384
+ for (const accountId of accountIds) {
385
+ const account = value.accounts[accountId];
386
+ if (!account || account.enabled === false) continue;
387
+ const accountMode = account.mode ?? baseMode;
388
+ const effectiveRelay = {
389
+ ...value.relay,
390
+ ...account.relay
391
+ };
392
+ const effectivePolicy = account.dmPolicy ?? value.dmPolicy ?? "pairing";
393
+ const effectiveAllowFrom = account.allowFrom ?? value.allowFrom;
394
+ requireOpenAllowFrom({
395
+ policy: effectivePolicy,
396
+ allowFrom: effectiveAllowFrom,
397
+ ctx,
398
+ path: [
399
+ "accounts",
400
+ accountId,
401
+ "allowFrom"
402
+ ],
403
+ message: "channels.slack.accounts.*.dmPolicy=\"open\" requires channels.slack.accounts.*.allowFrom (or channels.slack.allowFrom) to include \"*\""
404
+ });
405
+ requireAllowlistAllowFrom({
406
+ policy: effectivePolicy,
407
+ allowFrom: effectiveAllowFrom,
408
+ ctx,
409
+ path: [
410
+ "accounts",
411
+ accountId,
412
+ "allowFrom"
413
+ ],
414
+ message: "channels.slack.accounts.*.dmPolicy=\"allowlist\" requires channels.slack.accounts.*.allowFrom (or channels.slack.allowFrom) to contain at least one sender ID"
415
+ });
416
+ if (accountMode !== "http") {
417
+ if (accountMode === "relay") requireRelayConfig(effectiveRelay, [
418
+ "accounts",
419
+ accountId,
420
+ "relay"
421
+ ]);
422
+ continue;
423
+ }
424
+ }
425
+ validateSlackSigningSecretRequirements(value, ctx);
426
+ }), { uiHints: slackChannelConfigUiHints });
222
427
  //#endregion
223
428
  export { SlackChannelConfigSchema as t };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-DQEbYKh9.js";
2
+ import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-BSr252c_.js";
3
3
  import { i as parseSlackTarget } from "./target-parsing-N6lHogYZ.js";
4
4
  import "./targets-KmjP2E8s.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-Bv0lcUlH.js";
1
+ import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-B08pm5ZT.js";
2
2
  export { listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig };
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { a as resolveSlackAccount } from "./accounts-DQEbYKh9.js";
3
- import { a as createSlackLookupClient } from "./probe-Borhn9PQ.js";
2
+ import { a as resolveSlackAccount } from "./accounts-BSr252c_.js";
3
+ import { a as createSlackLookupClient } from "./probe-CVRuArHA.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,5 +1,5 @@
1
1
  import { n as resolveSlackNativeStreaming, r as resolveSlackStreamingMode } from "./streaming-compat-3_X-21wW.js";
2
- import { asObjectRecord, defineChannelAliasMigration } from "openclaw/plugin-sdk/runtime-doctor";
2
+ import { asObjectRecord, defineChannelAliasMigration, hasLegacyAccountStreamingAliases, normalizeChannelConfigEntries } from "openclaw/plugin-sdk/runtime-doctor";
3
3
  //#region extensions/slack/src/doctor-contract.ts
4
4
  const streamingAliasMigration = defineChannelAliasMigration({
5
5
  channelId: "slack",
@@ -22,6 +22,21 @@ function hasLegacySlackThreadMentionPolicy(value) {
22
22
  const thread = asObjectRecord(asObjectRecord(value)?.thread);
23
23
  return Boolean(thread && Object.hasOwn(thread, "requireExplicitMention"));
24
24
  }
25
+ function hasLegacyDmReplyMode(value) {
26
+ return Object.hasOwn(asObjectRecord(asObjectRecord(value)?.dm) ?? {}, "replyToMode");
27
+ }
28
+ function migrateDmReplyMode(entry, path, changes) {
29
+ const dm = asObjectRecord(entry.dm);
30
+ if (!dm || !Object.hasOwn(dm, "replyToMode")) return false;
31
+ const byType = asObjectRecord(entry.replyToModeByChatType) ?? {};
32
+ if (byType.direct === void 0) {
33
+ byType.direct = dm.replyToMode;
34
+ entry.replyToModeByChatType = byType;
35
+ changes.push(`Moved ${path}.dm.replyToMode → ${path}.replyToModeByChatType.direct.`);
36
+ } else changes.push(`Removed ${path}.dm.replyToMode (replyToModeByChatType.direct already set).`);
37
+ delete dm.replyToMode;
38
+ return true;
39
+ }
25
40
  function normalizeSlackThreadMentionPolicy(params) {
26
41
  const thread = asObjectRecord(params.value.thread);
27
42
  if (!thread || !Object.hasOwn(thread, "requireExplicitMention")) return {
@@ -69,6 +84,20 @@ function normalizeSlackChannelAllowAliases(params) {
69
84
  }
70
85
  const legacyConfigRules = [
71
86
  ...streamingAliasMigration.legacyConfigRules,
87
+ {
88
+ path: ["channels", "slack"],
89
+ message: "channels.slack.dm.replyToMode moved to replyToModeByChatType.direct. Run \"openclaw doctor --fix\".",
90
+ match: hasLegacyDmReplyMode
91
+ },
92
+ {
93
+ path: [
94
+ "channels",
95
+ "slack",
96
+ "accounts"
97
+ ],
98
+ message: "channels.slack.accounts.<id>.dm.replyToMode moved to replyToModeByChatType.direct. Run \"openclaw doctor --fix\".",
99
+ match: (value) => hasLegacyAccountStreamingAliases(value, hasLegacyDmReplyMode)
100
+ },
72
101
  {
73
102
  path: ["channels", "slack"],
74
103
  message: "channels.slack.thread.requireExplicitMention is legacy; use channels.slack.implicitMentions.threadParticipation instead. Run \"openclaw doctor --fix\".",
@@ -81,10 +110,7 @@ const legacyConfigRules = [
81
110
  "accounts"
82
111
  ],
83
112
  message: "channels.slack.accounts.<id>.thread.requireExplicitMention is legacy; use channels.slack.accounts.<id>.implicitMentions.threadParticipation instead. Run \"openclaw doctor --fix\".",
84
- match: (value) => {
85
- const accounts = asObjectRecord(value);
86
- return Boolean(accounts && Object.values(accounts).some((account) => hasLegacySlackThreadMentionPolicy(account)));
87
- }
113
+ match: (value) => hasLegacyAccountStreamingAliases(value, hasLegacySlackThreadMentionPolicy)
88
114
  },
89
115
  {
90
116
  path: ["channels", "slack"],
@@ -98,105 +124,50 @@ const legacyConfigRules = [
98
124
  "accounts"
99
125
  ],
100
126
  message: "channels.slack.accounts.<id>.channels.<id>.allow is legacy; use channels.slack.accounts.<id>.channels.<id>.enabled instead. Run \"openclaw doctor --fix\".",
101
- match: (value) => {
102
- const accounts = asObjectRecord(value);
103
- if (!accounts) return false;
104
- return Object.values(accounts).some((account) => hasLegacySlackChannelAllowAlias(account));
105
- }
127
+ match: (value) => hasLegacyAccountStreamingAliases(value, hasLegacySlackChannelAllowAlias)
106
128
  }
107
129
  ];
108
- function normalizeCompatibilityConfig({ cfg }) {
109
- const changes = [];
110
- const aliases = streamingAliasMigration.normalizeChannelConfig({
111
- cfg,
112
- changes
130
+ function normalizeSlackEntry(params) {
131
+ let entry = params.entry;
132
+ let changed = migrateDmReplyMode(entry, params.pathPrefix, params.changes);
133
+ const threadPolicy = normalizeSlackThreadMentionPolicy({
134
+ value: entry,
135
+ pathPrefix: params.pathPrefix,
136
+ changes: params.changes
113
137
  });
114
- const rawEntry = asObjectRecord(aliases.config.channels?.slack);
115
- if (!rawEntry) return {
116
- config: cfg,
117
- changes: []
118
- };
119
- let updated = rawEntry;
120
- let changed = aliases.config !== cfg;
121
- const normalizedThreadPolicy = normalizeSlackThreadMentionPolicy({
122
- value: updated,
123
- pathPrefix: "channels.slack",
124
- changes
125
- });
126
- if (normalizedThreadPolicy.changed) {
127
- updated = normalizedThreadPolicy.value;
128
- changed = true;
129
- }
130
- const channels = asObjectRecord(updated.channels);
138
+ entry = threadPolicy.value;
139
+ changed = changed || threadPolicy.changed;
140
+ const channels = asObjectRecord(entry.channels);
131
141
  if (channels) {
132
142
  const normalized = normalizeSlackChannelAllowAliases({
133
143
  channels,
134
- pathPrefix: "channels.slack.channels",
135
- changes
144
+ pathPrefix: `${params.pathPrefix}.channels`,
145
+ changes: params.changes
136
146
  });
137
147
  if (normalized.changed) {
138
- updated = {
139
- ...updated,
148
+ entry = {
149
+ ...entry,
140
150
  channels: normalized.channels
141
151
  };
142
152
  changed = true;
143
153
  }
144
154
  }
145
- const accounts = asObjectRecord(updated.accounts);
146
- if (accounts) {
147
- let accountsChanged = false;
148
- const nextAccounts = { ...accounts };
149
- for (const [accountId, accountValue] of Object.entries(accounts)) {
150
- let account = asObjectRecord(accountValue);
151
- if (!account) continue;
152
- const normalizedAccountThreadPolicy = normalizeSlackThreadMentionPolicy({
153
- value: account,
154
- pathPrefix: `channels.slack.accounts.${accountId}`,
155
- changes
156
- });
157
- if (normalizedAccountThreadPolicy.changed) {
158
- account = normalizedAccountThreadPolicy.value;
159
- nextAccounts[accountId] = account;
160
- accountsChanged = true;
161
- }
162
- const channelEntries = asObjectRecord(account.channels);
163
- if (channelEntries) {
164
- const normalized = normalizeSlackChannelAllowAliases({
165
- channels: channelEntries,
166
- pathPrefix: `channels.slack.accounts.${accountId}.channels`,
167
- changes
168
- });
169
- if (normalized.changed) {
170
- nextAccounts[accountId] = {
171
- ...account,
172
- channels: normalized.channels
173
- };
174
- accountsChanged = true;
175
- }
176
- }
177
- }
178
- if (accountsChanged) {
179
- updated = {
180
- ...updated,
181
- accounts: nextAccounts
182
- };
183
- changed = true;
184
- }
185
- }
186
- if (!changed) return {
187
- config: cfg,
188
- changes: []
189
- };
190
155
  return {
191
- config: {
192
- ...aliases.config,
193
- channels: {
194
- ...aliases.config.channels,
195
- slack: updated
196
- }
197
- },
198
- changes
156
+ entry,
157
+ changed
199
158
  };
200
159
  }
160
+ function normalizeCompatibilityConfig({ cfg }) {
161
+ const changes = [];
162
+ return normalizeChannelConfigEntries({
163
+ cfg: streamingAliasMigration.normalizeChannelConfig({
164
+ cfg,
165
+ changes
166
+ }).config,
167
+ channelId: "slack",
168
+ changes,
169
+ normalizeEntry: normalizeSlackEntry
170
+ });
171
+ }
201
172
  //#endregion
202
173
  export { normalizeCompatibilityConfig as n, legacyConfigRules as t };
@@ -1,2 +1,2 @@
1
- import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DKpe5VBr.js";
1
+ import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-U6oVntbM.js";
2
2
  export { legacyConfigRules, normalizeCompatibilityConfig };
@@ -1,4 +1,4 @@
1
- import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-DQEbYKh9.js";
1
+ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-BSr252c_.js";
2
2
  import { i as parseSlackTarget, t as canonicalizeSlackApiTargetId } from "./target-parsing-N6lHogYZ.js";
3
3
  import { t as isSlackPluginAccountConfigured } from "./account-configured-BwfXBo_F.js";
4
4
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
@@ -1512,6 +1512,33 @@ function buildSlackLink(link, text) {
1512
1512
  close: ">"
1513
1513
  };
1514
1514
  }
1515
+ const SLACK_FORMAT_PROFILE = {
1516
+ mechanism: "markdown",
1517
+ constructs: {
1518
+ bold: "native",
1519
+ italic: "native",
1520
+ underline: "strip",
1521
+ strikethrough: "native",
1522
+ spoiler: "fallback",
1523
+ codeInline: "native",
1524
+ codeBlock: "native",
1525
+ codeLanguage: "fallback",
1526
+ linkLabel: "native",
1527
+ heading: "fallback",
1528
+ bulletList: "fallback",
1529
+ orderedList: "fallback",
1530
+ taskList: "fallback",
1531
+ table: "fallback",
1532
+ blockquote: "native",
1533
+ image: "fallback",
1534
+ mention: "native"
1535
+ },
1536
+ chunk: {
1537
+ limit: 4e3,
1538
+ unit: "chars",
1539
+ hardCap: 4e4
1540
+ }
1541
+ };
1515
1542
  const SLACK_ASSISTANT_TRANSCRIPT_PREFIX = "`Assistant:` ";
1516
1543
  function tokenizeSlackMrkdwn(text) {
1517
1544
  const tokens = [];
@@ -1698,10 +1725,10 @@ function markdownToSlackMrkdwn(markdown, options = {}) {
1698
1725
  assistantTranscriptRoleHeaders: true,
1699
1726
  linkify: false,
1700
1727
  autolink: false,
1701
- headingStyle: "bold",
1728
+ headingStyle: "rich",
1702
1729
  blockquotePrefix: "> ",
1703
1730
  tableMode: options.tableMode
1704
- }), buildSlackRenderOptions());
1731
+ }), buildSlackRenderOptions(), SLACK_FORMAT_PROFILE);
1705
1732
  }
1706
1733
  function normalizeSlackOutboundText(markdown) {
1707
1734
  return protectSlackAssistantTranscriptRoleHeaders(markdownToSlackMrkdwn(markdown ?? ""));
@@ -1751,7 +1778,7 @@ function markdownToSlackMrkdwnChunks(markdown, limit, options = {}) {
1751
1778
  assistantTranscriptRoleHeaders: true,
1752
1779
  linkify: false,
1753
1780
  autolink: false,
1754
- headingStyle: "bold",
1781
+ headingStyle: "rich",
1755
1782
  blockquotePrefix: "> ",
1756
1783
  tableMode: options.tableMode
1757
1784
  });
@@ -1759,7 +1786,7 @@ function markdownToSlackMrkdwnChunks(markdown, limit, options = {}) {
1759
1786
  return renderMarkdownIRChunksWithinLimit({
1760
1787
  ir,
1761
1788
  limit,
1762
- renderChunk: (chunk) => protectSlackAssistantTranscriptRoleHeaders(renderMarkdownWithMarkers(chunk, renderOptions)),
1789
+ renderChunk: (chunk) => protectSlackAssistantTranscriptRoleHeaders(renderMarkdownWithMarkers(chunk, renderOptions, SLACK_FORMAT_PROFILE)),
1763
1790
  measureRendered: (rendered) => rendered.length
1764
1791
  }).map(({ rendered }) => rendered);
1765
1792
  }
@@ -1,4 +1,4 @@
1
- import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId } from "./accounts-DQEbYKh9.js";
1
+ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId } from "./accounts-BSr252c_.js";
2
2
  import { normalizeLowercaseStringOrEmpty, normalizeStringEntries, normalizeStringEntriesLower } 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-Dm_t2R9S.js";
1
+ import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-C3ffk6oN.js";
2
2
  export { compileSlackInteractiveReplies, isSlackInteractiveRepliesEnabled };
@@ -1,6 +1,6 @@
1
- import { a as resolveSlackAccount, t as listEnabledSlackAccounts } from "./accounts-DQEbYKh9.js";
1
+ import { a as resolveSlackAccount, t as listEnabledSlackAccounts } from "./accounts-BSr252c_.js";
2
2
  import { n as resolveSlackThreadTsValue, t as normalizeSlackThreadTsCandidate } from "./thread-ts-DUGhaYKq.js";
3
- import { n as isSlackInteractiveRepliesEnabled } from "./interactive-replies-Dm_t2R9S.js";
3
+ import { n as isSlackInteractiveRepliesEnabled } from "./interactive-replies-C3ffk6oN.js";
4
4
  import { createActionGate } from "openclaw/plugin-sdk/channel-actions";
5
5
  import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
6
6
  import { Type } from "typebox";
@@ -1,2 +1,2 @@
1
- import { t as describeSlackMessageTool } from "./message-tool-api-C2pcf5du.js";
1
+ import { t as describeSlackMessageTool } from "./message-tool-api-ByVyIVOh.js";
2
2
  export { describeSlackMessageTool as describeMessageTool };
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { S as buildSlackSlashCommandMatcher, t as monitorSlackProvider } from "./provider-B-HVL5ZE.js";
3
- import { t as isSlackChannelAllowedByPolicy } from "./policy-b_dOPDCq.js";
4
- import { o as resolveSlackThreadTs } from "./replies-B4bOdrYb.js";
2
+ import { S as buildSlackSlashCommandMatcher, t as monitorSlackProvider } from "./provider-htuIJGFD.js";
3
+ import { t as isSlackChannelAllowedByPolicy } from "./policy-C31RYSuT.js";
4
+ import { o as resolveSlackThreadTs } from "./replies-Cgr2Gli4.js";
5
5
  //#region extensions/slack/src/monitor.ts
6
6
  var monitor_exports = /* @__PURE__ */ __exportAll({
7
7
  buildSlackSlashCommandMatcher: () => buildSlackSlashCommandMatcher,
@@ -1,6 +1,6 @@
1
- import { F as SLACK_TEXT_LIMIT, M as resolveSlackAuthoredTextPlacement, Y as escapeSlackMrkdwn, Z as SLACK_PRESENTATION_CAPABILITIES, g as resolveSlackReplyDeliveryMessages, m as resolveSlackReplyBlockResolution, p as parseSlackReplyBlockSegments } from "./group-policy-Bw-65m3V.js";
1
+ import { F as SLACK_TEXT_LIMIT, M as resolveSlackAuthoredTextPlacement, Y as escapeSlackMrkdwn, Z as SLACK_PRESENTATION_CAPABILITIES, g as resolveSlackReplyDeliveryMessages, m as resolveSlackReplyBlockResolution, p as parseSlackReplyBlockSegments } from "./group-policy-CdnQzQBI.js";
2
2
  import { n as resolveSlackThreadTsValue } from "./thread-ts-DUGhaYKq.js";
3
- import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-Dm_t2R9S.js";
3
+ import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-C3ffk6oN.js";
4
4
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
6
6
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
@@ -10,7 +10,7 @@ import { resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextM
10
10
  import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
11
11
  //#region extensions/slack/src/outbound-adapter.ts
12
12
  const SLACK_RENDERED_PRESENTATION_PROVENANCE = Object.freeze({});
13
- const loadSlackSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-CXyxws1D.js"));
13
+ const loadSlackSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-a2pilFor.js"));
14
14
  function resolveSlackSendIdentity(identity) {
15
15
  if (!identity) return;
16
16
  const username = normalizeOptionalString(identity.name);