@openclaw/slack 2026.10.1 → 2026.10.5-beta.1

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 (195) hide show
  1. package/dist/.setup/account-configured-zcR9TJJN.mjs +35 -0
  2. package/dist/.setup/{account-inspect-Cs-7DXXW.mjs → account-inspect-D58VVDjk.mjs} +15 -35
  3. package/dist/.setup/{accounts-CDgkV7Cm.mjs → accounts-BMg9YLIv.mjs} +44 -53
  4. package/dist/.setup/{action-runtime-DJ1daRAZ.mjs → action-runtime-BiRZNsIG.mjs} +20 -22
  5. package/dist/.setup/action-runtime.runtime-C5xceJoS.mjs +2 -0
  6. package/dist/.setup/{actions-DDoAJnrH.mjs → actions-KGKwTAKO.mjs} +34 -43
  7. package/dist/.setup/{approval-handler.runtime-BcE_shWc.mjs → approval-handler.runtime-DYrsG2Ox.mjs} +44 -70
  8. package/dist/.setup/{approval-message-updates-EgKGmFXx.mjs → approval-message-updates-CwdDew9i.mjs} +1 -1
  9. package/dist/.setup/{channel-DgKSu8Iv.mjs → channel-C7MY-Hhg.mjs} +138 -97
  10. package/dist/.setup/{channel-type-B9zYYzBU.mjs → channel-type-NjX2SwvS.mjs} +3 -3
  11. package/dist/.setup/{channel.setup-BYIlwbQ7.mjs → channel.setup-BFpQowO3.mjs} +7 -14
  12. package/dist/.setup/{directory-config-B_by7zrc.mjs → directory-config-BEDZPfDn.mjs} +1 -1
  13. package/dist/.setup/{directory-live-C48wazJt.mjs → directory-live-FipfeCwt.mjs} +33 -36
  14. package/dist/.setup/{message-tool-api-CcjLPN3v.mjs → message-tool-api-C7im5ETh.mjs} +2 -2
  15. package/dist/.setup/{monitor-BuYBDmm7.mjs → monitor-BnN2px0N.mjs} +609 -801
  16. package/dist/.setup/{outbound-adapter-BZFkK-mw.mjs → outbound-adapter-4HdGq-8r.mjs} +4 -4
  17. package/dist/.setup/{pipeline.runtime-CIepKmZt.mjs → pipeline.runtime-ByPbC6MN.mjs} +287 -365
  18. package/dist/.setup/{policy-KKTqEiDv.mjs → policy-BaY9_eh1.mjs} +2 -2
  19. package/dist/.setup/{probe-BVlJ3dp0.mjs → probe-CyX52GtD.mjs} +54 -61
  20. package/dist/.setup/{relay-source-CC3h6M7y.mjs → relay-source-CVfH-fBO.mjs} +28 -45
  21. package/dist/.setup/{replies-DHbuthIR.mjs → replies-WmfwvQxc.mjs} +38 -49
  22. package/dist/.setup/{reply-blocks-CKnO4BSG.mjs → reply-blocks-rqHQ_3pr.mjs} +87 -138
  23. package/dist/.setup/{resolve-channels-HR0TgArR.mjs → resolve-channels-B96cgprw.mjs} +17 -41
  24. package/dist/.setup/{resolve-users-BNYBhF0q.mjs → resolve-users-Xz9aPdns.mjs} +22 -58
  25. package/dist/.setup/{scopes-DrDbyUH2.mjs → scopes-aMcMHhXk.mjs} +1 -1
  26. package/dist/.setup/{send-CgPI3Zj8.mjs → send-CLmsR42r.mjs} +157 -284
  27. package/dist/.setup/{session-status-D46GHwOV.mjs → session-status-CcXe10zN.mjs} +181 -238
  28. package/dist/.setup/{setup-plugin-api-ZrHs0N4U.mjs → setup-plugin-api-D92P5p51.mjs} +1 -1
  29. package/dist/.setup/{setup-surface-83lxvE2y.mjs → setup-surface-368jx6Uc.mjs} +6 -6
  30. package/dist/.setup/{shared-VtmYNj-v.mjs → shared-CtprVh_G.mjs} +5 -5
  31. package/dist/.setup/{slash-dispatch.runtime-gBj_uaLM.mjs → slash-dispatch.runtime-Dzwj6TPI.mjs} +1 -1
  32. package/dist/account-inspect-api.js +1 -1
  33. package/dist/api.js +12 -12
  34. package/dist/channel-plugin-api.js +1 -1
  35. package/dist/configured-state.js +6 -13
  36. package/dist/directory-contract-api.js +1 -1
  37. package/dist/message-tool-api.js +1 -1
  38. package/dist/runtime-api.js +10 -10
  39. package/dist/setup-entry.js +1 -1
  40. package/dist/setup-plugin-api.js +1 -1
  41. package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts +1 -1
  42. package/node_modules/@slack/types/dist/block-kit/block-elements.d.ts.map +1 -1
  43. package/node_modules/@slack/types/dist/block-kit/blocks.d.ts +79 -4
  44. package/node_modules/@slack/types/dist/block-kit/blocks.d.ts.map +1 -1
  45. package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts +17 -0
  46. package/node_modules/@slack/types/dist/block-kit/composition-objects.d.ts.map +1 -1
  47. package/node_modules/@slack/types/package.json +1 -1
  48. package/node_modules/@slack/web-api/dist/methods.d.ts +49 -2
  49. package/node_modules/@slack/web-api/dist/methods.d.ts.map +1 -1
  50. package/node_modules/@slack/web-api/dist/methods.js +47 -0
  51. package/node_modules/@slack/web-api/dist/methods.js.map +1 -1
  52. package/node_modules/@slack/web-api/dist/types/request/agents.d.ts +186 -0
  53. package/node_modules/@slack/web-api/dist/types/request/agents.d.ts.map +1 -1
  54. package/node_modules/@slack/web-api/dist/types/request/index.d.ts +1 -1
  55. package/node_modules/@slack/web-api/dist/types/request/index.d.ts.map +1 -1
  56. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsArchiveResponse.d.ts +9 -0
  57. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsArchiveResponse.d.ts.map +1 -0
  58. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsArchiveResponse.js +11 -0
  59. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsArchiveResponse.js.map +1 -0
  60. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsCreateResponse.d.ts +10 -0
  61. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsCreateResponse.d.ts.map +1 -0
  62. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsCreateResponse.js +11 -0
  63. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsCreateResponse.js.map +1 -0
  64. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsGetCanvasResponse.d.ts +29 -0
  65. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsGetCanvasResponse.d.ts.map +1 -0
  66. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsGetCanvasResponse.js +11 -0
  67. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsGetCanvasResponse.js.map +1 -0
  68. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsListViewsResponse.d.ts +18 -0
  69. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsListViewsResponse.d.ts.map +1 -0
  70. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsListViewsResponse.js +11 -0
  71. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsListViewsResponse.js.map +1 -0
  72. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsRemoveViewResponse.d.ts +11 -0
  73. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsRemoveViewResponse.d.ts.map +1 -0
  74. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsRemoveViewResponse.js +11 -0
  75. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsRemoveViewResponse.js.map +1 -0
  76. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCanvasContentResponse.d.ts +11 -0
  77. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCanvasContentResponse.d.ts.map +1 -0
  78. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCanvasContentResponse.js +11 -0
  79. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCanvasContentResponse.js.map +1 -0
  80. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCommandsResponse.d.ts +11 -0
  81. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCommandsResponse.d.ts.map +1 -0
  82. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCommandsResponse.js +11 -0
  83. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetCommandsResponse.js.map +1 -0
  84. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetPropertiesResponse.d.ts +10 -0
  85. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetPropertiesResponse.d.ts.map +1 -0
  86. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetPropertiesResponse.js +11 -0
  87. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetPropertiesResponse.js.map +1 -0
  88. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetViewResponse.d.ts +15 -0
  89. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetViewResponse.d.ts.map +1 -0
  90. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetViewResponse.js +11 -0
  91. package/node_modules/@slack/web-api/dist/types/response/AgentsConversationsSetViewResponse.js.map +1 -0
  92. package/node_modules/@slack/web-api/dist/types/response/ConversationsInfoResponse.d.ts +31 -0
  93. package/node_modules/@slack/web-api/dist/types/response/ConversationsInfoResponse.d.ts.map +1 -1
  94. package/node_modules/@slack/web-api/dist/types/response/index.d.ts +9 -0
  95. package/node_modules/@slack/web-api/dist/types/response/index.d.ts.map +1 -1
  96. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/LICENSE +21 -0
  97. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/README.md +15 -0
  98. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/assert/strict.d.ts +68 -0
  99. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/assert.d.ts +1077 -0
  100. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/async_hooks.d.ts +711 -0
  101. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/buffer.buffer.d.ts +471 -0
  102. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/buffer.d.ts +1800 -0
  103. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/child_process.d.ts +1361 -0
  104. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/cluster.d.ts +432 -0
  105. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/console.d.ts +93 -0
  106. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/constants.d.ts +14 -0
  107. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/crypto.d.ts +3964 -0
  108. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/dgram.d.ts +652 -0
  109. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/diagnostics_channel.d.ts +794 -0
  110. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/dns/promises.d.ts +497 -0
  111. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/dns.d.ts +876 -0
  112. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/domain.d.ts +150 -0
  113. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/events.d.ts +1008 -0
  114. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ffi.d.ts +500 -0
  115. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/fs/promises.d.ts +1477 -0
  116. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/fs.d.ts +4803 -0
  117. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/globals.d.ts +150 -0
  118. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/globals.typedarray.d.ts +101 -0
  119. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/http.d.ts +2218 -0
  120. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/http2.d.ts +2498 -0
  121. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/https.d.ts +400 -0
  122. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/index.d.ts +116 -0
  123. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/inspector/promises.d.ts +35 -0
  124. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/inspector.d.ts +265 -0
  125. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/inspector.generated.d.ts +4406 -0
  126. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/module.d.ts +726 -0
  127. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/net.d.ts +1074 -0
  128. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/os.d.ts +498 -0
  129. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/package.json +155 -0
  130. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/path/posix.d.ts +8 -0
  131. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/path/win32.d.ts +8 -0
  132. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/path.d.ts +178 -0
  133. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/perf_hooks.d.ts +617 -0
  134. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/process.d.ts +2269 -0
  135. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/punycode.d.ts +89 -0
  136. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/querystring.d.ts +139 -0
  137. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/quic.d.ts +2191 -0
  138. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/readline/promises.d.ts +158 -0
  139. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/readline.d.ts +508 -0
  140. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/repl.d.ts +420 -0
  141. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/sea.d.ts +47 -0
  142. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/sqlite.d.ts +1140 -0
  143. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream/consumers.d.ts +114 -0
  144. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream/iter.d.ts +449 -0
  145. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream/promises.d.ts +211 -0
  146. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream/web.d.ts +320 -0
  147. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/stream.d.ts +1806 -0
  148. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/string_decoder.d.ts +27 -0
  149. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/test/reporters.d.ts +60 -0
  150. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/test.d.ts +2558 -0
  151. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/timers/promises.d.ts +93 -0
  152. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/timers.d.ts +149 -0
  153. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/tls.d.ts +1232 -0
  154. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/trace_events.d.ts +103 -0
  155. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +467 -0
  156. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
  157. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
  158. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.6/index.d.ts +118 -0
  159. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
  160. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/ts5.7/index.d.ts +118 -0
  161. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/tty.d.ts +226 -0
  162. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/url.d.ts +556 -0
  163. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/util/types.d.ts +558 -0
  164. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/util.d.ts +1677 -0
  165. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/v8.d.ts +1059 -0
  166. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/vfs.d.ts +211 -0
  167. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/vm.d.ts +1137 -0
  168. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/wasi.d.ts +131 -0
  169. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/abortcontroller.d.ts +59 -0
  170. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/blob.d.ts +23 -0
  171. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/console.d.ts +9 -0
  172. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/crypto.d.ts +39 -0
  173. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/domexception.d.ts +83 -0
  174. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/encoding.d.ts +11 -0
  175. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/events.d.ts +106 -0
  176. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/fetch.d.ts +69 -0
  177. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/importmeta.d.ts +13 -0
  178. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/messaging.d.ts +23 -0
  179. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
  180. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/performance.d.ts +45 -0
  181. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  182. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/streams.d.ts +119 -0
  183. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/timers.d.ts +44 -0
  184. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/web-globals/url.d.ts +24 -0
  185. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/worker_threads.d.ts +672 -0
  186. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/zlib/iter.d.ts +131 -0
  187. package/node_modules/@slack/web-api/node_modules/@slack/logger/node_modules/@types/node/zlib.d.ts +606 -0
  188. package/node_modules/@slack/web-api/node_modules/@types/node/README.md +2 -2
  189. package/node_modules/@slack/web-api/node_modules/@types/node/package.json +2 -17
  190. package/node_modules/@slack/web-api/package.json +2 -2
  191. package/openclaw.plugin.json +0 -3
  192. package/package.json +6 -14
  193. package/dist/.setup/account-configured-sUohAxZr.mjs +0 -33
  194. package/dist/.setup/action-runtime.runtime-CdWL2mLC.mjs +0 -2
  195. package/dist/control-ui/2f4b1e827be6b68ced2ea0d8b7da8529a4eafbe72be27ee37e1064bdd530ec10/index.js +0 -1
@@ -1,20 +1,20 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
2
  import { n as registerSlackHttpHandler, r as normalizeSlackWebhookPath } from "./registry-CIbMfuf8.mjs";
3
- import { a as mergeSlackAccountConfig, c as resolveSlackAccountAllowFrom, f as resolveSlackReplyToMode, h as resolveSlackBotToken, l as resolveSlackAccountDmPolicy, m as resolveSlackAppToken, o as resolveDefaultSlackAccountId, p as formatSlackBotTokenIdentityWarning, s as resolveSlackAccount } from "./accounts-CDgkV7Cm.mjs";
3
+ import { a as mergeSlackAccountConfig, c as resolveSlackAccountAllowFrom, f as resolveSlackReplyToMode, h as resolveSlackBotToken, l as resolveSlackAccountDmPolicy, m as resolveSlackAppToken, o as resolveDefaultSlackAccountId, p as formatSlackBotTokenIdentityWarning, s as resolveSlackAccount } from "./accounts-BMg9YLIv.mjs";
4
4
  import { a as parseSlackTarget, n as formatSlackTarget } from "./target-parsing-FFE26kOV.mjs";
5
- import { B as isSlackApprovalActionId, H as isSlackQuestionActionId, K as resolveSlackQuestionAction, Mt as registerSlackInstallationState, Ot as isSlackPluginApprovalAuthorizedSender, Pt as isSlackExecApprovalAuthorizedSender, V as isSlackCallbackActionId, W as decodeSlackQuestionAction, c as qualifySlackRoutePeerId, ct as decodeSlackApprovalAction, d as resolveSlackConversationBindingRoute, gt as isSlackAnyNativeApprovalClientEnabled, j as truncateSlackText, k as SLACK_TEXT_LIMIT, l as resolveSlackEnterpriseMainDmSessionKey, n as setSlackSessionStatus, ot as escapeSlackMrkdwn, r as buildSlackChannelIdCandidates, s as qualifySlackConversationId, t as renameSlackSession, u as normalizeSlackRouteBindingConfig } from "./session-status-D46GHwOV.mjs";
6
- import { A as resolveSlackUserAllowListForTeam, C as resolveSlackMonitorDispatchers, D as normalizeSlackAllowOwnerEntry, E as allowListMatches, O as normalizeSlackSlug, S as resolveSlackLookupClientOptions, a as slackIngressIdentity, c as collectSlackCursorPages, f as createSlackStartupAuthClient, g as getSlackListenerWriteClient, i as createSlackIngressSubject, k as resolveSlackAllowListMatch, m as createSlackWebClient, o as formatSlackError, v as readLruMapEntry, w as resolveSlackWebClientOptions, y as writeLruMapEntry } from "./probe-BVlJ3dp0.mjs";
5
+ import { A as SLACK_TEXT_LIMIT, Dt as isSlackPluginApprovalAuthorizedSender, G as decodeSlackQuestionAction, H as isSlackCallbackActionId, M as truncateSlackText, Nt as isSlackExecApprovalAuthorizedSender, U as isSlackQuestionActionId, V as isSlackApprovalActionId, at as escapeSlackMrkdwn, c as qualifySlackRoutePeerId, d as resolveSlackConversationBindingRoute, ht as isSlackAnyNativeApprovalClientEnabled, jt as registerSlackInstallationState, l as resolveSlackAgentRoute, n as setSlackSessionStatus, q as resolveSlackQuestionAction, r as buildSlackChannelIdCandidates, s as qualifySlackConversationId, st as decodeSlackApprovalAction, t as renameSlackSession, u as normalizeSlackRouteBindingConfig } from "./session-status-CcXe10zN.mjs";
6
+ import { A as resolveSlackAllowListMatch, C as resolveSlackLookupClientOptions, D as allowListMatches, O as normalizeSlackAllowOwnerEntry, T as resolveSlackWebClientOptions, a as slackIngressIdentity, b as writeLruMapEntry, c as collectSlackCursorPages, f as createSlackStartupAuthClient, g as getSlackListenerWriteClient, i as createSlackIngressSubject, j as resolveSlackUserAllowListForTeam, k as normalizeSlackSlug, m as createSlackWebClient, o as formatSlackError, v as pruneExpiredMapEntries, w as resolveSlackMonitorDispatchers, y as readLruMapEntry } from "./probe-CyX52GtD.mjs";
7
7
  import { n as getSlackRuntime, t as getOptionalSlackRuntime } from "./runtime-JSVZSWAj.mjs";
8
8
  import { t as DEFAULT_SLACK_SUGGESTED_PROMPTS } from "./channel-meta-C443t-lI.mjs";
9
- import { S as hasSlackMessageTableBlock, f as readSlackMessages, v as isGovSlackClient, y as saveRemoteMedia } from "./actions-DDoAJnrH.mjs";
10
- import { d as requireSlackPostMessageTimestamp, f as buildSlackMessageIdentityPayload, r as setSlackDefaultSendIdentity } from "./send-CgPI3Zj8.mjs";
11
- import { n as resolveSlackChannelConfig, r as resolveSlackChannelLabel, t as isSlackChannelAllowedByPolicy } from "./policy-KKTqEiDv.mjs";
12
- import { t as resolveSlackChannelAllowlist } from "./resolve-channels-HR0TgArR.mjs";
13
- import { t as resolveSlackUserAllowlist } from "./resolve-users-BNYBhF0q.mjs";
14
- import { n as runSlackApprovalMessageUpdate, t as hasSlackApprovalControl } from "./approval-message-updates-EgKGmFXx.mjs";
9
+ import { S as hasSlackMessageTableBlock, f as readSlackMessages, v as isGovSlackClient, y as saveRemoteMedia } from "./actions-KGKwTAKO.mjs";
10
+ import { d as requireSlackPostMessageTimestamp, f as buildSlackMessageIdentityPayload, r as setSlackDefaultSendIdentity } from "./send-CLmsR42r.mjs";
11
+ import { n as resolveSlackChannelConfig, r as resolveSlackChannelLabel, t as isSlackChannelAllowedByPolicy } from "./policy-BaY9_eh1.mjs";
12
+ import { t as resolveSlackChannelAllowlist } from "./resolve-channels-B96cgprw.mjs";
13
+ import { t as resolveSlackUserAllowlist } from "./resolve-users-Xz9aPdns.mjs";
14
+ import { n as runSlackApprovalMessageUpdate, t as hasSlackApprovalControl } from "./approval-message-updates-CwdDew9i.mjs";
15
15
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
16
16
  import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
17
- import { asNonArrayRecord, asOptionalRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, normalizeUniqueTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
17
+ import { asNonArrayRecord, asOptionalObjectRecord, asOptionalRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, normalizeUniqueTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
18
18
  import { normalizeAccountId as normalizeAccountId$1, normalizeMainKey, resolveAgentIdFromSessionKey, resolveAgentRoute, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
19
19
  import { createChannelIngressError, createChannelIngressMonitor, waitUntilAbort } from "openclaw/plugin-sdk/channel-outbound";
20
20
  import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
@@ -27,7 +27,7 @@ import { normalizeStringEntries as normalizeStringEntries$1, normalizeStringEntr
27
27
  import { addAllowlistUserEntriesFromConfigEntry, buildAllowlistResolutionSummary, formatAllowlistMatchMeta, mergeAllowlist, patchAllowlistUsersInConfigEntries, summarizeMapping } from "openclaw/plugin-sdk/allow-from";
28
28
  import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
29
29
  import { parseExecApprovalCommandText } from "openclaw/plugin-sdk/approval-reply-runtime";
30
- import { asDateTimestampMs, parseFiniteNumber, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolvePromptHistoryLimit, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
30
+ import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolvePromptHistoryLimit, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
31
31
  import { WebAPIHTTPError, WebAPIPlatformError, WebAPIRateLimitedError, WebAPIRequestError, WebClient } from "@slack/web-api";
32
32
  import { classifyTransientNetworkErrorCode } from "openclaw/plugin-sdk/retry-runtime";
33
33
  import { buildPluginBindingResolvedText, parsePluginBindingApprovalCustomId, resolvePluginConversationBindingApproval, resolveRuntimeConversationBindingRoute, upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
@@ -44,8 +44,9 @@ import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runti
44
44
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
45
45
  import { channelBlockedPatch, channelReadyPatch } from "openclaw/plugin-sdk/gateway-runtime";
46
46
  import { getConversationSession, getSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
47
+ import { captureSessionEntryCurrentCheck } from "openclaw/plugin-sdk/session-binding-runtime";
47
48
  import { loadPreparedModelCatalog, resolveAgentDir, resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
48
- import { formatCommandArgMenuTitle, resolveCommandAuthorization, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride } from "openclaw/plugin-sdk/command-auth-native";
49
+ import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, parseCommandArgs, resolveCommandArgMenu, resolveCommandAuthorization, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride } from "openclaw/plugin-sdk/command-auth-native";
49
50
  import { mergeNativeCommandSpecs } from "openclaw/plugin-sdk/native-command-registry";
50
51
  import { generateSecureToken } from "openclaw/plugin-sdk/secure-random-runtime";
51
52
  import { resolveChannelConfigWrites } from "openclaw/plugin-sdk/channel-config-writes";
@@ -140,19 +141,20 @@ function createSlackAgentViewState(params) {
140
141
  };
141
142
  const openWorkspaceStore = createStoreOpener(SLACK_AGENT_VIEW_STATE_NAMESPACE, SLACK_AGENT_VIEW_STATE_MAX_ENTRIES);
142
143
  const openThreadStore = createStoreOpener(SLACK_AGENT_VIEW_THREAD_STATE_NAMESPACE, SLACK_AGENT_VIEW_THREAD_STATE_MAX_ENTRIES);
143
- const workspaceStateKey = () => {
144
+ const resolveStateKey = (thread) => {
144
145
  const apiAppId = params.getApiAppId();
145
146
  return apiAppId ? JSON.stringify([
146
- "workspace",
147
+ thread ? "thread" : "workspace",
147
148
  params.accountId,
148
149
  params.getTeamId(),
149
- apiAppId
150
+ apiAppId,
151
+ ...thread ?? []
150
152
  ]) : void 0;
151
153
  };
152
154
  const record = async () => {
153
155
  enabled = true;
154
156
  loaded = true;
155
- const stateKey = workspaceStateKey();
157
+ const stateKey = resolveStateKey();
156
158
  if (persisted || !stateKey) return;
157
159
  const openedStore = openWorkspaceStore();
158
160
  if (!openedStore) return;
@@ -169,7 +171,7 @@ function createSlackAgentViewState(params) {
169
171
  const isEnabled = async () => {
170
172
  if (enabled) return true;
171
173
  if (loaded) return false;
172
- const stateKey = workspaceStateKey();
174
+ const stateKey = resolveStateKey();
173
175
  if (!stateKey) return false;
174
176
  const openedStore = openWorkspaceStore();
175
177
  if (!openedStore) return false;
@@ -185,24 +187,13 @@ function createSlackAgentViewState(params) {
185
187
  }
186
188
  };
187
189
  const managedThreadKey = (channelId, threadTs) => JSON.stringify([channelId, threadTs]);
188
- const managedThreadStateKey = (channelId, threadTs) => {
189
- const apiAppId = params.getApiAppId();
190
- return apiAppId ? JSON.stringify([
191
- "thread",
192
- params.accountId,
193
- params.getTeamId(),
194
- apiAppId,
195
- channelId,
196
- threadTs
197
- ]) : void 0;
198
- };
199
190
  const rememberManagedThread = (key) => {
200
191
  writeLruMapEntry(managedThreads, key, true, SLACK_MANAGED_THREAD_CACHE_MAX_ENTRIES);
201
192
  };
202
193
  const recordManagedThread = async (channelId, threadTs) => {
203
194
  const key = managedThreadKey(channelId, threadTs);
204
195
  rememberManagedThread(key);
205
- const stateKey = managedThreadStateKey(channelId, threadTs);
196
+ const stateKey = resolveStateKey([channelId, threadTs]);
206
197
  const openedStore = stateKey ? openThreadStore() : void 0;
207
198
  if (!openedStore || !stateKey) return;
208
199
  try {
@@ -217,7 +208,7 @@ function createSlackAgentViewState(params) {
217
208
  const isManagedThread = async (channelId, threadTs) => {
218
209
  const key = managedThreadKey(channelId, threadTs);
219
210
  if (managedThreads.has(key)) return true;
220
- const stateKey = managedThreadStateKey(channelId, threadTs);
211
+ const stateKey = resolveStateKey([channelId, threadTs]);
221
212
  const openedStore = stateKey ? openThreadStore() : void 0;
222
213
  if (!openedStore || !stateKey) return false;
223
214
  try {
@@ -323,13 +314,14 @@ function inferSlackChannelType(channelId) {
323
314
  if (trimmed.startsWith("C")) return "channel";
324
315
  if (trimmed.startsWith("G")) return "group";
325
316
  }
326
- function normalizeSlackChannelType(channelType, channelId) {
317
+ function parseSlackChannelType(channelType) {
327
318
  const normalized = normalizeOptionalLowercaseString(channelType);
319
+ if (normalized === "im" || normalized === "mpim" || normalized === "channel" || normalized === "group") return normalized;
320
+ }
321
+ function normalizeSlackChannelType(channelType, channelId) {
322
+ const normalized = parseSlackChannelType(channelType);
328
323
  const inferred = inferSlackChannelType(channelId);
329
- if (normalized === "im" || normalized === "mpim" || normalized === "channel" || normalized === "group") {
330
- if (inferred === "im" && normalized !== "im") return "im";
331
- return normalized;
332
- }
324
+ if (normalized && inferred !== "im") return normalized;
333
325
  return inferred ?? "channel";
334
326
  }
335
327
  function resolveSlackChatType(channelType) {
@@ -617,13 +609,13 @@ const OPENCLAW_SLACK_NATIVE_RECONNECT_OBSERVER_KEY = "__openclawNativeReconnectF
617
609
  const SLACK_SOCKET_PONG_TIMEOUT_WARNING_PREFIX = "A pong wasn't received from the server";
618
610
  const SLACK_SOCKET_PING_TIMEOUT_WARNING_PREFIX = "A ping wasn't received from the server";
619
611
  const SLACK_SOCKET_LOG_LEVEL_IGNORED_WARNING_RE = /^The logLevel given to .+ was ignored as you also gave logger$/;
612
+ const SLACK_SOCKET_FOREIGN_DIAGNOSTICS_WARNING_RE = /^Received unexpected (?:ping|pong) diagnostics message format$/;
620
613
  function isConstructorFunction(value) {
621
614
  return typeof value === "function";
622
615
  }
623
616
  function installSlackNativeReconnectFailureObserver(receiver) {
624
- if (!receiver || typeof receiver !== "object") return;
625
- const client = Reflect.get(receiver, "client");
626
- if (!client || typeof client !== "object") return;
617
+ const client = asOptionalObjectRecord(asOptionalObjectRecord(receiver)?.client);
618
+ if (!client) return;
627
619
  if (Reflect.get(client, OPENCLAW_SLACK_NATIVE_RECONNECT_OBSERVER_KEY)) return;
628
620
  const delayReconnectAttempt = Reflect.get(client, "delayReconnectAttempt");
629
621
  const emit = Reflect.get(client, "emit");
@@ -681,10 +673,11 @@ function resolveSlackBoltModule(value) {
681
673
  }
682
674
  function resolveSlackBoltInterop(params) {
683
675
  const { defaultImport, namespaceImport } = params;
684
- const nestedDefault = defaultImport && typeof defaultImport === "object" ? Reflect.get(defaultImport, "default") : void 0;
685
- const namespaceDefault = namespaceImport && typeof namespaceImport === "object" ? Reflect.get(namespaceImport, "default") : void 0;
686
- const namespaceReceiver = namespaceImport && typeof namespaceImport === "object" ? Reflect.get(namespaceImport, "HTTPReceiver") : void 0;
687
- const namespaceSocketModeReceiver = namespaceImport && typeof namespaceImport === "object" ? Reflect.get(namespaceImport, "SocketModeReceiver") : void 0;
676
+ const nestedDefault = asOptionalObjectRecord(defaultImport)?.default;
677
+ const namespace = asOptionalObjectRecord(namespaceImport);
678
+ const namespaceDefault = namespace?.default;
679
+ const namespaceReceiver = namespace?.HTTPReceiver;
680
+ const namespaceSocketModeReceiver = namespace?.SocketModeReceiver;
688
681
  const directModule = resolveSlackBoltModule(defaultImport) ?? resolveSlackBoltModule(nestedDefault) ?? resolveSlackBoltModule(namespaceDefault) ?? resolveSlackBoltModule(namespaceImport);
689
682
  if (directModule) return directModule;
690
683
  if (isConstructorFunction(defaultImport) && isConstructorFunction(namespaceReceiver) && isConstructorFunction(namespaceSocketModeReceiver)) return {
@@ -723,11 +716,9 @@ function publishSlackDisconnectedStatus(setStatus, error) {
723
716
  lastError: message ?? null
724
717
  });
725
718
  }
726
- function isSlackSocketHeartbeatTimeoutWarning(args) {
727
- return typeof args[0] === "string" && (args[0].startsWith(SLACK_SOCKET_PONG_TIMEOUT_WARNING_PREFIX) || args[0].startsWith(SLACK_SOCKET_PING_TIMEOUT_WARNING_PREFIX));
728
- }
729
- function isSlackSocketSelfInflictedLoggerWarning(args) {
730
- return typeof args[0] === "string" && SLACK_SOCKET_LOG_LEVEL_IGNORED_WARNING_RE.test(args[0]);
719
+ function isSlackSocketNoiseWarning(args) {
720
+ const message = args[0];
721
+ return typeof message === "string" && (message.startsWith(SLACK_SOCKET_PONG_TIMEOUT_WARNING_PREFIX) || message.startsWith(SLACK_SOCKET_PING_TIMEOUT_WARNING_PREFIX) || SLACK_SOCKET_LOG_LEVEL_IGNORED_WARNING_RE.test(message) || SLACK_SOCKET_FOREIGN_DIAGNOSTICS_WARNING_RE.test(message));
731
722
  }
732
723
  function formatSlackSdkLogArgs(args) {
733
724
  return args.map((arg) => formatSlackError(arg, "")).filter(Boolean).join(" ");
@@ -745,7 +736,7 @@ function createSlackSocketModeLogger() {
745
736
  debug: () => {},
746
737
  info: () => {},
747
738
  warn: (...args) => {
748
- if (isSlackSocketHeartbeatTimeoutWarning(args) || isSlackSocketSelfInflictedLoggerWarning(args)) return;
739
+ if (isSlackSocketNoiseWarning(args)) return;
749
740
  remember(args);
750
741
  console.warn(prefix(), ...args);
751
742
  },
@@ -853,16 +844,9 @@ async function startSlackSocketAndWaitForDisconnect(params) {
853
844
  function isMissingSocketStartErrorDetail(err) {
854
845
  return err === void 0 || err === null || err === "" || err instanceof Error && err.message === "";
855
846
  }
856
- function resolveSlackSocketShutdownClient(app) {
857
- if (!app || typeof app !== "object") return;
858
- const receiver = Reflect.get(app, "receiver");
859
- if (!receiver || typeof receiver !== "object") return;
860
- const client = Reflect.get(receiver, "client");
861
- if (!client || typeof client !== "object") return;
862
- return client;
863
- }
864
847
  async function gracefulStopSlackApp(app) {
865
- const socketClient = resolveSlackSocketShutdownClient(app);
848
+ const receiver = asOptionalObjectRecord(asOptionalObjectRecord(app)?.receiver);
849
+ const socketClient = asOptionalObjectRecord(receiver?.client);
866
850
  if (socketClient) socketClient.shuttingDown = true;
867
851
  await Promise.resolve(app.stop()).catch(() => void 0);
868
852
  }
@@ -911,32 +895,16 @@ function createSlackSystemEventRouteResolver(params) {
911
895
  };
912
896
  const peerId = isDirectMessage ? senderId : channelId;
913
897
  if (!peerId) throw new Error("Slack system event route requires a peer");
914
- let route = resolveAgentRoute({
898
+ const route = resolveSlackAgentRoute({
915
899
  cfg: params.cfg,
916
- channel: "slack",
917
900
  accountId: params.accountId,
918
901
  teamId: event.eventScope?.teamId ?? params.getTeamId(),
919
902
  peer: {
920
903
  kind: resolveSlackChatType(channelType),
921
- id: qualifySlackRoutePeerId({
922
- id: peerId,
923
- kind: isDirectMessage ? "user" : "channel",
924
- eventScope: event.eventScope
925
- })
926
- }
904
+ id: peerId
905
+ },
906
+ eventScope: event.eventScope
927
907
  });
928
- if (event.eventScope && isDirectMessage && route.dmScope === "main") {
929
- const sessionKey = resolveSlackEnterpriseMainDmSessionKey({
930
- baseSessionKey: route.sessionKey,
931
- accountId: params.accountId,
932
- eventScope: event.eventScope
933
- });
934
- route = {
935
- ...route,
936
- sessionKey,
937
- mainSessionKey: sessionKey
938
- };
939
- }
940
908
  const threadTs = normalizeOptionalString(event.threadTs);
941
909
  const baseConversationId = qualifySlackConversationId(isDirectMessage ? `user:${senderId}` : channelId, event.eventScope);
942
910
  const threadBindingRoute = !event.eventScope && threadTs ? resolveRuntimeConversationBindingRoute({
@@ -1108,7 +1076,7 @@ async function resolveWorkspacePolicy(ctx, resolveToken) {
1108
1076
  } catch (err) {
1109
1077
  runtime.log?.(`slack channel resolve failed; using config entries. ${formatSlackError(err)}`);
1110
1078
  }
1111
- const dmEntries = new Set(normalizeStringEntries(allowFrom).filter((entry) => entry !== "*"));
1079
+ const dmEntries = new Set(allowFrom.filter((entry) => entry !== "*"));
1112
1080
  const userEntries = new Set(dmEntries);
1113
1081
  for (const channel of Object.values(channelsConfig ?? {})) addAllowlistUserEntriesFromConfigEntry(userEntries, channel);
1114
1082
  const entries = [...userEntries];
@@ -1129,10 +1097,10 @@ async function resolveWorkspacePolicy(ctx, resolveToken) {
1129
1097
  runtime.log?.(`slack user resolve failed; using config entries. ${formatSlackError(err)}`);
1130
1098
  }
1131
1099
  const { additions } = buildAllowlistResolutionSummary(resolved.filter((entry) => dmEntries.has(entry.input)), { formatResolved: formatSlackUserResolved });
1132
- ctx.allowFrom = normalizeStringEntries(mergeAllowlist({
1100
+ ctx.allowFrom = mergeAllowlist({
1133
1101
  existing: allowFrom,
1134
1102
  additions
1135
- }));
1103
+ });
1136
1104
  const { resolvedMap, mapping, unresolved } = buildAllowlistResolutionSummary(resolved, { formatResolved: formatSlackUserResolved });
1137
1105
  if (channelsConfig) ctx.channelsConfig = patchAllowlistUsersInConfigEntries({
1138
1106
  entries: channelsConfig,
@@ -1170,6 +1138,17 @@ async function updateSlackSuggestedPrompts(params) {
1170
1138
  }
1171
1139
  //#endregion
1172
1140
  //#region extensions/slack/src/monitor/context.ts
1141
+ function classifySlackChannelLookupFailure(error) {
1142
+ if (error instanceof WebAPIRateLimitedError) return "rate_limited";
1143
+ if (error instanceof WebAPIHTTPError) return error.statusCode === 429 ? "rate_limited" : error.statusCode === 404 ? "not_found" : "other";
1144
+ if (error instanceof WebAPIPlatformError) {
1145
+ if (error.data.error === "ratelimited") return "rate_limited";
1146
+ if (error.data.error === "channel_not_found" || error.data.error === "not_found") return "not_found";
1147
+ if (error.data.error === "missing_scope" || error.data.error === "not_in_channel") return "permission";
1148
+ }
1149
+ if (error instanceof WebAPIRequestError) return /^A rate limit was exceeded \(url: .+, retry-after: \d+\)$/.test(error.original.message) ? "rate_limited" : "network";
1150
+ return "other";
1151
+ }
1173
1152
  const SLACK_CHANNEL_CACHE_MAX_ENTRIES = 1024;
1174
1153
  const SLACK_USER_CACHE_MAX_ENTRIES = 2048;
1175
1154
  const SLACK_AVATAR_CACHE_MAX_ENTRIES = 128;
@@ -1208,8 +1187,8 @@ function createSlackMonitorContextFields(params) {
1208
1187
  const scopedKey = (key, eventScope) => eventScope ? `${params.accountId}:${eventScope.teamId}:${key}` : key;
1209
1188
  const rememberSlackChannelType = (channelId, channelType, eventScope) => {
1210
1189
  const id = normalizeOptionalString(channelId);
1211
- const normalizedType = normalizeOptionalString(channelType)?.toLowerCase();
1212
- if (!id || normalizedType !== "im" && normalizedType !== "mpim" && normalizedType !== "channel" && normalizedType !== "group") return;
1190
+ const normalizedType = parseSlackChannelType(channelType);
1191
+ if (!id || !normalizedType) return;
1213
1192
  const cacheKey = scopedKey(id, eventScope);
1214
1193
  const cached = readLruMapEntry(channelCache, cacheKey);
1215
1194
  const type = normalizeSlackChannelType(normalizedType, id);
@@ -1259,8 +1238,11 @@ function createSlackMonitorContextFields(params) {
1259
1238
  };
1260
1239
  writeLruMapEntry(channelCache, cacheKey, entry, SLACK_CHANNEL_CACHE_MAX_ENTRIES);
1261
1240
  return entry.info;
1262
- } catch {
1263
- return cached?.info ?? {};
1241
+ } catch (error) {
1242
+ return {
1243
+ ...cached?.info,
1244
+ lookupFailureCategory: classifySlackChannelLookupFailure(error)
1245
+ };
1264
1246
  }
1265
1247
  };
1266
1248
  const resolveUserName = async (userId, eventScope) => {
@@ -1682,26 +1664,22 @@ async function resolveThreadTsFromHistory(params) {
1682
1664
  return normalizeOptionalString(message?.thread_ts);
1683
1665
  }
1684
1666
  function createSlackThreadTsResolver(params) {
1685
- const ttlMs = Math.max(0, parseFiniteNumber(params.cacheTtlMs) ?? DEFAULT_THREAD_TS_CACHE_TTL_MS);
1686
- const maxSize = Math.max(0, parseFiniteNumber(params.maxSize) ?? DEFAULT_THREAD_TS_CACHE_MAX);
1687
1667
  const cache = /* @__PURE__ */ new Map();
1688
1668
  const inflight = /* @__PURE__ */ new Map();
1689
1669
  const getCached = (key, now) => {
1690
1670
  const entry = cache.get(key);
1691
1671
  if (!entry) return;
1692
- if (entry.expiresAt !== 0) {
1693
- const normalizedNow = asDateTimestampMs(now);
1694
- if (normalizedNow === void 0 || asDateTimestampMs(entry.expiresAt) === void 0 || entry.expiresAt <= normalizedNow) {
1695
- cache.delete(key);
1696
- return;
1697
- }
1672
+ const normalizedNow = asDateTimestampMs(now);
1673
+ if (normalizedNow === void 0 || entry.expiresAt <= normalizedNow) {
1674
+ cache.delete(key);
1675
+ return;
1698
1676
  }
1699
1677
  cache.delete(key);
1700
1678
  cache.set(key, entry);
1701
1679
  return entry.threadTs;
1702
1680
  };
1703
1681
  const setCached = (key, threadTs, now) => {
1704
- const expiresAt = ttlMs > 0 ? resolveExpiresAtMsFromDurationMs(ttlMs, { nowMs: now }) : 0;
1682
+ const expiresAt = resolveExpiresAtMsFromDurationMs(DEFAULT_THREAD_TS_CACHE_TTL_MS, { nowMs: now });
1705
1683
  if (expiresAt === void 0) {
1706
1684
  cache.delete(key);
1707
1685
  return;
@@ -1711,7 +1689,7 @@ function createSlackThreadTsResolver(params) {
1711
1689
  threadTs,
1712
1690
  expiresAt
1713
1691
  });
1714
- pruneMapToMaxSize(cache, maxSize);
1692
+ pruneMapToMaxSize(cache, DEFAULT_THREAD_TS_CACHE_MAX);
1715
1693
  };
1716
1694
  return { resolve: async (request) => {
1717
1695
  const { message } = request;
@@ -1759,7 +1737,7 @@ function createSlackThreadTsResolver(params) {
1759
1737
  //#endregion
1760
1738
  //#region extensions/slack/src/monitor/auth.ts
1761
1739
  const slackChannelMembersCache = /* @__PURE__ */ new WeakMap();
1762
- const DEFAULT_CHANNEL_MEMBERS_CACHE_TTL_MS = 6e4;
1740
+ const CHANNEL_MEMBERS_CACHE_TTL_MS = 6e4;
1763
1741
  const CHANNEL_MEMBERS_CACHE_MAX = 512;
1764
1742
  const SLACK_CHANNEL_ID = "slack";
1765
1743
  var SlackSystemEventAuthRetryError = class extends Error {};
@@ -1771,12 +1749,6 @@ function createSlackIngressResolver(ctx) {
1771
1749
  cfg: ctx.cfg
1772
1750
  });
1773
1751
  }
1774
- function readSlackCacheTtlMs(envName, fallback) {
1775
- const raw = process.env[envName]?.trim();
1776
- if (!raw) return fallback;
1777
- const parsed = /^\d+$/.test(raw) ? Number(raw) : NaN;
1778
- return Number.isSafeInteger(parsed) ? parsed : fallback;
1779
- }
1780
1752
  function getChannelMembersCache(ctx) {
1781
1753
  const existing = slackChannelMembersCache.get(ctx);
1782
1754
  if (existing) return existing;
@@ -1822,17 +1794,16 @@ async function fetchSlackChannelMemberIds(ctx, channelId, eventScope) {
1822
1794
  async function resolveSlackChannelMemberIds(ctx, channelId, eventScope) {
1823
1795
  const cache = getChannelMembersCache(ctx);
1824
1796
  const key = `${ctx.accountId}:${eventScope ? `${eventScope.teamId}:` : ""}${channelId}`;
1825
- const ttlMs = readSlackCacheTtlMs("OPENCLAW_SLACK_CHANNEL_MEMBERS_CACHE_TTL_MS", DEFAULT_CHANNEL_MEMBERS_CACHE_TTL_MS);
1826
1797
  const rawNowMs = Date.now();
1827
1798
  const nowMs = asDateTimestampMs(rawNowMs);
1828
1799
  const cached = cache.get(key);
1829
1800
  if (cached?.members) {
1830
- if (ttlMs > 0 && nowMs !== void 0 && cached.expiresAtMs >= nowMs) return cached.members;
1801
+ if (nowMs !== void 0 && cached.expiresAtMs >= nowMs) return cached.members;
1831
1802
  cache.delete(key);
1832
1803
  }
1833
1804
  if (cached?.pending) return await cached.pending;
1834
1805
  const pending = fetchSlackChannelMemberIds(ctx, channelId, eventScope);
1835
- const pendingExpiresAtMs = ttlMs > 0 ? resolveExpiresAtMsFromDurationMs(ttlMs, { nowMs: rawNowMs }) : void 0;
1806
+ const pendingExpiresAtMs = resolveExpiresAtMsFromDurationMs(CHANNEL_MEMBERS_CACHE_TTL_MS, { nowMs: rawNowMs });
1836
1807
  cache.set(key, {
1837
1808
  expiresAtMs: pendingExpiresAtMs ?? 0,
1838
1809
  pending
@@ -1840,7 +1811,7 @@ async function resolveSlackChannelMemberIds(ctx, channelId, eventScope) {
1840
1811
  pruneMapToMaxSize(cache, CHANNEL_MEMBERS_CACHE_MAX);
1841
1812
  try {
1842
1813
  const members = await pending;
1843
- const membersExpiresAtMs = ttlMs > 0 ? resolveExpiresAtMsFromDurationMs(ttlMs) : void 0;
1814
+ const membersExpiresAtMs = resolveExpiresAtMsFromDurationMs(CHANNEL_MEMBERS_CACHE_TTL_MS);
1844
1815
  if (membersExpiresAtMs !== void 0) {
1845
1816
  cache.set(key, {
1846
1817
  expiresAtMs: membersExpiresAtMs,
@@ -2037,9 +2008,7 @@ async function authorizeSlackSystemEventSender(params) {
2037
2008
  channelName
2038
2009
  };
2039
2010
  if (params.interactiveEvent) {
2040
- const inferredFromId = inferSlackChannelType(channelId);
2041
- const sourceNormalized = typeof resolvedTypeSource === "string" ? resolvedTypeSource.toLowerCase().trim() : void 0;
2042
- if (inferredFromId === void 0 && !(sourceNormalized === "im" || sourceNormalized === "mpim" || sourceNormalized === "channel" || sourceNormalized === "group")) return {
2011
+ if (inferSlackChannelType(channelId) === void 0 && !parseSlackChannelType(resolvedTypeSource)) return {
2043
2012
  allowed: false,
2044
2013
  reason: "ambiguous-channel-type",
2045
2014
  channelType,
@@ -2105,6 +2074,39 @@ async function authorizeSlackSystemEventSender(params) {
2105
2074
  };
2106
2075
  }
2107
2076
  //#endregion
2077
+ //#region extensions/slack/src/monitor/event-scope.ts
2078
+ function resolveSlackMonitorEventScope(params) {
2079
+ const identity = params.ctx.installationIdentity;
2080
+ const clientOptions = params.ctx.app.webClientOptions;
2081
+ const onDrop = params.onDrop ?? ((reason) => logVerbose(`slack: drop listener event (${reason})`));
2082
+ const drop = (reason) => {
2083
+ onDrop(reason);
2084
+ return null;
2085
+ };
2086
+ const context = params.context ?? {};
2087
+ if (identity.kind !== "enterprise") return context.isEnterpriseInstall === true ? drop("enterprise_event_for_workspace_account") : void 0;
2088
+ const body = params.body && typeof params.body === "object" ? params.body : {};
2089
+ const apiAppId = normalizeOptionalString(body.api_app_id);
2090
+ if (apiAppId && identity.apiAppId && apiAppId !== identity.apiAppId) return drop("wrong_app");
2091
+ if (context.isEnterpriseInstall !== true) return drop("not_enterprise_install");
2092
+ const enterpriseId = normalizeOptionalString(context.enterpriseId);
2093
+ if (!enterpriseId) return drop("missing_enterprise_id");
2094
+ if (enterpriseId !== identity.enterpriseId) return drop("wrong_enterprise");
2095
+ const teamId = normalizeOptionalString(context.teamId);
2096
+ if (!teamId) return drop("missing_team_id");
2097
+ if (!params.client) return drop("missing_listener_client");
2098
+ const writeClient = getSlackListenerWriteClient({
2099
+ listenerClient: params.client,
2100
+ teamId,
2101
+ clientOptions
2102
+ });
2103
+ return {
2104
+ teamId,
2105
+ client: params.client,
2106
+ ...writeClient ? { writeClient } : {}
2107
+ };
2108
+ }
2109
+ //#endregion
2108
2110
  //#region extensions/slack/src/types.ts
2109
2111
  function parseSlackMessageEvent(value) {
2110
2112
  const record = asOptionalRecord(value);
@@ -2464,17 +2466,14 @@ function resolveSlackThreadContext(params) {
2464
2466
  }
2465
2467
  //#endregion
2466
2468
  //#region extensions/slack/src/monitor/session-run-targets.ts
2467
- function captureSlackSessionTargetGuard(ctx, route, isActive) {
2468
- const scope = {
2469
+ async function captureSlackSessionTargetGuard(ctx, route, isActive) {
2470
+ const { isCurrent } = await captureSessionEntryCurrentCheck({
2469
2471
  agentId: route.agentId,
2470
2472
  sessionKey: route.sessionKey,
2471
- storePath: resolveStorePath(ctx.cfg.session?.store, { agentId: route.agentId })
2472
- };
2473
- const selected = getSessionEntry(scope);
2474
- return () => {
2475
- const current = getSessionEntry(scope);
2476
- return isActive?.() !== false && current?.sessionId === selected?.sessionId && current?.lifecycleRevision === selected?.lifecycleRevision;
2477
- };
2473
+ storePath: resolveStorePath(ctx.cfg.session?.store, { agentId: route.agentId }),
2474
+ isActive
2475
+ });
2476
+ return isCurrent;
2478
2477
  }
2479
2478
  const runs = /* @__PURE__ */ new WeakMap();
2480
2479
  function addressKey(address) {
@@ -2511,34 +2510,6 @@ function getSlackSessionRuns(ctx, address) {
2511
2510
  }
2512
2511
  //#endregion
2513
2512
  //#region extensions/slack/src/monitor/message-handler/prepare-routing.ts
2514
- function resolveSlackInitialAgentRoute(params) {
2515
- const route = resolveAgentRoute({
2516
- cfg: params.boundAgentId || !params.bindingOwnerAvailable ? { session: params.ctx.cfg.session } : normalizeSlackRouteBindingConfig(params.ctx.cfg),
2517
- defaultAgentId: params.boundAgentId,
2518
- channel: "slack",
2519
- accountId: params.account.accountId,
2520
- teamId: params.eventScope?.teamId || params.ctx.teamId || void 0,
2521
- peer: {
2522
- kind: params.chatType,
2523
- id: qualifySlackRoutePeerId({
2524
- id: params.chatType === "direct" ? params.message.user ?? "unknown" : params.message.channel,
2525
- kind: params.chatType === "direct" ? "user" : "channel",
2526
- eventScope: params.eventScope
2527
- })
2528
- }
2529
- });
2530
- if (!params.eventScope || params.chatType !== "direct" || route.dmScope !== "main") return route;
2531
- const sessionKey = resolveSlackEnterpriseMainDmSessionKey({
2532
- baseSessionKey: route.sessionKey,
2533
- accountId: params.account.accountId,
2534
- eventScope: params.eventScope
2535
- });
2536
- return {
2537
- ...route,
2538
- sessionKey,
2539
- mainSessionKey: sessionKey
2540
- };
2541
- }
2542
2513
  function resolveSlackRoutingContext(params) {
2543
2514
  const { ctx, account, message, chatType, channelConfig, seedTopLevelRoomThread, assistantThreadTs, agentViewThreadTs, eventScope } = params;
2544
2515
  const isDirectMessage = chatType === "direct";
@@ -2557,12 +2528,15 @@ function resolveSlackRoutingContext(params) {
2557
2528
  const runtimeBindingThreadId = routedThreadId ?? (isDirectMessage && isThreadReply ? threadTs : void 0);
2558
2529
  const bindingRoute = resolveSlackConversationBindingRoute({
2559
2530
  cfg: ctx.cfg,
2560
- resolveRoute: (selection) => resolveSlackInitialAgentRoute({
2561
- ...selection,
2562
- ctx,
2563
- account,
2564
- message,
2565
- chatType,
2531
+ resolveRoute: ({ boundAgentId, bindingOwnerAvailable }) => resolveSlackAgentRoute({
2532
+ cfg: boundAgentId || !bindingOwnerAvailable ? { session: ctx.cfg.session } : normalizeSlackRouteBindingConfig(ctx.cfg),
2533
+ defaultAgentId: boundAgentId,
2534
+ accountId: account.accountId,
2535
+ teamId: eventScope?.teamId || ctx.teamId || void 0,
2536
+ peer: {
2537
+ kind: chatType,
2538
+ id: isDirectMessage ? message.user ?? "unknown" : message.channel
2539
+ },
2566
2540
  eventScope
2567
2541
  }),
2568
2542
  accountId: account.accountId,
@@ -2663,12 +2637,44 @@ async function resolveSlackSessionEventRoutingContext(params) {
2663
2637
  }
2664
2638
  if (!owner) throw new Error("No recorded session owns this Slack conversation");
2665
2639
  const { route } = owner;
2666
- const isCurrentIncarnation = params.intent === "stop" ? captureSlackSessionTargetGuard(ctx, route, owner.isActive) : void 0;
2640
+ const readLiveOwner = () => getSlackSessionRuns(ctx, liveAddress).at(-1);
2641
+ const current = await captureSessionEntryCurrentCheck({
2642
+ agentId: route.agentId,
2643
+ sessionKey: route.sessionKey,
2644
+ storePath: resolveStorePath(ctx.cfg.session?.store, { agentId: route.agentId }),
2645
+ isActive: params.intent === "stop" ? owner.isActive : void 0,
2646
+ matchGeneration: params.intent === "stop",
2647
+ errorMessage: params.intent === "title" ? "Slack conversation owner changed before the title update" : "The selected session changed before it could be stopped.",
2648
+ alternatives: [
2649
+ { conversations: [{
2650
+ ...threadAddress,
2651
+ sessionKey: route.sessionKey
2652
+ }] },
2653
+ {
2654
+ conversations: [{
2655
+ ...threadAddress,
2656
+ sessionKey: null
2657
+ }],
2658
+ isActive: () => readLiveOwner()?.route.sessionKey === route.sessionKey
2659
+ },
2660
+ ...allowDirectParent ? [{
2661
+ conversations: [{
2662
+ ...threadAddress,
2663
+ sessionKey: null
2664
+ }, {
2665
+ ...address,
2666
+ sessionKey: route.sessionKey
2667
+ }],
2668
+ isActive: () => !readLiveOwner()
2669
+ }] : []
2670
+ ]
2671
+ });
2667
2672
  return {
2668
2673
  ...routing,
2669
2674
  route,
2670
2675
  sessionKey: route.sessionKey,
2671
- isCurrentSession: () => readOwner()?.route.sessionKey === route.sessionKey && isCurrentIncarnation?.() !== false
2676
+ isCurrentSession: current.isCurrent,
2677
+ assertCurrentSession: current.assertCurrent
2672
2678
  };
2673
2679
  }
2674
2680
  //#endregion
@@ -2743,77 +2749,11 @@ async function authorizeSlackDirectMessage(params) {
2743
2749
  return false;
2744
2750
  }
2745
2751
  //#endregion
2746
- //#region extensions/slack/src/monitor/event-scope.ts
2747
- function resolveSlackListenerEventScope$1(params) {
2748
- const resolved = resolveSlackEventScope(params);
2749
- if (!resolved.ok) {
2750
- params.onDrop?.(resolved.reason);
2751
- return null;
2752
- }
2753
- return resolved.scope;
2754
- }
2755
- function resolveSlackEventScope(params) {
2756
- const context = params.context ?? {};
2757
- if (params.identity.kind !== "enterprise") return context.isEnterpriseInstall === true ? {
2758
- ok: false,
2759
- reason: "enterprise_event_for_workspace_account"
2760
- } : { ok: true };
2761
- const body = params.body && typeof params.body === "object" ? params.body : {};
2762
- const apiAppId = normalizeOptionalString(body.api_app_id);
2763
- if (apiAppId && params.identity.apiAppId && apiAppId !== params.identity.apiAppId) return {
2764
- ok: false,
2765
- reason: "wrong_app"
2766
- };
2767
- if (context.isEnterpriseInstall !== true) return {
2768
- ok: false,
2769
- reason: "not_enterprise_install"
2770
- };
2771
- const enterpriseId = normalizeOptionalString(context.enterpriseId);
2772
- if (!enterpriseId) return {
2773
- ok: false,
2774
- reason: "missing_enterprise_id"
2775
- };
2776
- if (enterpriseId !== params.identity.enterpriseId) return {
2777
- ok: false,
2778
- reason: "wrong_enterprise"
2779
- };
2780
- const teamId = normalizeOptionalString(context.teamId);
2781
- if (!teamId) return {
2782
- ok: false,
2783
- reason: "missing_team_id"
2784
- };
2785
- if (!params.client) return {
2786
- ok: false,
2787
- reason: "missing_listener_client"
2788
- };
2789
- const writeClient = getSlackListenerWriteClient({
2790
- listenerClient: params.client,
2791
- teamId,
2792
- clientOptions: params.clientOptions
2793
- });
2794
- return {
2795
- ok: true,
2796
- scope: {
2797
- teamId,
2798
- client: params.client,
2799
- ...writeClient ? { writeClient } : {}
2800
- }
2801
- };
2802
- }
2803
- //#endregion
2804
2752
  //#region extensions/slack/src/monitor/external-arg-menu-store.ts
2805
2753
  const SLACK_EXTERNAL_ARG_MENU_TOKEN_BYTES = 18;
2806
2754
  const SLACK_EXTERNAL_ARG_MENU_TOKEN_PATTERN = new RegExp(`^[A-Za-z0-9_-]{${Math.ceil(24)}}$`);
2807
2755
  const SLACK_EXTERNAL_ARG_MENU_TTL_MS = 6e5;
2808
2756
  const SLACK_EXTERNAL_ARG_MENU_PREFIX = "openclaw_cmdarg_ext:";
2809
- function pruneSlackExternalArgMenuStore(store, rawNow) {
2810
- const now = asDateTimestampMs(rawNow);
2811
- if (now === void 0) {
2812
- store.clear();
2813
- return;
2814
- }
2815
- for (const [token, entry] of store.entries()) if (asDateTimestampMs(entry.expiresAt) === void 0 || entry.expiresAt <= now) store.delete(token);
2816
- }
2817
2757
  function createSlackExternalArgMenuToken(store) {
2818
2758
  let token;
2819
2759
  do
@@ -2825,7 +2765,7 @@ function createSlackExternalArgMenuStore() {
2825
2765
  const store = /* @__PURE__ */ new Map();
2826
2766
  return {
2827
2767
  create(params, now = Date.now()) {
2828
- pruneSlackExternalArgMenuStore(store, now);
2768
+ pruneExpiredMapEntries(store, now);
2829
2769
  const token = createSlackExternalArgMenuToken(store);
2830
2770
  const expiresAt = resolveExpiresAtMsFromDurationMs(SLACK_EXTERNAL_ARG_MENU_TTL_MS, { nowMs: now });
2831
2771
  if (expiresAt !== void 0) store.set(token, {
@@ -2841,7 +2781,7 @@ function createSlackExternalArgMenuStore() {
2841
2781
  return SLACK_EXTERNAL_ARG_MENU_TOKEN_PATTERN.test(token) ? token : void 0;
2842
2782
  },
2843
2783
  get(token, now = Date.now()) {
2844
- pruneSlackExternalArgMenuStore(store, now);
2784
+ pruneExpiredMapEntries(store, now);
2845
2785
  return store.get(token);
2846
2786
  }
2847
2787
  };
@@ -2890,8 +2830,7 @@ const SLACK_COMMAND_ARG_BUTTON_VALUE_MAX = 2e3;
2890
2830
  const SLACK_COMMAND_ARG_CONFIRM_TEXT_MAX = 300;
2891
2831
  const SLACK_HEADER_TEXT_MAX = 150;
2892
2832
  const SLACK_COMMAND_ARG_ACTION_BLOCKS_MAX = 47;
2893
- const loadSlashCommandsRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/command-auth-native"));
2894
- const loadSlashDispatchRuntime = createLazyRuntimeModule(() => import("./slash-dispatch.runtime-gBj_uaLM.mjs"));
2833
+ const loadSlashDispatchRuntime = createLazyRuntimeModule(() => import("./slash-dispatch.runtime-Dzwj6TPI.mjs"));
2895
2834
  const loadPluginCommandRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/plugin-command-runtime"));
2896
2835
  function resolveSlackCommandMenuModelContext(params) {
2897
2836
  if (!params.sessionKey.trim()) return {};
@@ -3211,7 +3150,7 @@ function createSlackCommandHandler(params) {
3211
3150
  if (p.threadTs) {
3212
3151
  if (p.sessionTarget) {
3213
3152
  resolvedSlashRoute = p.sessionTarget;
3214
- isCurrentSession = captureSlackSessionTargetGuard(ctx, p.sessionTarget, p.isSessionTargetCurrent);
3153
+ isCurrentSession = await captureSlackSessionTargetGuard(ctx, p.sessionTarget, p.isSessionTargetCurrent);
3215
3154
  return resolvedSlashRoute;
3216
3155
  }
3217
3156
  const routing = await resolveSlackSessionEventRoutingContext({
@@ -3247,7 +3186,6 @@ function createSlackCommandHandler(params) {
3247
3186
  return resolvedSlashRoute;
3248
3187
  };
3249
3188
  if (commandDefinition && supportsInteractiveArgMenus) {
3250
- const { resolveCommandArgMenu } = await loadSlashCommandsRuntime();
3251
3189
  const menuNeedsModelContext = !(commandArgs?.raw && !commandArgs.values) && commandDefinition.args?.some((arg) => typeof arg.choices === "function" && commandArgs?.values?.[arg.name] == null);
3252
3190
  const menuRoute = menuNeedsModelContext || commandDefinition.key === "verbose" ? await resolveSlashRoute() : void 0;
3253
3191
  const menuModelContext = menuNeedsModelContext && menuRoute ? resolveSlackCommandMenuModelContext({
@@ -3407,12 +3345,10 @@ function createSlackCommandHandler(params) {
3407
3345
  dispatcherOptions: { onSettled: async () => {
3408
3346
  if (pendingSlashReplies.length === 0) return;
3409
3347
  const pending = pendingSlashReplies.splice(0);
3410
- const settled = /* @__PURE__ */ new Set();
3411
3348
  try {
3412
3349
  await deliverSlashPayloads(pending.map((entry) => entry.payload), ({ replyIndex, visibleReplySent, error }) => {
3413
3350
  const entry = pending[replyIndex];
3414
- if (!entry || settled.has(replyIndex)) return;
3415
- settled.add(replyIndex);
3351
+ if (!entry) return;
3416
3352
  if (error !== void 0) {
3417
3353
  entry.finalization.reject(error);
3418
3354
  return;
@@ -3421,7 +3357,7 @@ function createSlackCommandHandler(params) {
3421
3357
  });
3422
3358
  } catch (error) {
3423
3359
  const unsettledError = isChannelPartialDeliveryError(error) ? error.cause ?? error : error;
3424
- for (const [replyIndex, entry] of pending.entries()) if (!settled.has(replyIndex)) entry.finalization.reject(unsettledError);
3360
+ for (const entry of pending) entry.finalization.reject(unsettledError);
3425
3361
  throw error;
3426
3362
  }
3427
3363
  } },
@@ -3470,12 +3406,9 @@ async function registerSlackMonitorSlashCommands(params) {
3470
3406
  const { ctx, account, trackEvent } = params;
3471
3407
  const startupCfg = ctx.cfg;
3472
3408
  const runtime = ctx.runtime;
3473
- const resolveEventScope = (args) => resolveSlackListenerEventScope$1({
3474
- identity: ctx.installationIdentity,
3475
- body: args.body,
3476
- context: args.context,
3477
- client: args.client,
3478
- clientOptions: ctx.app.webClientOptions,
3409
+ const resolveEventScope = (args) => resolveSlackMonitorEventScope({
3410
+ ...args,
3411
+ ctx,
3479
3412
  onDrop: (reason) => runtime.log?.(`slack: drop slash payload (${reason})`)
3480
3413
  });
3481
3414
  const supportsInteractiveArgMenus = typeof ctx.app.action === "function";
@@ -3520,20 +3453,18 @@ async function registerSlackMonitorSlashCommands(params) {
3520
3453
  });
3521
3454
  };
3522
3455
  let nativeCommands = [];
3523
- let slashCommandsRuntime = null;
3524
3456
  let pluginCommandRuntimeModule = null;
3525
3457
  if (registration.mode === "disabled" && resolveNativeCommandsEnabled({
3526
3458
  providerId: "slack",
3527
3459
  providerSetting: account.config.commands?.native,
3528
3460
  globalSetting: startupCfg.commands?.native
3529
3461
  })) {
3530
- slashCommandsRuntime = await loadSlashCommandsRuntime();
3531
3462
  const skillCommands = resolveNativeSkillsEnabled({
3532
3463
  providerId: "slack",
3533
3464
  providerSetting: account.config.commands?.nativeSkills,
3534
3465
  globalSetting: startupCfg.commands?.nativeSkills
3535
- }) ? slashCommandsRuntime.listSkillCommandsForAgents({ cfg: startupCfg }) : [];
3536
- nativeCommands = slashCommandsRuntime.listNativeCommandSpecsForConfig(startupCfg, {
3466
+ }) ? listSkillCommandsForAgents({ cfg: startupCfg }) : [];
3467
+ nativeCommands = listNativeCommandSpecsForConfig(startupCfg, {
3537
3468
  skillCommands,
3538
3469
  provider: "slack"
3539
3470
  });
@@ -3547,16 +3478,16 @@ async function registerSlackMonitorSlashCommands(params) {
3547
3478
  }
3548
3479
  if (registration.mode === "single") registerCommand(buildSlackSlashCommandMatcher(registration.name));
3549
3480
  else if (registration.mode === "native") {
3550
- if (!slashCommandsRuntime || !pluginCommandRuntimeModule) throw new Error("Missing command runtimes for native Slack commands.");
3481
+ if (!pluginCommandRuntimeModule) throw new Error("Missing command runtimes for native Slack commands.");
3551
3482
  for (const command of nativeCommands) {
3552
3483
  const pluginCommandCandidate = "prepareDispatch" in command ? command : void 0;
3553
3484
  registerCommand(`/${command.name}`, (cmd) => {
3554
- const commandDefinition = pluginCommandCandidate ? void 0 : slashCommandsRuntime.findCommandByNativeName(command.name, "slack");
3485
+ const commandDefinition = pluginCommandCandidate ? void 0 : findCommandByNativeName(command.name, "slack");
3555
3486
  const rawText = cmd.text?.trim() ?? "";
3556
3487
  const pluginCommandDispatch = pluginCommandCandidate?.prepareDispatch(rawText) ?? NON_PLUGIN_COMMAND_DISPATCH;
3557
- const commandArgs = commandDefinition ? slashCommandsRuntime.parseCommandArgs(commandDefinition, rawText) : rawText ? { raw: rawText } : void 0;
3488
+ const commandArgs = commandDefinition ? parseCommandArgs(commandDefinition, rawText) : rawText ? { raw: rawText } : void 0;
3558
3489
  return {
3559
- prompt: commandDefinition ? slashCommandsRuntime.buildCommandTextFromArgs(commandDefinition, commandArgs) : rawText ? `/${command.name} ${rawText}` : `/${command.name}`,
3490
+ prompt: commandDefinition ? buildCommandTextFromArgs(commandDefinition, commandArgs) : rawText ? `/${command.name} ${rawText}` : `/${command.name}`,
3560
3491
  commandArgs,
3561
3492
  commandDefinition: commandDefinition ?? void 0,
3562
3493
  pluginCommandReplyOptions: { [pluginCommandRuntimeModule.PLUGIN_COMMAND_DISPATCH]: pluginCommandDispatch }
@@ -3648,7 +3579,6 @@ async function registerSlackMonitorSlashCommands(params) {
3648
3579
  });
3649
3580
  return;
3650
3581
  }
3651
- const { buildCommandTextFromArgs, findCommandByNativeName } = await loadSlashCommandsRuntime();
3652
3582
  const commandDefinition = findCommandByNativeName(parsed.command, "slack");
3653
3583
  const commandArgs = { values: { [parsed.arg]: parsed.value } };
3654
3584
  const prompt = commandDefinition ? buildCommandTextFromArgs(commandDefinition, commandArgs) : `/${parsed.command} ${parsed.value}`;
@@ -3719,47 +3649,6 @@ function isSlackBoltRespondError(error) {
3719
3649
  return Boolean(error) && typeof error === "object" && error.code === "slack_bolt_respond_error";
3720
3650
  }
3721
3651
  //#endregion
3722
- //#region extensions/slack/src/monitor/events/system-event-context.ts
3723
- async function authorizeAndResolveSlackSystemEventContext(params) {
3724
- const { senderId, channelId, channelType, eventKind } = params;
3725
- const ctx = await params.ctx.readRuntimeContext();
3726
- const auth = await authorizeSlackSystemEventSender({
3727
- ctx,
3728
- senderId,
3729
- channelId,
3730
- channelType,
3731
- eventScope: params.eventScope,
3732
- retryNameLookup: eventKind.startsWith("member-")
3733
- });
3734
- if (!auth.allowed) {
3735
- logVerbose(`slack: drop ${eventKind} sender ${senderId ?? "unknown"} channel=${channelId ?? "unknown"} reason=${auth.reason ?? "unauthorized"}`);
3736
- return;
3737
- }
3738
- return {
3739
- channelLabel: resolveSlackChannelLabel({
3740
- channelId,
3741
- channelName: auth.channelName
3742
- }),
3743
- route: ctx.resolveSlackSystemEventRoute({
3744
- channelId,
3745
- channelType: auth.channelType,
3746
- senderId,
3747
- threadTs: auth.channelType === "im" ? void 0 : params.threadTs,
3748
- eventScope: params.eventScope
3749
- })
3750
- };
3751
- }
3752
- function resolveSlackListenerEventScope(params) {
3753
- return resolveSlackListenerEventScope$1({
3754
- identity: params.ctx.installationIdentity,
3755
- body: params.body,
3756
- context: params.context,
3757
- client: params.client,
3758
- clientOptions: params.ctx.app.webClientOptions,
3759
- onDrop: (reason) => logVerbose(`slack: drop listener event (${reason})`)
3760
- });
3761
- }
3762
- //#endregion
3763
3652
  //#region extensions/slack/src/monitor/events/agent.ts
3764
3653
  function registerSlackAgentEvents(params) {
3765
3654
  const { ctx, trackEvent } = params;
@@ -3778,7 +3667,7 @@ function registerSlackAgentEvents(params) {
3778
3667
  });
3779
3668
  ctx.app.event("agent_session_stopped", async ({ event, body, context, client }) => {
3780
3669
  if (ctx.shouldDropMismatchedSlackEvent(body)) return;
3781
- const eventScope = resolveSlackListenerEventScope({
3670
+ const eventScope = resolveSlackMonitorEventScope({
3782
3671
  ctx,
3783
3672
  body,
3784
3673
  context,
@@ -3843,7 +3732,7 @@ function registerSlackAgentEvents(params) {
3843
3732
  accountId: runtimeContext.accountId
3844
3733
  });
3845
3734
  if (runtimeContext.shouldDropMismatchedSlackEvent(body)) return;
3846
- const eventScope = resolveSlackListenerEventScope({
3735
+ const eventScope = resolveSlackMonitorEventScope({
3847
3736
  ctx: runtimeContext,
3848
3737
  body,
3849
3738
  context,
@@ -3878,9 +3767,7 @@ function registerSlackAgentEvents(params) {
3878
3767
  storePath: resolveStorePath(runtimeContext.cfg.session?.store, { agentId: routing.route.agentId }),
3879
3768
  sessionKey: routing.sessionKey,
3880
3769
  preserveActivity: true,
3881
- assertCommitAllowed: () => {
3882
- if (!routing.isCurrentSession()) throw new Error("Slack conversation owner changed before the title update");
3883
- },
3770
+ assertCommitAllowed: routing.assertCurrentSession,
3884
3771
  update: () => ({ displayName: event.title })
3885
3772
  })) throw new Error("Slack conversation session disappeared before the title update");
3886
3773
  runtimeContext.recordSlackSessionTitle({
@@ -4015,7 +3902,7 @@ function registerSlackChannelEvents(params) {
4015
3902
  const { ctx, trackEvent } = params;
4016
3903
  for (const [eventName, kind] of [["channel_created", "created"], ["channel_rename", "renamed"]]) ctx.app.event(eventName, async (args) => {
4017
3904
  const { event, body, context, client } = args;
4018
- const eventScope = resolveSlackListenerEventScope({
3905
+ const eventScope = resolveSlackMonitorEventScope({
4019
3906
  ctx,
4020
3907
  body,
4021
3908
  context,
@@ -4180,18 +4067,117 @@ async function dispatchSlackPluginInteractiveHandler(params) {
4180
4067
  }
4181
4068
  //#endregion
4182
4069
  //#region extensions/slack/src/monitor/events/interaction-event.ts
4183
- function enqueueSlackInteractionEvent(...args) {
4184
- if (enqueueRoutedSystemEvent(...args)) {
4185
- const route = args[1];
4186
- requestHeartbeat({
4187
- source: "hook",
4188
- intent: "immediate",
4189
- reason: "hook:slack-interaction",
4190
- agentId: route.agentId,
4191
- sessionKey: route.sessionKey,
4192
- heartbeat: { target: "last" }
4193
- });
4070
+ const SLACK_INTERACTION_EVENT_PREFIX = "Slack interaction: ";
4071
+ const REDACTED_INTERACTION_VALUE = "[redacted]";
4072
+ const SLACK_INTERACTION_EVENT_MAX_CHARS = 2400;
4073
+ const SLACK_INTERACTION_STRING_MAX_CHARS = 160;
4074
+ const SLACK_INTERACTION_ARRAY_MAX_ITEMS = 64;
4075
+ const SLACK_INTERACTION_COMPACT_INPUTS_MAX_ITEMS = 3;
4076
+ const SLACK_INTERACTION_REDACTED_KEYS = /* @__PURE__ */ new Set([
4077
+ "triggerId",
4078
+ "responseUrl",
4079
+ "workflowTriggerUrl",
4080
+ "privateMetadata",
4081
+ "viewHash"
4082
+ ]);
4083
+ function sanitizeSlackInteractionPayloadValue(value, key) {
4084
+ if (value === void 0) return;
4085
+ if (key && SLACK_INTERACTION_REDACTED_KEYS.has(key)) {
4086
+ if (typeof value !== "string" || value.trim().length === 0) return;
4087
+ return REDACTED_INTERACTION_VALUE;
4088
+ }
4089
+ if (typeof value === "string") return truncateSlackText(value, SLACK_INTERACTION_STRING_MAX_CHARS);
4090
+ if (Array.isArray(value)) {
4091
+ const sanitized = value.slice(0, SLACK_INTERACTION_ARRAY_MAX_ITEMS).map((entry) => sanitizeSlackInteractionPayloadValue(entry)).filter((entry) => entry !== void 0);
4092
+ if (value.length > SLACK_INTERACTION_ARRAY_MAX_ITEMS) sanitized.push(`…+${value.length - SLACK_INTERACTION_ARRAY_MAX_ITEMS} more`);
4093
+ return sanitized;
4094
+ }
4095
+ if (!value || typeof value !== "object") return value;
4096
+ const output = {};
4097
+ for (const [entryKey, entryValue] of Object.entries(value)) {
4098
+ const sanitized = sanitizeSlackInteractionPayloadValue(entryValue, entryKey);
4099
+ if (sanitized === void 0) continue;
4100
+ if (typeof sanitized === "string" && sanitized.length === 0) continue;
4101
+ if (Array.isArray(sanitized) && sanitized.length === 0) continue;
4102
+ output[entryKey] = sanitized;
4194
4103
  }
4104
+ return output;
4105
+ }
4106
+ function buildCompactSlackInteractionPayload(payload) {
4107
+ const rawInputs = Array.isArray(payload.inputs) ? payload.inputs : [];
4108
+ const compactInputs = rawInputs.slice(0, SLACK_INTERACTION_COMPACT_INPUTS_MAX_ITEMS).flatMap((entry) => {
4109
+ const typed = asOptionalObjectRecord(entry);
4110
+ if (!typed) return [];
4111
+ return [{
4112
+ actionId: typed.actionId,
4113
+ blockId: typed.blockId,
4114
+ actionType: typed.actionType,
4115
+ inputKind: typed.inputKind,
4116
+ selectedValues: typed.selectedValues,
4117
+ selectedLabels: typed.selectedLabels,
4118
+ inputValue: typed.inputValue,
4119
+ inputNumber: typed.inputNumber,
4120
+ selectedDate: typed.selectedDate,
4121
+ selectedTime: typed.selectedTime,
4122
+ selectedDateTime: typed.selectedDateTime,
4123
+ richTextPreview: typed.richTextPreview
4124
+ }];
4125
+ });
4126
+ return {
4127
+ interactionType: payload.interactionType,
4128
+ actionId: payload.actionId,
4129
+ callbackId: payload.callbackId,
4130
+ actionType: payload.actionType,
4131
+ actionTs: payload.actionTs,
4132
+ userId: payload.userId,
4133
+ teamId: payload.teamId,
4134
+ channelId: payload.channelId ?? payload.routedChannelId,
4135
+ messageTs: payload.messageTs,
4136
+ threadTs: payload.threadTs,
4137
+ messageUserId: payload.messageUserId,
4138
+ messageText: payload.messageText,
4139
+ viewId: payload.viewId,
4140
+ isCleared: payload.isCleared,
4141
+ selectedValues: payload.selectedValues,
4142
+ selectedLabels: payload.selectedLabels,
4143
+ selectedDate: payload.selectedDate,
4144
+ selectedTime: payload.selectedTime,
4145
+ selectedDateTime: payload.selectedDateTime,
4146
+ workflowId: payload.workflowId,
4147
+ routedChannelType: payload.routedChannelType,
4148
+ pluginHandled: payload.pluginHandled,
4149
+ pluginNamespace: payload.pluginNamespace,
4150
+ pluginDuplicate: payload.pluginDuplicate,
4151
+ pluginSystemEvent: payload.pluginSystemEvent,
4152
+ inputs: compactInputs.length > 0 ? compactInputs : void 0,
4153
+ inputsOmitted: rawInputs.length > SLACK_INTERACTION_COMPACT_INPUTS_MAX_ITEMS ? rawInputs.length - SLACK_INTERACTION_COMPACT_INPUTS_MAX_ITEMS : void 0,
4154
+ payloadTruncated: true
4155
+ };
4156
+ }
4157
+ function formatSlackInteractionSystemEvent(payload) {
4158
+ const toEventText = (value) => `${SLACK_INTERACTION_EVENT_PREFIX}${JSON.stringify(value)}`;
4159
+ const sanitizedPayload = sanitizeSlackInteractionPayloadValue(payload) ?? {};
4160
+ let eventText = toEventText(sanitizedPayload);
4161
+ if (eventText.length <= SLACK_INTERACTION_EVENT_MAX_CHARS) return eventText;
4162
+ eventText = toEventText(sanitizeSlackInteractionPayloadValue(buildCompactSlackInteractionPayload(sanitizedPayload)));
4163
+ if (eventText.length <= SLACK_INTERACTION_EVENT_MAX_CHARS) return eventText;
4164
+ return toEventText({
4165
+ interactionType: sanitizedPayload.interactionType,
4166
+ actionId: sanitizedPayload.actionId ?? "unknown",
4167
+ userId: sanitizedPayload.userId,
4168
+ channelId: sanitizedPayload.channelId ?? sanitizedPayload.routedChannelId,
4169
+ payloadTruncated: true
4170
+ });
4171
+ }
4172
+ function enqueueSlackInteractionEvent(payload, route, options) {
4173
+ if (enqueueRoutedSystemEvent(formatSlackInteractionSystemEvent(payload), route, options)) requestHeartbeat({
4174
+ source: "hook",
4175
+ intent: "immediate",
4176
+ reason: "hook:slack-interaction",
4177
+ agentId: route.agentId,
4178
+ sessionKey: route.sessionKey,
4179
+ heartbeat: { target: "last" }
4180
+ });
4195
4181
  }
4196
4182
  //#endregion
4197
4183
  //#region extensions/slack/src/monitor/events/interactions.approval-sender.ts
@@ -4211,14 +4197,14 @@ function resolveSlackPluginApprovalSender(params) {
4211
4197
  };
4212
4198
  }
4213
4199
  //#endregion
4214
- //#region extensions/slack/src/monitor/events/interactions.block-actions.ts
4200
+ //#region extensions/slack/src/monitor/events/modal-input-summary.ts
4215
4201
  function readOptionStrings(options, read) {
4216
4202
  if (!Array.isArray(options)) return [];
4217
4203
  return options.map((option) => option && typeof option === "object" ? read(option) : void 0).filter((value) => typeof value === "string" && value.trim().length > 0);
4218
4204
  }
4219
4205
  function collectRichTextFragments(value, out) {
4220
- if (!value || typeof value !== "object") return;
4221
- const typed = value;
4206
+ const typed = asOptionalObjectRecord(value);
4207
+ if (!typed) return;
4222
4208
  if (typeof typed.text === "string" && typed.text.trim().length > 0) out.push(typed.text.trim());
4223
4209
  if (Array.isArray(typed.elements)) for (const child of typed.elements) collectRichTextFragments(child, out);
4224
4210
  }
@@ -4246,12 +4232,7 @@ function summarizeAction(action) {
4246
4232
  const inputValue = typeof typed.value === "string" ? typed.value : void 0;
4247
4233
  const inputNumber = actionType === "number_input" && inputValue != null ? parseStrictFiniteNumber(inputValue) : void 0;
4248
4234
  const inputEmail = actionType === "email_text_input" && inputValue?.includes("@") ? inputValue : void 0;
4249
- let inputUrl;
4250
- if (actionType === "url_text_input" && inputValue) try {
4251
- inputUrl = new URL(inputValue).toString();
4252
- } catch {
4253
- inputUrl = void 0;
4254
- }
4235
+ const inputUrl = actionType === "url_text_input" && inputValue ? URL.parse(inputValue)?.toString() : void 0;
4255
4236
  const richTextValue = actionType === "rich_text_input" ? typed.rich_text_value : void 0;
4256
4237
  const richTextPreview = summarizeRichTextPreview(richTextValue);
4257
4238
  return {
@@ -4276,10 +4257,32 @@ function summarizeAction(action) {
4276
4257
  workflowId: typed.workflow?.workflow_id
4277
4258
  };
4278
4259
  }
4279
- function formatInteractionSelectionLabel(params) {
4280
- if (params.summary.actionType === "button" && params.buttonText?.trim()) return params.buttonText.trim();
4281
- const selected = params.summary.selectedLabels?.length ? params.summary.selectedLabels : params.summary.selectedValues;
4282
- if (selected?.length) return selected.length <= 3 ? selected.join(", ") : `${selected.slice(0, 3).join(", ")} +${selected.length - 3}`;
4260
+ function summarizeSlackViewState(values) {
4261
+ const blocks = asOptionalObjectRecord(values);
4262
+ if (!blocks) return [];
4263
+ const entries = [];
4264
+ for (const [blockId, blockValue] of Object.entries(blocks)) {
4265
+ const actions = asOptionalObjectRecord(blockValue);
4266
+ if (!actions) continue;
4267
+ for (const [actionId, rawAction] of Object.entries(actions)) {
4268
+ const action = asOptionalObjectRecord(rawAction);
4269
+ if (!action) continue;
4270
+ const actionSummary = summarizeAction(action);
4271
+ entries.push({
4272
+ blockId,
4273
+ actionId,
4274
+ ...actionSummary
4275
+ });
4276
+ }
4277
+ }
4278
+ return entries;
4279
+ }
4280
+ //#endregion
4281
+ //#region extensions/slack/src/monitor/events/interactions.block-actions.ts
4282
+ function formatInteractionSelectionLabel(params) {
4283
+ if (params.summary.actionType === "button" && params.buttonText?.trim()) return params.buttonText.trim();
4284
+ const selected = params.summary.selectedLabels?.length ? params.summary.selectedLabels : params.summary.selectedValues;
4285
+ if (selected?.length) return selected.length <= 3 ? selected.join(", ") : `${selected.slice(0, 3).join(", ")} +${selected.length - 3}`;
4283
4286
  if (params.summary.selectedDate) return params.summary.selectedDate;
4284
4287
  if (params.summary.selectedTime) return params.summary.selectedTime;
4285
4288
  if (typeof params.summary.selectedDateTime === "number") {
@@ -4458,7 +4461,7 @@ async function handleSlackApprovalInteraction(params) {
4458
4461
  channelId,
4459
4462
  messageTs
4460
4463
  }, async () => {
4461
- const { readSlackMessages } = await import("./actions-DDoAJnrH.mjs").then((n) => n.t);
4464
+ const { readSlackMessages } = await import("./actions-KGKwTAKO.mjs").then((n) => n.t);
4462
4465
  const { messages } = await readSlackMessages(channelId, {
4463
4466
  client: params.eventScope?.client ?? params.ctx.app.client,
4464
4467
  messageId: messageTs,
@@ -4657,23 +4660,21 @@ function enqueueSlackBlockActionEvent(params) {
4657
4660
  threadTs: params.parsed.threadTs
4658
4661
  };
4659
4662
  params.ctx.runtime.log?.(`slack:interaction action=${params.parsed.actionId} type=${params.parsed.actionSummary.actionType ?? "unknown"} user=${params.parsed.userId} channel=${params.parsed.channelId}`);
4660
- const route = params.ctx.resolveSlackSystemEventRoute({
4663
+ enqueueSlackInteractionEvent(eventPayload, params.ctx.resolveSlackSystemEventRoute({
4661
4664
  channelId: params.parsed.channelId,
4662
4665
  channelType: params.auth.channelType,
4663
4666
  senderId: params.parsed.userId,
4664
4667
  threadTs: params.parsed.threadTs,
4665
4668
  eventScope: params.eventScope
4666
- });
4667
- const contextParts = [
4668
- "slack:interaction",
4669
- params.teamId,
4670
- params.parsed.channelId,
4671
- params.parsed.messageTs,
4672
- params.parsed.actionId,
4673
- normalizeOptionalString(params.parsed.typedActionWithText.action_ts) ?? params.parsed.typedBody.trigger_id
4674
- ].filter(Boolean);
4675
- enqueueSlackInteractionEvent(params.formatSystemEvent(eventPayload), route, {
4676
- contextKey: contextParts.join(":"),
4669
+ }), {
4670
+ contextKey: [
4671
+ "slack:interaction",
4672
+ params.teamId,
4673
+ params.parsed.channelId,
4674
+ params.parsed.messageTs,
4675
+ params.parsed.actionId,
4676
+ normalizeOptionalString(params.parsed.typedActionWithText.action_ts) ?? params.parsed.typedBody.trigger_id
4677
+ ].filter(Boolean).join(":"),
4677
4678
  deliveryContext: {
4678
4679
  channel: "slack",
4679
4680
  to: deferredTarget?.target,
@@ -4723,12 +4724,11 @@ function registerSlackBlockActionHandler(params) {
4723
4724
  const { ack, body, action, respond } = args;
4724
4725
  await ack();
4725
4726
  const runtimeContext = await params.ctx.readRuntimeContext();
4726
- const eventScope = resolveSlackListenerEventScope$1({
4727
- identity: runtimeContext.installationIdentity,
4727
+ const eventScope = resolveSlackMonitorEventScope({
4728
+ ctx: runtimeContext,
4728
4729
  body,
4729
4730
  context: args.context,
4730
4731
  client: args.client,
4731
- clientOptions: runtimeContext.app.webClientOptions,
4732
4732
  onDrop: (reason) => runtimeContext.runtime.log?.(`slack:interaction drop action ${reason}`)
4733
4733
  });
4734
4734
  if (eventScope === null) return;
@@ -4811,8 +4811,7 @@ function registerSlackBlockActionHandler(params) {
4811
4811
  enqueueSlackBlockActionEvent({
4812
4812
  ...actionContext,
4813
4813
  teamId: args.context.teamId,
4814
- auth,
4815
- formatSystemEvent: params.formatSystemEvent
4814
+ auth
4816
4815
  });
4817
4816
  await updateSlackLegacyBlockAction(actionContext);
4818
4817
  });
@@ -4850,14 +4849,12 @@ function shouldHandleSlackModalLifecycleBody(body) {
4850
4849
  return Boolean(metadata.pluginInteractiveData?.trim());
4851
4850
  }
4852
4851
  function resolveSlackPluginSystemEventPayload(result) {
4853
- if (!result || typeof result !== "object") return;
4854
- const systemEvent = result.systemEvent;
4855
- if (!systemEvent || typeof systemEvent !== "object") return;
4856
- const typed = systemEvent;
4852
+ const systemEvent = asOptionalObjectRecord(asOptionalObjectRecord(result)?.systemEvent);
4853
+ if (!systemEvent) return;
4857
4854
  const output = {};
4858
- if (typeof typed.summary === "string" && typed.summary.trim()) output.summary = typed.summary;
4859
- if (typeof typed.reference === "string" && typed.reference.trim()) output.reference = typed.reference;
4860
- if (typed.data && typeof typed.data === "object" && !Array.isArray(typed.data)) output.data = typed.data;
4855
+ if (typeof systemEvent.summary === "string" && systemEvent.summary.trim()) output.summary = systemEvent.summary;
4856
+ if (typeof systemEvent.reference === "string" && systemEvent.reference.trim()) output.reference = systemEvent.reference;
4857
+ if (systemEvent.data && typeof systemEvent.data === "object" && !Array.isArray(systemEvent.data)) output.data = systemEvent.data;
4861
4858
  return Object.keys(output).length > 0 ? output : void 0;
4862
4859
  }
4863
4860
  function resolveModalSessionRouting(params) {
@@ -4869,22 +4866,19 @@ function resolveModalSessionRouting(params) {
4869
4866
  channelId: metadata.channelId,
4870
4867
  channelType: metadata.channelType
4871
4868
  };
4872
- const routing = metadata.channelId ? {
4873
- ...params.ctx.resolveSlackSystemEventRoute({
4874
- channelId: metadata.channelId,
4875
- channelType: metadata.channelType,
4876
- senderId: params.userId,
4877
- eventScope: params.eventScope
4878
- }),
4879
- channelId: metadata.channelId,
4880
- channelType: metadata.channelType
4881
- } : {
4869
+ const routing = {
4882
4870
  ...params.ctx.resolveSlackSystemEventRoute({
4883
- channelType: "im",
4871
+ ...metadata.channelId ? {
4872
+ channelId: metadata.channelId,
4873
+ channelType: metadata.channelType
4874
+ } : { channelType: "im" },
4884
4875
  senderId: params.userId,
4885
4876
  eventScope: params.eventScope
4886
4877
  }),
4887
- channelType: params.eventScope ? "im" : void 0
4878
+ ...metadata.channelId ? {
4879
+ channelId: metadata.channelId,
4880
+ channelType: metadata.channelType
4881
+ } : { channelType: params.eventScope ? "im" : void 0 }
4888
4882
  };
4889
4883
  if (metadata.sessionKey && (metadata.sessionKey === routing.sessionKey || metadata.sessionKey.startsWith(`${routing.sessionKey}:thread:`))) return {
4890
4884
  ...routing,
@@ -4892,105 +4886,35 @@ function resolveModalSessionRouting(params) {
4892
4886
  };
4893
4887
  return routing;
4894
4888
  }
4895
- function resolveSlackModalEventBase(params) {
4889
+ async function emitSlackModalLifecycleEvent(params) {
4896
4890
  const metadata = parseSlackModalPrivateMetadata(params.body.view?.private_metadata);
4897
4891
  const callbackId = params.body.view?.callback_id ?? "unknown";
4898
4892
  const userId = params.body.user?.id ?? "unknown";
4899
4893
  const viewId = params.body.view?.id;
4900
- const inputs = params.summarizeViewState(params.body.view?.state?.values);
4894
+ const inputs = summarizeSlackViewState(params.body.view?.state?.values);
4901
4895
  const sessionRouting = resolveModalSessionRouting({
4902
4896
  ctx: params.ctx,
4903
4897
  metadata,
4904
4898
  userId,
4905
4899
  eventScope: params.eventScope
4906
4900
  });
4907
- return {
4901
+ const stateValues = params.body.view?.state?.values;
4902
+ const payload = {
4903
+ actionId: `view:${callbackId}`,
4908
4904
  callbackId,
4909
- userId,
4910
- metadata,
4911
4905
  viewId,
4912
- sessionRouting,
4913
- stateValues: params.body.view?.state?.values,
4914
- payload: {
4915
- actionId: `view:${callbackId}`,
4916
- callbackId,
4917
- viewId,
4918
- userId,
4919
- teamId: params.teamId,
4920
- rootViewId: params.body.view?.root_view_id,
4921
- previousViewId: params.body.view?.previous_view_id,
4922
- externalId: params.body.view?.external_id,
4923
- viewHash: params.body.view?.hash,
4924
- isStackedView: Boolean(params.body.view?.previous_view_id),
4925
- privateMetadata: params.body.view?.private_metadata,
4926
- routedChannelId: sessionRouting.channelId,
4927
- routedChannelType: sessionRouting.channelType,
4928
- inputs
4929
- }
4930
- };
4931
- }
4932
- async function dispatchSlackModalPluginInteractiveHandler(params) {
4933
- if (!params.data) return {
4934
- matched: false,
4935
- handled: false,
4936
- duplicate: false
4937
- };
4938
- const isViewClosed = params.interactionType === "view_closed";
4939
- const interactionId = [
4940
- params.interactionType,
4941
- params.payload.callbackId,
4942
- params.payload.viewId,
4943
- params.payload.userId
4944
- ].filter(Boolean).join(":");
4945
- const result = await dispatchSlackPluginInteractiveHandler({
4946
- data: params.data,
4947
- interactionId,
4948
- teamId: params.eventScope?.teamId,
4949
- channelType: params.channelType,
4950
- ctx: {
4951
- accountId: params.ctx.accountId,
4952
- interactionId,
4953
- conversationId: params.sessionRouting.channelId ?? "",
4954
- parentConversationId: void 0,
4955
- threadId: void 0,
4956
- senderId: params.payload.userId,
4957
- senderUsername: void 0,
4958
- auth: params.auth,
4959
- interaction: {
4960
- kind: params.interactionType,
4961
- callbackId: params.payload.callbackId,
4962
- viewId: params.payload.viewId,
4963
- rootViewId: params.payload.rootViewId,
4964
- previousViewId: params.payload.previousViewId,
4965
- externalId: params.payload.externalId,
4966
- isStackedView: params.payload.isStackedView,
4967
- isCleared: isViewClosed ? params.body.is_cleared === true : void 0,
4968
- inputs: params.payload.inputs,
4969
- stateValues: params.stateValues,
4970
- triggerId: params.body.trigger_id
4971
- }
4972
- },
4973
- respond: {
4974
- acknowledge: async () => {},
4975
- reply: async () => {},
4976
- followUp: async () => {},
4977
- editMessage: async () => {}
4978
- }
4979
- });
4980
- return {
4981
- ...result,
4982
- namespace: result.matched ? params.data.split(":", 1)[0] : void 0,
4983
- systemEvent: result.matched ? resolveSlackPluginSystemEventPayload(result.result) : void 0
4984
- };
4985
- }
4986
- async function emitSlackModalLifecycleEvent(params) {
4987
- const { callbackId, userId, metadata, viewId, sessionRouting, stateValues, payload } = resolveSlackModalEventBase({
4988
- ctx: params.ctx,
4989
- body: params.body,
4990
- eventScope: params.eventScope,
4906
+ userId,
4991
4907
  teamId: params.teamId,
4992
- summarizeViewState: params.summarizeViewState
4993
- });
4908
+ rootViewId: params.body.view?.root_view_id,
4909
+ previousViewId: params.body.view?.previous_view_id,
4910
+ externalId: params.body.view?.external_id,
4911
+ viewHash: params.body.view?.hash,
4912
+ isStackedView: Boolean(params.body.view?.previous_view_id),
4913
+ privateMetadata: params.body.view?.private_metadata,
4914
+ routedChannelId: sessionRouting.channelId,
4915
+ routedChannelType: sessionRouting.channelType,
4916
+ inputs
4917
+ };
4994
4918
  const pluginInteractiveData = resolveSlackModalPluginInteractiveData({
4995
4919
  callbackId,
4996
4920
  metadata
@@ -5006,18 +4930,53 @@ async function emitSlackModalLifecycleEvent(params) {
5006
4930
  else params.ctx.runtime.log?.(`slack:interaction view_submission callback=${callbackId} user=${userId} inputs=${payload.inputs.length}`);
5007
4931
  const dispatchPlugin = async (isAuthorizedSender, channelType) => {
5008
4932
  try {
5009
- return await dispatchSlackModalPluginInteractiveHandler({
5010
- ctx: params.ctx,
5011
- body: params.body,
5012
- eventScope: params.eventScope,
5013
- interactionType: params.interactionType,
4933
+ if (!pluginInteractiveData) return;
4934
+ const interactionId = [
4935
+ params.interactionType,
4936
+ payload.callbackId,
4937
+ payload.viewId,
4938
+ payload.userId
4939
+ ].filter(Boolean).join(":");
4940
+ const result = await dispatchSlackPluginInteractiveHandler({
5014
4941
  data: pluginInteractiveData,
5015
- auth: { isAuthorizedSender },
4942
+ interactionId,
4943
+ teamId: params.eventScope?.teamId,
5016
4944
  channelType,
5017
- payload,
5018
- stateValues,
5019
- sessionRouting
4945
+ ctx: {
4946
+ accountId: params.ctx.accountId,
4947
+ interactionId,
4948
+ conversationId: sessionRouting.channelId ?? "",
4949
+ parentConversationId: void 0,
4950
+ threadId: void 0,
4951
+ senderId: payload.userId,
4952
+ senderUsername: void 0,
4953
+ auth: { isAuthorizedSender },
4954
+ interaction: {
4955
+ kind: params.interactionType,
4956
+ callbackId: payload.callbackId,
4957
+ viewId: payload.viewId,
4958
+ rootViewId: payload.rootViewId,
4959
+ previousViewId: payload.previousViewId,
4960
+ externalId: payload.externalId,
4961
+ isStackedView: payload.isStackedView,
4962
+ isCleared: isViewClosed ? params.body.is_cleared === true : void 0,
4963
+ inputs: payload.inputs,
4964
+ stateValues,
4965
+ triggerId: params.body.trigger_id
4966
+ }
4967
+ },
4968
+ respond: {
4969
+ acknowledge: async () => {},
4970
+ reply: async () => {},
4971
+ followUp: async () => {},
4972
+ editMessage: async () => {}
4973
+ }
5020
4974
  });
4975
+ return {
4976
+ ...result,
4977
+ namespace: result.matched ? pluginInteractiveData.split(":", 1)[0] : void 0,
4978
+ systemEvent: result.matched ? resolveSlackPluginSystemEventPayload(result.result) : void 0
4979
+ };
5021
4980
  } catch (error) {
5022
4981
  params.ctx.runtime.log?.(`slack:interaction modal plugin dispatch failed callback=${callbackId} error=${error instanceof Error ? error.message : String(error)}`);
5023
4982
  return;
@@ -5055,12 +5014,12 @@ async function emitSlackModalLifecycleEvent(params) {
5055
5014
  kind: targetKind,
5056
5015
  id: targetId
5057
5016
  }) : void 0;
5058
- enqueueSlackInteractionEvent(params.formatSystemEvent({
5017
+ enqueueSlackInteractionEvent({
5059
5018
  ...eventPayload,
5060
5019
  ...pluginEventFields
5061
- }), sessionRouting, {
5020
+ }, sessionRouting, {
5062
5021
  contextKey: [
5063
- params.contextPrefix,
5022
+ isViewClosed ? "slack:interaction:view-closed" : "slack:interaction:view",
5064
5023
  params.teamId,
5065
5024
  callbackId,
5066
5025
  viewId,
@@ -5074,16 +5033,18 @@ async function emitSlackModalLifecycleEvent(params) {
5074
5033
  });
5075
5034
  }
5076
5035
  function registerModalLifecycleHandler(params) {
5077
- params.register(params.matcher, async (args) => {
5036
+ params.ctx.app.view({
5037
+ callback_id: /.*/,
5038
+ type: params.interactionType
5039
+ }, async (args) => {
5078
5040
  const { ack, body } = args;
5079
5041
  if (!shouldHandleSlackModalLifecycleBody(body)) return;
5080
5042
  await ack();
5081
- const eventScope = resolveSlackListenerEventScope$1({
5082
- identity: params.ctx.installationIdentity,
5043
+ const eventScope = resolveSlackMonitorEventScope({
5044
+ ctx: params.ctx,
5083
5045
  body,
5084
5046
  context: args.context,
5085
5047
  client: args.client,
5086
- clientOptions: params.ctx.app.webClientOptions,
5087
5048
  onDrop: (reason) => params.ctx.runtime.log?.(`slack:interaction drop ${params.interactionType} ${reason}`)
5088
5049
  });
5089
5050
  if (eventScope === null) return;
@@ -5098,10 +5059,7 @@ function registerModalLifecycleHandler(params) {
5098
5059
  body: typedBody,
5099
5060
  eventScope,
5100
5061
  teamId: args.context.teamId,
5101
- interactionType: params.interactionType,
5102
- contextPrefix: params.contextPrefix,
5103
- summarizeViewState: params.summarizeViewState,
5104
- formatSystemEvent: params.formatSystemEvent
5062
+ interactionType: params.interactionType
5105
5063
  });
5106
5064
  });
5107
5065
  }
@@ -5113,12 +5071,11 @@ function registerSlackShortcutHandler(params) {
5113
5071
  const { ack, body } = args;
5114
5072
  await ack();
5115
5073
  const runtimeContext = await params.ctx.readRuntimeContext();
5116
- const eventScope = resolveSlackListenerEventScope$1({
5117
- identity: runtimeContext.installationIdentity,
5074
+ const eventScope = resolveSlackMonitorEventScope({
5075
+ ctx: runtimeContext,
5118
5076
  body,
5119
5077
  context: args.context,
5120
5078
  client: args.client,
5121
- clientOptions: runtimeContext.app.webClientOptions,
5122
5079
  onDrop: (reason) => runtimeContext.runtime.log?.(`slack:interaction drop shortcut ${reason}`)
5123
5080
  });
5124
5081
  if (eventScope === null) return;
@@ -5195,7 +5152,7 @@ function registerSlackShortcutHandler(params) {
5195
5152
  body.action_ts
5196
5153
  ].filter(Boolean).join(":");
5197
5154
  runtimeContext.runtime.log?.(`slack:interaction ${interactionType} callback=${callbackId} user=${userId} channel=${channelId ?? "direct"}`);
5198
- enqueueSlackInteractionEvent(params.formatSystemEvent(eventPayload), route, {
5155
+ enqueueSlackInteractionEvent(eventPayload, route, {
5199
5156
  contextKey,
5200
5157
  deliveryContext: {
5201
5158
  channel: "slack",
@@ -5208,152 +5165,47 @@ function registerSlackShortcutHandler(params) {
5208
5165
  }
5209
5166
  //#endregion
5210
5167
  //#region extensions/slack/src/monitor/events/interactions.ts
5211
- const SLACK_INTERACTION_EVENT_PREFIX = "Slack interaction: ";
5212
- const REDACTED_INTERACTION_VALUE = "[redacted]";
5213
- const SLACK_INTERACTION_EVENT_MAX_CHARS = 2400;
5214
- const SLACK_INTERACTION_STRING_MAX_CHARS = 160;
5215
- const SLACK_INTERACTION_ARRAY_MAX_ITEMS = 64;
5216
- const SLACK_INTERACTION_COMPACT_INPUTS_MAX_ITEMS = 3;
5217
- const SLACK_INTERACTION_REDACTED_KEYS = /* @__PURE__ */ new Set([
5218
- "triggerId",
5219
- "responseUrl",
5220
- "workflowTriggerUrl",
5221
- "privateMetadata",
5222
- "viewHash"
5223
- ]);
5224
- function sanitizeSlackInteractionPayloadValue(value, key) {
5225
- if (value === void 0) return;
5226
- if (key && SLACK_INTERACTION_REDACTED_KEYS.has(key)) {
5227
- if (typeof value !== "string" || value.trim().length === 0) return;
5228
- return REDACTED_INTERACTION_VALUE;
5229
- }
5230
- if (typeof value === "string") return truncateSlackText(value, SLACK_INTERACTION_STRING_MAX_CHARS);
5231
- if (Array.isArray(value)) {
5232
- const sanitized = value.slice(0, SLACK_INTERACTION_ARRAY_MAX_ITEMS).map((entry) => sanitizeSlackInteractionPayloadValue(entry)).filter((entry) => entry !== void 0);
5233
- if (value.length > SLACK_INTERACTION_ARRAY_MAX_ITEMS) sanitized.push(`…+${value.length - SLACK_INTERACTION_ARRAY_MAX_ITEMS} more`);
5234
- return sanitized;
5235
- }
5236
- if (!value || typeof value !== "object") return value;
5237
- const output = {};
5238
- for (const [entryKey, entryValue] of Object.entries(value)) {
5239
- const sanitized = sanitizeSlackInteractionPayloadValue(entryValue, entryKey);
5240
- if (sanitized === void 0) continue;
5241
- if (typeof sanitized === "string" && sanitized.length === 0) continue;
5242
- if (Array.isArray(sanitized) && sanitized.length === 0) continue;
5243
- output[entryKey] = sanitized;
5244
- }
5245
- return output;
5246
- }
5247
- function buildCompactSlackInteractionPayload(payload) {
5248
- const rawInputs = Array.isArray(payload.inputs) ? payload.inputs : [];
5249
- const compactInputs = rawInputs.slice(0, SLACK_INTERACTION_COMPACT_INPUTS_MAX_ITEMS).flatMap((entry) => {
5250
- if (!entry || typeof entry !== "object") return [];
5251
- const typed = entry;
5252
- return [{
5253
- actionId: typed.actionId,
5254
- blockId: typed.blockId,
5255
- actionType: typed.actionType,
5256
- inputKind: typed.inputKind,
5257
- selectedValues: typed.selectedValues,
5258
- selectedLabels: typed.selectedLabels,
5259
- inputValue: typed.inputValue,
5260
- inputNumber: typed.inputNumber,
5261
- selectedDate: typed.selectedDate,
5262
- selectedTime: typed.selectedTime,
5263
- selectedDateTime: typed.selectedDateTime,
5264
- richTextPreview: typed.richTextPreview
5265
- }];
5266
- });
5267
- return {
5268
- interactionType: payload.interactionType,
5269
- actionId: payload.actionId,
5270
- callbackId: payload.callbackId,
5271
- actionType: payload.actionType,
5272
- actionTs: payload.actionTs,
5273
- userId: payload.userId,
5274
- teamId: payload.teamId,
5275
- channelId: payload.channelId ?? payload.routedChannelId,
5276
- messageTs: payload.messageTs,
5277
- threadTs: payload.threadTs,
5278
- messageUserId: payload.messageUserId,
5279
- messageText: payload.messageText,
5280
- viewId: payload.viewId,
5281
- isCleared: payload.isCleared,
5282
- selectedValues: payload.selectedValues,
5283
- selectedLabels: payload.selectedLabels,
5284
- selectedDate: payload.selectedDate,
5285
- selectedTime: payload.selectedTime,
5286
- selectedDateTime: payload.selectedDateTime,
5287
- workflowId: payload.workflowId,
5288
- routedChannelType: payload.routedChannelType,
5289
- pluginHandled: payload.pluginHandled,
5290
- pluginNamespace: payload.pluginNamespace,
5291
- pluginDuplicate: payload.pluginDuplicate,
5292
- pluginSystemEvent: payload.pluginSystemEvent,
5293
- inputs: compactInputs.length > 0 ? compactInputs : void 0,
5294
- inputsOmitted: rawInputs.length > SLACK_INTERACTION_COMPACT_INPUTS_MAX_ITEMS ? rawInputs.length - SLACK_INTERACTION_COMPACT_INPUTS_MAX_ITEMS : void 0,
5295
- payloadTruncated: true
5296
- };
5297
- }
5298
- function formatSlackInteractionSystemEvent(payload) {
5299
- const toEventText = (value) => `${SLACK_INTERACTION_EVENT_PREFIX}${JSON.stringify(value)}`;
5300
- const sanitizedPayload = sanitizeSlackInteractionPayloadValue(payload) ?? {};
5301
- let eventText = toEventText(sanitizedPayload);
5302
- if (eventText.length <= SLACK_INTERACTION_EVENT_MAX_CHARS) return eventText;
5303
- eventText = toEventText(sanitizeSlackInteractionPayloadValue(buildCompactSlackInteractionPayload(sanitizedPayload)));
5304
- if (eventText.length <= SLACK_INTERACTION_EVENT_MAX_CHARS) return eventText;
5305
- return toEventText({
5306
- interactionType: sanitizedPayload.interactionType,
5307
- actionId: sanitizedPayload.actionId ?? "unknown",
5308
- userId: sanitizedPayload.userId,
5309
- channelId: sanitizedPayload.channelId ?? sanitizedPayload.routedChannelId,
5310
- payloadTruncated: true
5311
- });
5312
- }
5313
- function summarizeViewState(values) {
5314
- if (!values || typeof values !== "object") return [];
5315
- const entries = [];
5316
- for (const [blockId, blockValue] of Object.entries(values)) {
5317
- if (!blockValue || typeof blockValue !== "object") continue;
5318
- for (const [actionId, rawAction] of Object.entries(blockValue)) {
5319
- if (!rawAction || typeof rawAction !== "object") continue;
5320
- const actionSummary = summarizeAction(rawAction);
5321
- entries.push({
5322
- blockId,
5323
- actionId,
5324
- ...actionSummary
5325
- });
5326
- }
5327
- }
5328
- return entries;
5329
- }
5330
5168
  function registerSlackInteractionEvents(params) {
5331
5169
  const { ctx, trackEvent } = params;
5332
- registerSlackBlockActionHandler({
5333
- ctx,
5334
- trackEvent,
5335
- formatSystemEvent: formatSlackInteractionSystemEvent
5336
- });
5337
- registerSlackShortcutHandler({
5170
+ registerSlackBlockActionHandler(params);
5171
+ registerSlackShortcutHandler(params);
5172
+ if (typeof ctx.app.view !== "function") return;
5173
+ for (const interactionType of ["view_submission", "view_closed"]) registerModalLifecycleHandler({
5338
5174
  ctx,
5339
5175
  trackEvent,
5340
- formatSystemEvent: formatSlackInteractionSystemEvent
5176
+ interactionType
5341
5177
  });
5342
- if (typeof ctx.app.view !== "function") return;
5343
- const modalMatcher = /.*/;
5344
- for (const [interactionType, contextPrefix] of [["view_submission", "slack:interaction:view"], ["view_closed", "slack:interaction:view-closed"]]) registerModalLifecycleHandler({
5345
- register: (matcher, handler) => ctx.app.view({
5346
- callback_id: matcher,
5347
- type: interactionType
5348
- }, handler),
5349
- matcher: modalMatcher,
5178
+ }
5179
+ //#endregion
5180
+ //#region extensions/slack/src/monitor/events/system-event-context.ts
5181
+ async function authorizeAndResolveSlackSystemEventContext(params) {
5182
+ const { senderId, channelId, channelType, eventKind } = params;
5183
+ const ctx = await params.ctx.readRuntimeContext();
5184
+ const auth = await authorizeSlackSystemEventSender({
5350
5185
  ctx,
5351
- trackEvent,
5352
- interactionType,
5353
- contextPrefix,
5354
- summarizeViewState,
5355
- formatSystemEvent: formatSlackInteractionSystemEvent
5186
+ senderId,
5187
+ channelId,
5188
+ channelType,
5189
+ eventScope: params.eventScope,
5190
+ retryNameLookup: eventKind.startsWith("member-")
5356
5191
  });
5192
+ if (!auth.allowed) {
5193
+ logVerbose(`slack: drop ${eventKind} sender ${senderId ?? "unknown"} channel=${channelId ?? "unknown"} reason=${auth.reason ?? "unauthorized"}`);
5194
+ return;
5195
+ }
5196
+ return {
5197
+ channelLabel: resolveSlackChannelLabel({
5198
+ channelId,
5199
+ channelName: auth.channelName
5200
+ }),
5201
+ route: ctx.resolveSlackSystemEventRoute({
5202
+ channelId,
5203
+ channelType: auth.channelType,
5204
+ senderId,
5205
+ threadTs: auth.channelType === "im" ? void 0 : params.threadTs,
5206
+ eventScope: params.eventScope
5207
+ })
5208
+ };
5357
5209
  }
5358
5210
  //#endregion
5359
5211
  //#region extensions/slack/src/monitor/events/members.ts
@@ -5364,7 +5216,7 @@ function registerSlackMemberEvents(params) {
5364
5216
  const eventId = body.event_id;
5365
5217
  try {
5366
5218
  const runtimeContext = await params.ctx.readRuntimeContext();
5367
- const eventScope = resolveSlackListenerEventScope({
5219
+ const eventScope = resolveSlackMonitorEventScope({
5368
5220
  ctx: runtimeContext,
5369
5221
  body,
5370
5222
  context,
@@ -5497,51 +5349,28 @@ function noteSlackDraftConversationMessage(conversation) {
5497
5349
  }
5498
5350
  //#endregion
5499
5351
  //#region extensions/slack/src/monitor/events/message-subtype-handlers.ts
5500
- function resolveNestedThreadTs(event) {
5501
- const changed = event;
5502
- const message = changed.message?.thread_ts ? changed.message : changed.previous_message;
5503
- if (!message) return;
5504
- return resolveSlackThreadContext({
5505
- message: {
5506
- type: "message",
5507
- channel: event.channel,
5508
- ...message
5509
- },
5510
- replyToMode: "off"
5511
- }).replyToId;
5512
- }
5513
- const SUBTYPE_HANDLER_REGISTRY = {
5514
- message_changed: {
5515
- eventKind: "message_changed",
5516
- describe: (channelLabel) => `Slack message edited in ${channelLabel}.`,
5517
- contextKey: (event) => {
5518
- const changed = event;
5519
- return `slack:message:changed:${changed.channel ?? "unknown"}:${changed.message?.ts ?? changed.previous_message?.ts ?? changed.event_ts ?? "unknown"}`;
5520
- },
5521
- resolveSenderId: (event) => {
5522
- const changed = event;
5523
- return changed.message?.user ?? changed.previous_message?.user ?? changed.message?.bot_id ?? changed.previous_message?.bot_id;
5524
- },
5525
- resolveThreadTs: resolveNestedThreadTs
5526
- },
5527
- message_deleted: {
5528
- eventKind: "message_deleted",
5529
- describe: (channelLabel) => `Slack message deleted in ${channelLabel}.`,
5530
- contextKey: (event) => {
5531
- const deleted = event;
5532
- return `slack:message:deleted:${deleted.channel ?? "unknown"}:${deleted.deleted_ts ?? deleted.event_ts ?? "unknown"}`;
5533
- },
5534
- resolveSenderId: (event) => {
5535
- const deleted = event;
5536
- return deleted.previous_message?.user ?? deleted.previous_message?.bot_id;
5537
- },
5538
- resolveThreadTs: resolveNestedThreadTs
5539
- }
5540
- };
5541
5352
  function resolveSlackMessageSubtypeHandler(event) {
5542
5353
  const subtype = event.subtype;
5543
5354
  if (subtype !== "message_changed" && subtype !== "message_deleted") return;
5544
- return SUBTYPE_HANDLER_REGISTRY[subtype];
5355
+ const changed = event;
5356
+ const message = changed.message?.thread_ts ? changed.message : changed.previous_message;
5357
+ const isChanged = subtype === "message_changed";
5358
+ const senderId = isChanged ? changed.message?.user ?? changed.previous_message?.user ?? changed.message?.bot_id ?? changed.previous_message?.bot_id : changed.previous_message?.user ?? changed.previous_message?.bot_id;
5359
+ const messageId = isChanged ? changed.message?.ts ?? changed.previous_message?.ts ?? changed.event_ts : event.deleted_ts ?? event.event_ts;
5360
+ return {
5361
+ eventKind: subtype,
5362
+ describe: (channelLabel) => `Slack message ${isChanged ? "edited" : "deleted"} in ${channelLabel}.`,
5363
+ contextKey: `slack:message:${isChanged ? "changed" : "deleted"}:${event.channel ?? "unknown"}:${messageId ?? "unknown"}`,
5364
+ senderId,
5365
+ threadTs: message ? resolveSlackThreadContext({
5366
+ message: {
5367
+ type: "message",
5368
+ channel: event.channel,
5369
+ ...message
5370
+ },
5371
+ replyToMode: "off"
5372
+ }).replyToId : void 0
5373
+ };
5545
5374
  }
5546
5375
  //#endregion
5547
5376
  //#region extensions/slack/src/monitor/events/messages.ts
@@ -5551,11 +5380,17 @@ function isBotAuthoredEnterpriseEvent(event) {
5551
5380
  }
5552
5381
  async function resolveSlackAppMentionChannelType(params) {
5553
5382
  const explicitType = normalizeOptionalString(params.mention.channel_type);
5554
- if (explicitType) return normalizeSlackChannelType(explicitType, params.mention.channel);
5383
+ if (explicitType) return { type: normalizeSlackChannelType(explicitType, params.mention.channel) };
5555
5384
  const rememberedType = params.ctx.recallSlackChannelType(params.mention.channel, params.eventScope);
5556
- if (rememberedType) return normalizeSlackChannelType(rememberedType, params.mention.channel);
5557
- const resolved = await params.ctx.resolveChannelName(params.mention.channel, params.eventScope).catch(() => ({ type: void 0 }));
5558
- return resolved.type ? normalizeSlackChannelType(resolved.type, params.mention.channel) : void 0;
5385
+ if (rememberedType) return { type: normalizeSlackChannelType(rememberedType, params.mention.channel) };
5386
+ const resolved = await params.ctx.resolveChannelName(params.mention.channel, params.eventScope).catch(() => ({
5387
+ type: void 0,
5388
+ lookupFailureCategory: "other"
5389
+ }));
5390
+ return {
5391
+ type: resolved.type ? normalizeSlackChannelType(resolved.type, params.mention.channel) : void 0,
5392
+ lookupFailureCategory: resolved.lookupFailureCategory
5393
+ };
5559
5394
  }
5560
5395
  function resolveAssistantMessageChangedSender(params) {
5561
5396
  const payload = asOptionalRecord(asOptionalRecord(params.message?.metadata)?.event_payload);
@@ -5614,14 +5449,6 @@ function resolveAssistantMessageChangedInbound(params) {
5614
5449
  }
5615
5450
  function registerSlackMessageEvents(params) {
5616
5451
  const { ctx, handleSlackMessage } = params;
5617
- const resolveEventScope = (args) => resolveSlackListenerEventScope$1({
5618
- identity: ctx.installationIdentity,
5619
- body: args.body,
5620
- context: args.context,
5621
- client: args.client,
5622
- clientOptions: ctx.app.webClientOptions,
5623
- onDrop: (reason) => logVerbose(`slack: drop event (${reason})`)
5624
- });
5625
5452
  const noteConversationMessage = (message, eventScope) => {
5626
5453
  noteSlackDraftConversationMessage({
5627
5454
  accountId: ctx.accountId,
@@ -5635,96 +5462,82 @@ function registerSlackMessageEvents(params) {
5635
5462
  subtype: "subtype" in message ? normalizeOptionalString(message.subtype) : void 0
5636
5463
  });
5637
5464
  };
5638
- const handleIncomingMessageEvent = async ({ event, body, context, client }) => {
5465
+ for (const source of ["message", "app_mention"]) ctx.app.event(source, async ({ event, body, context, client }) => {
5639
5466
  const turnAdoptionLifecycle = resolveSlackIngressTurnLifecycle(context);
5640
5467
  try {
5641
- const eventScope = resolveEventScope({
5468
+ const eventScope = resolveSlackMonitorEventScope({
5469
+ ctx,
5642
5470
  body,
5643
5471
  context,
5644
- client
5472
+ client,
5473
+ onDrop: (reason) => logVerbose(`slack: drop event (${reason})`)
5645
5474
  });
5646
- if (eventScope === null) return;
5647
- if (ctx.shouldDropMismatchedSlackEvent(body)) return;
5475
+ if (eventScope === null || ctx.shouldDropMismatchedSlackEvent(body)) return;
5648
5476
  const message = event;
5649
- ctx.rememberSlackChannelType(message.channel, message.channel_type, eventScope);
5650
- const assistantChangedInbound = resolveAssistantMessageChangedInbound({
5651
- event: message,
5652
- ctx
5653
- });
5654
- if (!assistantChangedInbound && message.subtype === "message_changed" && isSelfAttributedMessageChange({
5655
- event: message,
5656
- message: asOptionalRecord(message.message),
5657
- ctx
5658
- })) return;
5659
- const subtypeHandler = assistantChangedInbound ? void 0 : resolveSlackMessageSubtypeHandler(message);
5660
- if (subtypeHandler) {
5661
- const ingressContext = await authorizeAndResolveSlackSystemEventContext({
5477
+ let assistantChangedInbound;
5478
+ if (source === "message") {
5479
+ ctx.rememberSlackChannelType(message.channel, message.channel_type, eventScope);
5480
+ assistantChangedInbound = resolveAssistantMessageChangedInbound({
5481
+ event: message,
5482
+ ctx
5483
+ });
5484
+ if (!assistantChangedInbound && message.subtype === "message_changed" && isSelfAttributedMessageChange({
5485
+ event: message,
5486
+ message: asOptionalRecord(message.message),
5487
+ ctx
5488
+ })) return;
5489
+ const subtypeHandler = assistantChangedInbound ? void 0 : resolveSlackMessageSubtypeHandler(message);
5490
+ if (subtypeHandler) {
5491
+ const ingressContext = await authorizeAndResolveSlackSystemEventContext({
5492
+ ctx,
5493
+ senderId: subtypeHandler.senderId,
5494
+ channelId: message.channel,
5495
+ threadTs: subtypeHandler.threadTs,
5496
+ eventKind: subtypeHandler.eventKind,
5497
+ eventScope
5498
+ });
5499
+ if (!ingressContext) return;
5500
+ enqueueRoutedSystemEvent(subtypeHandler.describe(ingressContext.channelLabel), ingressContext.route, { contextKey: `${subtypeHandler.contextKey}:${body.event_id}` });
5501
+ return;
5502
+ }
5503
+ } else {
5504
+ const mention = event;
5505
+ if (eventScope && isBotAuthoredEnterpriseEvent(mention)) {
5506
+ logVerbose("slack: drop enterprise bot-authored app_mention");
5507
+ return;
5508
+ }
5509
+ const { type: channelType, lookupFailureCategory } = await resolveSlackAppMentionChannelType({
5662
5510
  ctx,
5663
- senderId: subtypeHandler.resolveSenderId(message),
5664
- channelId: message.channel,
5665
- threadTs: subtypeHandler.resolveThreadTs(message),
5666
- eventKind: subtypeHandler.eventKind,
5511
+ mention,
5667
5512
  eventScope
5668
5513
  });
5669
- if (!ingressContext) return;
5670
- enqueueRoutedSystemEvent(subtypeHandler.describe(ingressContext.channelLabel), ingressContext.route, { contextKey: `${subtypeHandler.contextKey(message)}:${body.event_id}` });
5671
- return;
5514
+ if (!channelType) {
5515
+ const channelId = /^[CDG][A-Z0-9]{1,32}$/.test(mention.channel) ? mention.channel : "unrecognized";
5516
+ const category = lookupFailureCategory ?? "missing_type";
5517
+ slackInboundLog.info(`Slack app_mention skipped: conversation type unresolved; channelId=${channelId} lookupFailureCategory=${category}; waiting for message event`, {
5518
+ channelId,
5519
+ lookupFailureCategory: category
5520
+ });
5521
+ return;
5522
+ }
5523
+ if (channelType === "im" || channelType === "mpim") return;
5524
+ const from = `slack:${eventScope?.teamId ?? ctx.teamId}:channel:${mention.channel}:user:${normalizeOptionalString(mention.user) ?? "unknown"}`;
5525
+ slackInboundLog.info(`Inbound app_mention ${from} -> bot:${ctx.botUserId} (${channelType}, ${normalizeOptionalString(mention.text)?.length ?? 0} chars)`);
5672
5526
  }
5673
5527
  const inbound = assistantChangedInbound ?? message;
5674
5528
  noteConversationMessage(inbound, eventScope);
5675
5529
  await handleSlackMessage(inbound, {
5676
- source: "message",
5530
+ source,
5677
5531
  senderAuthentication: assistantChangedInbound ? void 0 : resolveSlackSenderAuthentication(context),
5532
+ ...source === "app_mention" ? { wasMentioned: true } : {},
5678
5533
  eventScope,
5679
5534
  ...turnAdoptionLifecycle ? { turnAdoptionLifecycle } : {},
5680
5535
  ...eventScope || turnAdoptionLifecycle ? { awaitDispatch: true } : {}
5681
5536
  });
5682
5537
  } catch (err) {
5683
5538
  if (turnAdoptionLifecycle) throw err;
5684
- ctx.runtime.error?.(danger(`slack handler failed: ${formatErrorMessage(err)}`));
5685
- }
5686
- };
5687
- ctx.app.event("message", handleIncomingMessageEvent);
5688
- ctx.app.event("app_mention", async (args) => {
5689
- const { event, body, context, client } = args;
5690
- const turnAdoptionLifecycle = resolveSlackIngressTurnLifecycle(context);
5691
- try {
5692
- const eventScope = resolveEventScope({
5693
- body,
5694
- context,
5695
- client
5696
- });
5697
- if (eventScope === null) return;
5698
- if (ctx.shouldDropMismatchedSlackEvent(body)) return;
5699
- const mention = event;
5700
- if (eventScope && isBotAuthoredEnterpriseEvent(mention)) {
5701
- logVerbose("slack: drop enterprise bot-authored app_mention");
5702
- return;
5703
- }
5704
- const channelType = await resolveSlackAppMentionChannelType({
5705
- ctx,
5706
- mention,
5707
- eventScope
5708
- });
5709
- if (!channelType) {
5710
- logVerbose(`slack: drop typeless app_mention channel=${mention.channel} (conversation type unresolved; waiting for message event)`);
5711
- return;
5712
- }
5713
- if (channelType === "im" || channelType === "mpim") return;
5714
- const from = `slack:${eventScope?.teamId ?? ctx.teamId}:channel:${mention.channel}:user:${normalizeOptionalString(mention.user) ?? "unknown"}`;
5715
- slackInboundLog.info(`Inbound app_mention ${from} -> bot:${ctx.botUserId} (${channelType}, ${normalizeOptionalString(mention.text)?.length ?? 0} chars)`);
5716
- noteConversationMessage(mention, eventScope);
5717
- await handleSlackMessage(mention, {
5718
- source: "app_mention",
5719
- senderAuthentication: resolveSlackSenderAuthentication(context),
5720
- wasMentioned: true,
5721
- eventScope,
5722
- ...turnAdoptionLifecycle ? { turnAdoptionLifecycle } : {},
5723
- ...eventScope || turnAdoptionLifecycle ? { awaitDispatch: true } : {}
5724
- });
5725
- } catch (err) {
5726
- if (turnAdoptionLifecycle) throw err;
5727
- ctx.runtime.error?.(danger(`slack mention handler failed: ${formatErrorMessage(err)}`));
5539
+ const handler = source === "app_mention" ? "mention handler" : "handler";
5540
+ ctx.runtime.error?.(danger(`slack ${handler} failed: ${formatErrorMessage(err)}`));
5728
5541
  }
5729
5542
  });
5730
5543
  }
@@ -5737,7 +5550,7 @@ function registerSlackPinEvents(params) {
5737
5550
  ctx.app.event(`pin_${contextKeySuffix}`, async (args) => {
5738
5551
  const { event, body, context, client } = args;
5739
5552
  try {
5740
- const eventScope = resolveSlackListenerEventScope({
5553
+ const eventScope = resolveSlackMonitorEventScope({
5741
5554
  ctx,
5742
5555
  body,
5743
5556
  context,
@@ -5791,7 +5604,7 @@ function registerSlackReactionEvents(params) {
5791
5604
  for (const action of ["added", "removed"]) ctx.app.event(`reaction_${action}`, async (args) => {
5792
5605
  const { body, context, client } = args;
5793
5606
  const event = args.event;
5794
- const eventScope = resolveSlackListenerEventScope({
5607
+ const eventScope = resolveSlackMonitorEventScope({
5795
5608
  ctx,
5796
5609
  body,
5797
5610
  context,
@@ -5987,7 +5800,7 @@ function buildSlackDebounceKey(message, accountId, teamId) {
5987
5800
  }
5988
5801
  //#endregion
5989
5802
  //#region extensions/slack/src/monitor/message-handler.ts
5990
- const loadSlackMessagePipeline = createLazyRuntimeModule(() => import("./pipeline.runtime-CIepKmZt.mjs"));
5803
+ const loadSlackMessagePipeline = createLazyRuntimeModule(() => import("./pipeline.runtime-ByPbC6MN.mjs"));
5991
5804
  const RETRYABLE_FLUSH_MAX_ATTEMPTS = 3;
5992
5805
  const RETRYABLE_FLUSH_RETRY_DELAY_MS = 1e3;
5993
5806
  const REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE = /reply session initialization conflicted for \S+/u;
@@ -6345,14 +6158,26 @@ function createSlackPresenceMonitor(params) {
6345
6158
  const scheduler = params.scheduler.scope();
6346
6159
  let started = false;
6347
6160
  const rateLimitedUntilByWorkspace = /* @__PURE__ */ new Map();
6161
+ const collectEligibleSubjects = () => {
6162
+ const subjects = /* @__PURE__ */ new Map();
6163
+ for (const target of targets.values()) {
6164
+ if (!isTargetEligible(target)) continue;
6165
+ for (const userId of target.participants.keys()) {
6166
+ const subject = {
6167
+ teamId: target.teamId,
6168
+ userId
6169
+ };
6170
+ subjects.set(presenceSubjectKey(subject), subject);
6171
+ }
6172
+ }
6173
+ return subjects;
6174
+ };
6348
6175
  const pruneTargets = (now) => {
6349
6176
  for (const [key, target] of targets) if (!target.isPolicyCurrent() || now - target.lastActivityAtMs >= SLACK_PRESENCE_TARGET_TTL_MS) targets.delete(key);
6350
6177
  pruneMapToMaxSize(targets, SLACK_PRESENCE_MAX_TARGETS);
6351
- const eligibleUsers = new Set(Array.from(targets.values()).filter(isTargetEligible).flatMap((target) => Array.from(target.participants.keys()).map((userId) => presenceSubjectKey({
6352
- teamId: target.teamId,
6353
- userId
6354
- }))));
6355
- for (const userId of presenceByUser.keys()) if (!eligibleUsers.has(userId)) presenceByUser.delete(userId);
6178
+ const eligibleSubjects = collectEligibleSubjects();
6179
+ for (const userId of presenceByUser.keys()) if (!eligibleSubjects.has(userId)) presenceByUser.delete(userId);
6180
+ return eligibleSubjects;
6356
6181
  };
6357
6182
  const observe = (prepared) => {
6358
6183
  const now = nowMs();
@@ -6425,19 +6250,7 @@ function createSlackPresenceMonitor(params) {
6425
6250
  };
6426
6251
  const performPoll = async () => {
6427
6252
  const now = nowMs();
6428
- pruneTargets(now);
6429
- const candidatesByKey = /* @__PURE__ */ new Map();
6430
- for (const target of targets.values()) {
6431
- if (!isTargetEligible(target)) continue;
6432
- for (const userId of target.participants.keys()) {
6433
- const subject = {
6434
- teamId: target.teamId,
6435
- userId
6436
- };
6437
- candidatesByKey.set(presenceSubjectKey(subject), subject);
6438
- }
6439
- }
6440
- const candidates = Array.from(candidatesByKey.entries()).toSorted(([left], [right]) => left.localeCompare(right)).map(([, subject]) => subject);
6253
+ const candidates = Array.from(pruneTargets(now).entries()).toSorted(([left], [right]) => left.localeCompare(right)).map(([, subject]) => subject);
6441
6254
  if (candidates.length === 0) return;
6442
6255
  const count = Math.min(candidates.length, SLACK_PRESENCE_MAX_POLLS_PER_INTERVAL);
6443
6256
  const selected = Array.from({ length: count }, (_, index) => candidates[(pollOffset + index) % candidates.length]).filter((subject) => Boolean(subject));
@@ -6532,7 +6345,7 @@ async function getSlackBoltInterop() {
6532
6345
  }
6533
6346
  return slackBoltInterop;
6534
6347
  }
6535
- const loadSlackRelaySource = createLazyRuntimeModule(() => import("./relay-source-CC3h6M7y.mjs"));
6348
+ const loadSlackRelaySource = createLazyRuntimeModule(() => import("./relay-source-CVfH-fBO.mjs"));
6536
6349
  function resolveSlackRuntimeIdentity(params) {
6537
6350
  const botUserId = normalizeOptionalString(params.botUserId);
6538
6351
  const botId = normalizeOptionalString(params.botId);
@@ -6832,8 +6645,7 @@ async function monitorSlackProvider(opts) {
6832
6645
  const appHomeSlashCommandName = commandRegistration.mode === "single" ? commandRegistration.name : void 0;
6833
6646
  let workspaceRuntimePromise;
6834
6647
  const installSlackWorkspaceRuntime = async () => {
6835
- if (workspaceRuntimePromise) return await workspaceRuntimePromise;
6836
- workspaceRuntimePromise = (async () => {
6648
+ workspaceRuntimePromise ??= (async () => {
6837
6649
  registerSlackWorkspaceEvents({
6838
6650
  ctx,
6839
6651
  appHomeSlashCommandName,
@@ -6931,63 +6743,60 @@ async function monitorSlackProvider(opts) {
6931
6743
  if (slackMode === "socket") {
6932
6744
  let reconnectAttempts = 0;
6933
6745
  let hasLoggedSocketConnected = false;
6934
- while (!opts.abortSignal?.aborted) try {
6935
- const disconnect = await startSlackSocketAndWaitForDisconnect({
6936
- app,
6937
- abortSignal: opts.abortSignal,
6938
- onStarted: async () => {
6939
- reconnectAttempts = 0;
6940
- await recoverSlackIdentity();
6941
- publishSlackConnectedStatus(opts.setStatus, ctx.identityHealth);
6942
- if (!hasLoggedSocketConnected) {
6943
- hasLoggedSocketConnected = true;
6944
- runtime.log?.(ctx.identityHealth.lifecycle === "blocked" ? "slack socket mode connected (degraded identity)" : "slack socket mode connected");
6746
+ while (!opts.abortSignal?.aborted) {
6747
+ let delayMs;
6748
+ try {
6749
+ const disconnect = await startSlackSocketAndWaitForDisconnect({
6750
+ app,
6751
+ abortSignal: opts.abortSignal,
6752
+ onStarted: async () => {
6753
+ reconnectAttempts = 0;
6754
+ await recoverSlackIdentity();
6755
+ publishSlackConnectedStatus(opts.setStatus, ctx.identityHealth);
6756
+ if (!hasLoggedSocketConnected) {
6757
+ hasLoggedSocketConnected = true;
6758
+ runtime.log?.(ctx.identityHealth.lifecycle === "blocked" ? "slack socket mode connected (degraded identity)" : "slack socket mode connected");
6759
+ }
6945
6760
  }
6761
+ });
6762
+ if (!disconnect) break;
6763
+ if (opts.abortSignal?.aborted) break;
6764
+ publishSlackDisconnectedStatus(opts.setStatus, disconnect.error);
6765
+ if (disconnect.error && isNonRecoverableSlackAuthError(disconnect.error)) {
6766
+ publishSlackBlockedStatus(opts.setStatus, disconnect.error);
6767
+ runtime.error?.(`slack socket mode disconnected due to non-recoverable auth error — skipping channel (${formatSlackError(disconnect.error)})`);
6768
+ throw disconnect.error instanceof Error ? disconnect.error : new Error(formatSlackError(disconnect.error));
6946
6769
  }
6947
- });
6948
- if (!disconnect) break;
6949
- if (opts.abortSignal?.aborted) break;
6950
- publishSlackDisconnectedStatus(opts.setStatus, disconnect.error);
6951
- if (disconnect.error && isNonRecoverableSlackAuthError(disconnect.error)) {
6952
- publishSlackBlockedStatus(opts.setStatus, disconnect.error);
6953
- runtime.error?.(`slack socket mode disconnected due to non-recoverable auth error — skipping channel (${formatSlackError(disconnect.error)})`);
6954
- throw disconnect.error instanceof Error ? disconnect.error : new Error(formatSlackError(disconnect.error));
6955
- }
6956
- reconnectAttempts += 1;
6957
- const delayMs = computeBackoff(SLACK_SOCKET_RECONNECT_POLICY, reconnectAttempts);
6958
- runtime.log?.(warn(formatSlackSocketReconnectMessage({
6959
- event: disconnect.event,
6960
- attempt: reconnectAttempts,
6961
- delayMs,
6962
- error: disconnect.error
6963
- })));
6964
- await gracefulStopSlackApp(app);
6965
- try {
6966
- await sleepWithAbort(delayMs, opts.abortSignal);
6967
- } catch {
6968
- break;
6969
- }
6970
- } catch (err) {
6971
- if (isNonRecoverableSlackAuthError(err)) {
6972
- publishSlackBlockedStatus(opts.setStatus, err);
6973
- runtime.error?.(`slack socket mode failed to start due to non-recoverable auth error — skipping channel (${formatSlackError(err)})`);
6974
- throw err;
6770
+ reconnectAttempts += 1;
6771
+ delayMs = computeBackoff(SLACK_SOCKET_RECONNECT_POLICY, reconnectAttempts);
6772
+ runtime.log?.(warn(formatSlackSocketReconnectMessage({
6773
+ event: disconnect.event,
6774
+ attempt: reconnectAttempts,
6775
+ delayMs,
6776
+ error: disconnect.error
6777
+ })));
6778
+ await gracefulStopSlackApp(app);
6779
+ } catch (err) {
6780
+ if (isNonRecoverableSlackAuthError(err)) {
6781
+ publishSlackBlockedStatus(opts.setStatus, err);
6782
+ runtime.error?.(`slack socket mode failed to start due to non-recoverable auth error — skipping channel (${formatSlackError(err)})`);
6783
+ throw err;
6784
+ }
6785
+ publishSlackDisconnectedStatus(opts.setStatus, err);
6786
+ reconnectAttempts += 1;
6787
+ delayMs = computeBackoff(SLACK_SOCKET_RECONNECT_POLICY, reconnectAttempts);
6788
+ runtime.error?.(formatSlackSocketStartRetryMessage({
6789
+ attempt: reconnectAttempts,
6790
+ delayMs,
6791
+ error: err,
6792
+ sdkContext: socketModeLogger.getLastMessage()
6793
+ }));
6975
6794
  }
6976
- publishSlackDisconnectedStatus(opts.setStatus, err);
6977
- reconnectAttempts += 1;
6978
- const delayMs = computeBackoff(SLACK_SOCKET_RECONNECT_POLICY, reconnectAttempts);
6979
- runtime.error?.(formatSlackSocketStartRetryMessage({
6980
- attempt: reconnectAttempts,
6981
- delayMs,
6982
- error: err,
6983
- sdkContext: socketModeLogger.getLastMessage()
6984
- }));
6985
6795
  try {
6986
6796
  await sleepWithAbort(delayMs, opts.abortSignal);
6987
6797
  } catch {
6988
6798
  break;
6989
6799
  }
6990
- continue;
6991
6800
  }
6992
6801
  } else if (slackMode === "relay" && relayConfig) {
6993
6802
  const relaySource = await loadSlackRelaySource();
@@ -7030,8 +6839,7 @@ async function monitorSlackProvider(opts) {
7030
6839
  function createSlackWorkspaceClientResolver(params) {
7031
6840
  if (params.installationIdentity.kind !== "enterprise") return () => params.appClient;
7032
6841
  const clients = /* @__PURE__ */ new Map();
7033
- return (rawTeamId) => {
7034
- const teamId = rawTeamId;
6842
+ return (teamId) => {
7035
6843
  if (!teamId || !/^T[A-Z0-9]+$/.test(teamId)) throw new Error("Slack Enterprise Grid workspace client requires a valid teamId");
7036
6844
  const cached = clients.get(teamId);
7037
6845
  if (cached) return cached;