@openclaw/slack 2026.9.1-beta.1 → 2026.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/{account-inspect-CN2hBsim.js → account-inspect-C3sePHWa.js} +3 -3
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{action-runtime-BoSeX09X.js → action-runtime-DftQWpI4.js} +84 -66
  4. package/dist/action-runtime.runtime-rHI3UAh4.js +2 -0
  5. package/dist/{actions-XdQyjG_p.js → actions-CFkvEv1d.js} +198 -54
  6. package/dist/api.js +14 -14
  7. package/dist/{approval-handler.runtime-DxXfGX_Z.js → approval-handler.runtime-BeILKdw4.js} +47 -25
  8. package/dist/{channel-C_vnTgxo.js → channel-CmOuxbOD.js} +76 -133
  9. package/dist/channel-config-api.js +1 -1
  10. package/dist/channel-plugin-api.js +1 -1
  11. package/dist/{channel-type-j-2lalcC.js → channel-type-BWt2CRaI.js} +2 -2
  12. package/dist/{channel.setup-aal8tokM.js → channel.setup-D5z1ReaT.js} +29 -23
  13. package/dist/{config-schema-CN3XZRX5.js → config-schema-JDx_f9Zb.js} +26 -17
  14. package/dist/{cursor-pages-eX7p8Wwt.js → cursor-pages-ByFwo-Py.js} +7 -1
  15. package/dist/{directory-config-DqfQ42OV.js → directory-config-Bmw4ykSy.js} +4 -3
  16. package/dist/directory-contract-api.js +1 -1
  17. package/dist/{directory-live-lC6X_Ru-.js → directory-live-BuBPHmju.js} +3 -8
  18. package/dist/{doctor-contract-BAy7-EUQ.js → doctor-contract-BNjw9bxb.js} +5 -4
  19. package/dist/doctor-contract-api.js +1 -1
  20. package/dist/{message-tool-api-CWosHSi5.js → message-tool-api-uNEfQYGY.js} +19 -2
  21. package/dist/message-tool-api.js +1 -1
  22. package/dist/{monitor-DrNCGneD.js → monitor-DI07pfJl.js} +3 -3
  23. package/dist/{outbound-adapter-DkT2vUE9.js → outbound-adapter-B5QyTRpJ.js} +96 -91
  24. package/dist/{pipeline.runtime-CRRng_Nw.js → pipeline.runtime-BdIwZgm4.js} +596 -920
  25. package/dist/{policy-BoP6t88v.js → policy-Bh5TOqII.js} +7 -4
  26. package/dist/{probe-4_aHtVT3.js → probe-Biy--yhL.js} +251 -12
  27. package/dist/{provider-D4nDgxCh.js → provider-DoaUvAM4.js} +5621 -4944
  28. package/dist/{relay-source-CEmze11m.js → relay-source-D4uecp68.js} +6 -4
  29. package/dist/{replies-D9XMM_S0.js → replies-DENuTcPO.js} +21 -16
  30. package/dist/reply-blocks-PRkhyAN7.js +790 -0
  31. package/dist/{resolve-channels-DSamDgVs.js → resolve-channels-DQGV2VrE.js} +6 -10
  32. package/dist/{resolve-users-CIzwbaJR.js → resolve-users-DRGt_Q4I.js} +5 -4
  33. package/dist/runtime-api.js +10 -10
  34. package/dist/{scopes-BBrUzpBH.js → scopes-CZzeGdWV.js} +1 -1
  35. package/dist/{send-DtjEnlLh.js → send-DElUcgIs.js} +32 -24
  36. package/dist/send-results-eeOu_HYm.js +23 -0
  37. package/dist/{send.runtime-DQeNKa2J.js → send.runtime-C8D6cKGm.js} +1 -1
  38. package/dist/{group-policy-CU1tEGpS.js → session-status-BynwcZSO.js} +284 -1013
  39. package/dist/setup-plugin-api.js +1 -1
  40. package/dist/{setup-surface-CsBCM4rP.js → setup-surface-B1_gpGBl.js} +5 -5
  41. package/dist/{shared-D9GeeR9K.js → shared-CNQsWJT7.js} +7 -5
  42. package/dist/{slash-dispatch.runtime-Chr3YHnT.js → slash-dispatch.runtime-DhsXavSY.js} +2 -2
  43. package/dist/{target-parsing-BnMD2ZqZ.js → target-parsing-PbxGDbr9.js} +11 -6
  44. package/dist/{targets-Cx5W_n3W.js → targets-7FexXJ62.js} +1 -1
  45. package/dist/{thread-ts-DUGhaYKq.js → thread-ts-CukseRVL.js} +5 -1
  46. package/node_modules/@slack/bolt/node_modules/negotiator/lib/accept.js +54 -0
  47. package/node_modules/@slack/bolt/node_modules/negotiator/lib/charset.js +10 -34
  48. package/node_modules/@slack/bolt/node_modules/negotiator/lib/encoding.js +9 -30
  49. package/node_modules/@slack/bolt/node_modules/negotiator/lib/language.js +15 -36
  50. package/node_modules/@slack/bolt/node_modules/negotiator/lib/mediaType.js +16 -134
  51. package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
  52. package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/README.md +71 -0
  53. package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
  54. package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
  55. package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
  56. package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/package.json +52 -0
  57. package/node_modules/@slack/bolt/node_modules/negotiator/package.json +16 -10
  58. package/node_modules/typebox/build/format/email.mjs +1 -1
  59. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +19 -1
  60. package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
  61. package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
  62. package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
  63. package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
  64. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  65. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  66. package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
  67. package/node_modules/typebox/build/system/memory/create.mjs +3 -4
  68. package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
  69. package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
  70. package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
  71. package/node_modules/typebox/build/system/memory/update.mjs +3 -2
  72. package/node_modules/typebox/package.json +1 -1
  73. package/node_modules/undici/lib/dispatcher/balanced-pool.js +4 -2
  74. package/node_modules/undici/lib/dispatcher/client-h1.js +12 -4
  75. package/node_modules/undici/lib/dispatcher/client-h2.js +70 -14
  76. package/node_modules/undici/lib/dispatcher/client.js +6 -2
  77. package/node_modules/undici/lib/handler/cache-handler.js +21 -5
  78. package/node_modules/undici/lib/handler/retry-handler.js +42 -7
  79. package/node_modules/undici/lib/interceptor/cache.js +20 -1
  80. package/node_modules/undici/lib/interceptor/decompress.js +146 -14
  81. package/node_modules/undici/lib/interceptor/dump.js +10 -23
  82. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +245 -150
  83. package/node_modules/undici/lib/web/websocket/connection.js +1 -1
  84. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +5 -0
  85. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -10
  86. package/node_modules/undici/package.json +1 -1
  87. package/node_modules/undici/types/interceptors.d.ts +2 -0
  88. package/openclaw.plugin.json +17 -9
  89. package/package.json +6 -6
  90. package/skills/_vendor/slack-skills-plugin.LICENSE +21 -0
  91. package/skills/_vendor/slack-skills-plugin.json +31 -0
  92. package/skills/block-kit/SKILL.md +37 -0
  93. package/skills/block-kit/references/official-block-kit.md +257 -0
  94. package/skills/block-kit/references/official-common-patterns.md +385 -0
  95. package/skills/slack/SKILL.md +1 -1
  96. package/dist/action-runtime.runtime-Dpa16J87.js +0 -2
  97. package/dist/conversation-binding-route-DFVLUdYF.js +0 -115
  98. package/dist/slack-client-kind-hSfjXyUM.js +0 -94
  99. package/node_modules/@slack/bolt/node_modules/negotiator/HISTORY.md +0 -114
@@ -0,0 +1,385 @@
1
+ # Common Block Kit Patterns
2
+
3
+ > Starting scaffolds for frequent use cases — copy one and customize rather than building from scratch.
4
+ > They were valid when written, but the live docs (the skill's **Source of Truth**) remain authoritative for field schemas, and Block Kit evolves. Confirm any field you change against the component's doc page, and re-run the customized payload through `blocks.validate` (Step 5) before shipping.
5
+
6
+ ---
7
+
8
+ ## Approval Message [M]
9
+
10
+ A notification with context and Approve/Reject buttons.
11
+
12
+ ```json
13
+ {
14
+ "channel": "C0123456789",
15
+ "text": "New request from Jane awaiting approval",
16
+ "blocks": [
17
+ {
18
+ "type": "header",
19
+ "text": { "type": "plain_text", "text": "New Approval Request" }
20
+ },
21
+ {
22
+ "type": "section",
23
+ "text": {
24
+ "type": "mrkdwn",
25
+ "text": "*Requester:* <@U0123456789>\n*Type:* Access request\n*Details:* Production database read access"
26
+ }
27
+ },
28
+ { "type": "divider" },
29
+ {
30
+ "type": "actions",
31
+ "block_id": "approval_actions",
32
+ "elements": [
33
+ {
34
+ "type": "button",
35
+ "text": { "type": "plain_text", "text": "Approve" },
36
+ "style": "primary",
37
+ "action_id": "approve_btn",
38
+ "value": "request_123"
39
+ },
40
+ {
41
+ "type": "button",
42
+ "text": { "type": "plain_text", "text": "Reject" },
43
+ "style": "danger",
44
+ "action_id": "reject_btn",
45
+ "value": "request_123"
46
+ }
47
+ ]
48
+ }
49
+ ]
50
+ }
51
+ ```
52
+
53
+ **Customization points:** Header text, section fields, button values, adding a confirmation dialog to the Reject button.
54
+
55
+ ---
56
+
57
+ ## Simple Form Modal [V]
58
+
59
+ A modal with text input, select menu, and optional checkbox.
60
+
61
+ ```json
62
+ {
63
+ "type": "modal",
64
+ "callback_id": "feedback_form",
65
+ "title": { "type": "plain_text", "text": "Submit Feedback" },
66
+ "submit": { "type": "plain_text", "text": "Submit" },
67
+ "close": { "type": "plain_text", "text": "Cancel" },
68
+ "blocks": [
69
+ {
70
+ "type": "input",
71
+ "block_id": "category_block",
72
+ "label": { "type": "plain_text", "text": "Category" },
73
+ "element": {
74
+ "type": "static_select",
75
+ "action_id": "category_select",
76
+ "placeholder": { "type": "plain_text", "text": "Choose a category" },
77
+ "options": [
78
+ { "text": { "type": "plain_text", "text": "Bug Report" }, "value": "bug" },
79
+ { "text": { "type": "plain_text", "text": "Feature Request" }, "value": "feature" },
80
+ { "text": { "type": "plain_text", "text": "General Feedback" }, "value": "general" }
81
+ ]
82
+ }
83
+ },
84
+ {
85
+ "type": "input",
86
+ "block_id": "description_block",
87
+ "label": { "type": "plain_text", "text": "Description" },
88
+ "element": {
89
+ "type": "plain_text_input",
90
+ "action_id": "description_input",
91
+ "multiline": true,
92
+ "placeholder": { "type": "plain_text", "text": "Tell us more..." }
93
+ }
94
+ },
95
+ {
96
+ "type": "input",
97
+ "block_id": "urgency_block",
98
+ "label": { "type": "plain_text", "text": "Priority" },
99
+ "element": {
100
+ "type": "radio_buttons",
101
+ "action_id": "urgency_select",
102
+ "options": [
103
+ { "text": { "type": "plain_text", "text": "Low" }, "value": "low" },
104
+ { "text": { "type": "plain_text", "text": "Medium" }, "value": "medium" },
105
+ { "text": { "type": "plain_text", "text": "High" }, "value": "high" }
106
+ ]
107
+ },
108
+ "optional": true
109
+ }
110
+ ]
111
+ }
112
+ ```
113
+
114
+ **Customization points:** Title, callback_id, input types, options list, adding/removing input blocks.
115
+
116
+ ---
117
+
118
+ ## Notification Alert [M]
119
+
120
+ An alert banner with description and timestamp context.
121
+
122
+ ```json
123
+ {
124
+ "channel": "C0123456789",
125
+ "text": "Alert: Deployment failed for api-gateway",
126
+ "blocks": [
127
+ {
128
+ "type": "alert",
129
+ "text": { "type": "plain_text", "text": "Deployment failed for api-gateway" },
130
+ "level": "error"
131
+ },
132
+ {
133
+ "type": "section",
134
+ "text": {
135
+ "type": "mrkdwn",
136
+ "text": "The deployment to *production* failed during the health check phase.\n\n*Error:* `Connection timeout after 30s`\n*Commit:* `a1b2c3d`"
137
+ }
138
+ },
139
+ {
140
+ "type": "context",
141
+ "elements": [
142
+ {
143
+ "type": "mrkdwn",
144
+ "text": "Triggered by <@U0123456789> | <!date^1700000000^{date_short} at {time}|Nov 14, 2023>"
145
+ }
146
+ ]
147
+ },
148
+ {
149
+ "type": "actions",
150
+ "elements": [
151
+ {
152
+ "type": "button",
153
+ "text": { "type": "plain_text", "text": "View Logs" },
154
+ "url": "https://logs.example.com/deploy/456",
155
+ "action_id": "view_logs_btn"
156
+ },
157
+ {
158
+ "type": "button",
159
+ "text": { "type": "plain_text", "text": "Retry" },
160
+ "style": "primary",
161
+ "action_id": "retry_deploy_btn"
162
+ }
163
+ ]
164
+ }
165
+ ]
166
+ }
167
+ ```
168
+
169
+ **Customization points:** Level (`info`, `warning`, `error`, `success`), description text, action buttons.
170
+
171
+ ---
172
+
173
+ ## Dashboard Home Tab [H]
174
+
175
+ A welcome dashboard with metrics fields and quick-action buttons.
176
+
177
+ ```json
178
+ {
179
+ "type": "home",
180
+ "blocks": [
181
+ {
182
+ "type": "header",
183
+ "text": { "type": "plain_text", "text": "Welcome to AppName" }
184
+ },
185
+ {
186
+ "type": "section",
187
+ "text": { "type": "mrkdwn", "text": "Here's your overview for today:" }
188
+ },
189
+ {
190
+ "type": "section",
191
+ "fields": [
192
+ { "type": "mrkdwn", "text": "*Open Tickets:*\n12" },
193
+ { "type": "mrkdwn", "text": "*Resolved Today:*\n5" },
194
+ { "type": "mrkdwn", "text": "*Avg Response:*\n2.4 hrs" },
195
+ { "type": "mrkdwn", "text": "*SLA Status:*\n:white_check_mark: On Track" }
196
+ ]
197
+ },
198
+ { "type": "divider" },
199
+ {
200
+ "type": "actions",
201
+ "elements": [
202
+ {
203
+ "type": "button",
204
+ "text": { "type": "plain_text", "text": "New Ticket" },
205
+ "style": "primary",
206
+ "action_id": "new_ticket_btn"
207
+ },
208
+ {
209
+ "type": "button",
210
+ "text": { "type": "plain_text", "text": "My Queue" },
211
+ "action_id": "my_queue_btn"
212
+ },
213
+ {
214
+ "type": "button",
215
+ "text": { "type": "plain_text", "text": "Settings" },
216
+ "action_id": "settings_btn"
217
+ }
218
+ ]
219
+ }
220
+ ]
221
+ }
222
+ ```
223
+
224
+ **Customization points:** Metrics fields, action buttons, adding image blocks or additional sections.
225
+
226
+ ---
227
+
228
+ ## Confirmation with Dialog [M]
229
+
230
+ An action button with a confirmation dialog attached (prevents accidental clicks).
231
+
232
+ ```json
233
+ {
234
+ "channel": "C0123456789",
235
+ "text": "Server shutdown requested",
236
+ "blocks": [
237
+ {
238
+ "type": "section",
239
+ "text": { "type": "mrkdwn", "text": "Are you sure you want to shut down *prod-server-01*?" }
240
+ },
241
+ {
242
+ "type": "actions",
243
+ "elements": [
244
+ {
245
+ "type": "button",
246
+ "text": { "type": "plain_text", "text": "Shut Down" },
247
+ "style": "danger",
248
+ "action_id": "shutdown_btn",
249
+ "value": "prod-server-01",
250
+ "confirm": {
251
+ "title": { "type": "plain_text", "text": "Confirm Shutdown" },
252
+ "text": {
253
+ "type": "plain_text",
254
+ "text": "This will immediately terminate the server. Active connections will be dropped."
255
+ },
256
+ "confirm": { "type": "plain_text", "text": "Shut Down" },
257
+ "deny": { "type": "plain_text", "text": "Cancel" },
258
+ "style": "danger"
259
+ }
260
+ }
261
+ ]
262
+ }
263
+ ]
264
+ }
265
+ ```
266
+
267
+ **Customization points:** Confirmation title/text (title max 100 chars, text max 300 chars, confirm/deny max 30 chars), button style.
268
+
269
+ ---
270
+
271
+ ## Data Table [M]
272
+
273
+ A structured table for displaying tabular data. Only one table block per message.
274
+
275
+ ```json
276
+ {
277
+ "channel": "C0123456789",
278
+ "text": "Team sprint summary",
279
+ "blocks": [
280
+ {
281
+ "type": "header",
282
+ "text": { "type": "plain_text", "text": "Sprint Summary" }
283
+ },
284
+ {
285
+ "type": "table",
286
+ "column_settings": [{ "is_wrapped": true }, { "align": "center" }, { "align": "right" }],
287
+ "rows": [
288
+ [
289
+ { "type": "raw_text", "text": "Name" },
290
+ { "type": "raw_text", "text": "Status" },
291
+ { "type": "raw_text", "text": "Points" }
292
+ ],
293
+ [
294
+ { "type": "raw_text", "text": "Auth refactor" },
295
+ { "type": "raw_text", "text": "In Progress" },
296
+ { "type": "raw_text", "text": "5" }
297
+ ],
298
+ [
299
+ { "type": "raw_text", "text": "API docs update" },
300
+ { "type": "raw_text", "text": "Done" },
301
+ { "type": "raw_text", "text": "2" }
302
+ ],
303
+ [
304
+ { "type": "raw_text", "text": "Bug #1234" },
305
+ { "type": "raw_text", "text": "Blocked" },
306
+ { "type": "raw_text", "text": "3" }
307
+ ]
308
+ ]
309
+ }
310
+ ]
311
+ }
312
+ ```
313
+
314
+ **Customization points:** Column settings (alignment: `left`/`center`/`right`, wrapping: `is_wrapped`), row data, cell type (`raw_text` for plain content, `rich_text` for formatted content with links/emoji/mentions). Max 100 rows, max 20 cells per row. First row is the header. Only one table block per message.
315
+
316
+ ---
317
+
318
+ ## Settings Modal with Multiple Input Types [V]
319
+
320
+ A modal combining different input types for a settings/preferences form.
321
+
322
+ ```json
323
+ {
324
+ "type": "modal",
325
+ "callback_id": "settings_modal",
326
+ "title": { "type": "plain_text", "text": "Notification Settings" },
327
+ "submit": { "type": "plain_text", "text": "Save" },
328
+ "close": { "type": "plain_text", "text": "Cancel" },
329
+ "blocks": [
330
+ {
331
+ "type": "input",
332
+ "block_id": "channel_block",
333
+ "label": { "type": "plain_text", "text": "Notification Channel" },
334
+ "element": {
335
+ "type": "conversations_select",
336
+ "action_id": "channel_select",
337
+ "default_to_current_conversation": true
338
+ }
339
+ },
340
+ {
341
+ "type": "input",
342
+ "block_id": "frequency_block",
343
+ "label": { "type": "plain_text", "text": "Digest Frequency" },
344
+ "element": {
345
+ "type": "static_select",
346
+ "action_id": "frequency_select",
347
+ "options": [
348
+ { "text": { "type": "plain_text", "text": "Real-time" }, "value": "realtime" },
349
+ { "text": { "type": "plain_text", "text": "Hourly" }, "value": "hourly" },
350
+ { "text": { "type": "plain_text", "text": "Daily" }, "value": "daily" }
351
+ ],
352
+ "initial_option": { "text": { "type": "plain_text", "text": "Daily" }, "value": "daily" }
353
+ }
354
+ },
355
+ {
356
+ "type": "input",
357
+ "block_id": "events_block",
358
+ "label": { "type": "plain_text", "text": "Notify me about" },
359
+ "element": {
360
+ "type": "checkboxes",
361
+ "action_id": "events_checkboxes",
362
+ "options": [
363
+ { "text": { "type": "plain_text", "text": "New deployments" }, "value": "deploys" },
364
+ { "text": { "type": "plain_text", "text": "Failed builds" }, "value": "failures" },
365
+ { "text": { "type": "plain_text", "text": "PR reviews needed" }, "value": "reviews" }
366
+ ]
367
+ }
368
+ },
369
+ {
370
+ "type": "input",
371
+ "block_id": "quiet_hours_block",
372
+ "label": { "type": "plain_text", "text": "Quiet hours start" },
373
+ "element": {
374
+ "type": "timepicker",
375
+ "action_id": "quiet_start",
376
+ "initial_time": "22:00",
377
+ "placeholder": { "type": "plain_text", "text": "Select time" }
378
+ },
379
+ "optional": true
380
+ }
381
+ ]
382
+ }
383
+ ```
384
+
385
+ **Customization points:** Input types, options, initial values, adding `hint` text to inputs, marking fields as `optional`.
@@ -17,4 +17,4 @@ Use the `message` tool with `channel: "slack"`. The tool schema lists the action
17
17
  - When multiple Slack accounts are configured, pass `accountId` rather than guessing.
18
18
  - Confirm destructive deletes when the target or intent is unclear.
19
19
 
20
- Slack formatting, mentions, tables, charts, and interactive controls are described automatically by the current `message` tool hints. Follow those hints instead of maintaining a second action or formatting catalog here.
20
+ Slack formatting, mentions, and available actions are described automatically by the current `message` tool hints. Follow those hints instead of maintaining a second action catalog here.
@@ -1,2 +0,0 @@
1
- import { t as handleSlackAction } from "./action-runtime-BoSeX09X.js";
2
- export { handleSlackAction };
@@ -1,115 +0,0 @@
1
- import { a as parseSlackTarget } from "./target-parsing-BnMD2ZqZ.js";
2
- import "./targets-Cx5W_n3W.js";
3
- import { resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
4
- //#region extensions/slack/src/account-reply-mode.ts
5
- function normalizeSlackChatType(raw) {
6
- const value = raw?.trim().toLowerCase();
7
- if (!value) return;
8
- if (value === "direct" || value === "dm") return "direct";
9
- if (value === "group" || value === "channel") return value;
10
- }
11
- function resolveSlackReplyToMode(account, chatType) {
12
- const normalized = normalizeSlackChatType(chatType ?? void 0);
13
- if (normalized && account.replyToModeByChatType?.[normalized] !== void 0) return account.replyToModeByChatType[normalized] ?? "off";
14
- return account.replyToMode ?? "off";
15
- }
16
- //#endregion
17
- //#region extensions/slack/src/conversation-binding-route.ts
18
- const slackRouteBindingConfigCache = /* @__PURE__ */ new WeakMap();
19
- function slackTargetDefaultKindForPeer(kind) {
20
- return kind === "direct" ? "user" : "channel";
21
- }
22
- function slackTargetKindMatchesPeer(peerKind, targetKind) {
23
- if (targetKind === "user") return peerKind === "direct";
24
- return peerKind === "channel" || peerKind === "group";
25
- }
26
- function normalizeSlackRouteBindingPeer(peer) {
27
- const rawId = peer.id.trim();
28
- if (!rawId || rawId === "*") return peer;
29
- const target = (() => {
30
- try {
31
- return parseSlackTarget(rawId, { defaultKind: slackTargetDefaultKindForPeer(peer.kind) });
32
- } catch {
33
- return;
34
- }
35
- })();
36
- if (!target || !slackTargetKindMatchesPeer(peer.kind, target.kind)) return peer;
37
- const normalizedId = target.teamId ? `team:${target.teamId}:${target.kind}:${target.id}` : target.id;
38
- return normalizedId === peer.id ? peer : {
39
- ...peer,
40
- id: normalizedId
41
- };
42
- }
43
- function normalizeSlackRouteBindingConfig(cfg) {
44
- const bindings = cfg.bindings;
45
- const cached = slackRouteBindingConfigCache.get(cfg);
46
- if (cached && cached.bindingsRef === bindings) return cached.normalizedCfg;
47
- if (!Array.isArray(bindings)) return cfg;
48
- let changed = false;
49
- const normalizedBindings = bindings.map((binding) => {
50
- if (binding.type === "acp" || binding.match.channel.trim().toLowerCase() !== "slack") return binding;
51
- const peer = binding.match.peer;
52
- if (!peer) return binding;
53
- const normalizedPeer = normalizeSlackRouteBindingPeer(peer);
54
- if (normalizedPeer === peer) return binding;
55
- changed = true;
56
- return {
57
- ...binding,
58
- match: {
59
- ...binding.match,
60
- peer: normalizedPeer
61
- }
62
- };
63
- });
64
- const normalizedCfg = changed ? {
65
- ...cfg,
66
- bindings: normalizedBindings
67
- } : cfg;
68
- slackRouteBindingConfigCache.set(cfg, {
69
- bindingsRef: bindings,
70
- normalizedCfg
71
- });
72
- return normalizedCfg;
73
- }
74
- function resolveSlackConversationBindingRoute(params) {
75
- const boundThreadRoute = params.bindingsEnabled && params.runtimeBindingThreadId ? resolveRuntimeConversationBindingRoute({
76
- route: params.route,
77
- touchBinding: params.touchBinding,
78
- conversation: {
79
- channel: "slack",
80
- accountId: params.accountId,
81
- conversationId: params.runtimeBindingThreadId,
82
- parentConversationId: params.baseConversationId
83
- }
84
- }) : null;
85
- const runtimeRoute = !params.bindingsEnabled ? {
86
- bindingOwnerAvailable: true,
87
- route: params.route,
88
- bindingRecord: null,
89
- boundSessionKey: void 0
90
- } : boundThreadRoute?.boundSessionKey || boundThreadRoute?.bindingRecord ? boundThreadRoute : resolveRuntimeConversationBindingRoute({
91
- route: params.route,
92
- touchBinding: params.touchBinding,
93
- conversation: {
94
- channel: "slack",
95
- accountId: params.accountId,
96
- conversationId: params.baseConversationId
97
- }
98
- });
99
- const configuredRoute = params.bindingsEnabled && !runtimeRoute.boundSessionKey && !runtimeRoute.bindingRecord ? resolveConfiguredBindingRoute({
100
- cfg: params.cfg,
101
- route: params.route,
102
- conversation: {
103
- channel: "slack",
104
- accountId: params.accountId,
105
- conversationId: params.baseConversationId
106
- }
107
- }) : null;
108
- return {
109
- runtimeRoute,
110
- configuredRoute,
111
- route: runtimeRoute.boundSessionKey ? runtimeRoute.route : configuredRoute?.route ?? params.route
112
- };
113
- }
114
- //#endregion
115
- export { resolveSlackConversationBindingRoute as n, resolveSlackReplyToMode as r, normalizeSlackRouteBindingConfig as t };
@@ -1,94 +0,0 @@
1
- import { F as renderSlackBlockFallbackText } from "./group-policy-CU1tEGpS.js";
2
- import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
- import { normalizeHostname } from "openclaw/plugin-sdk/host-runtime";
4
- import { fetchWithRuntimeDispatcher } from "openclaw/plugin-sdk/runtime-fetch";
5
- import { saveRemoteMedia } from "openclaw/plugin-sdk/media-runtime";
6
- //#region extensions/slack/src/monitor/block-text.ts
7
- function readSlackBlockType(block) {
8
- return block && typeof block === "object" && !Array.isArray(block) ? block.type : void 0;
9
- }
10
- function hasSlackTableBlock(blocks) {
11
- return blocks?.some((block) => readSlackBlockType(block) === "table") ?? false;
12
- }
13
- function hasSlackMessageTableBlock(message) {
14
- return hasSlackTableBlock(message.blocks) || message.attachments?.some((attachment) => !isSlackUnfurlAttachment(attachment) && hasSlackTableBlock(attachment.blocks)) === true;
15
- }
16
- function isSlackUnfurlAttachment(attachment) {
17
- return attachment.is_msg_unfurl === true || attachment.is_app_unfurl === true || typeof attachment.app_unfurl_url === "string" && attachment.app_unfurl_url.trim().length > 0;
18
- }
19
- function resolveSlackBlocksText(blocks) {
20
- if (!blocks?.length) return;
21
- const parts = [];
22
- let hasRichText = false;
23
- let hasNativeData = false;
24
- for (const block of blocks) {
25
- const blockType = readSlackBlockType(block);
26
- hasRichText ||= blockType === "rich_text";
27
- hasNativeData ||= blockType === "data_visualization" || blockType === "data_table" || blockType === "table";
28
- const text = renderSlackBlockFallbackText(block, { nativeDataFormat: "plain" });
29
- if (text) parts.push(text);
30
- }
31
- return parts.length > 0 ? {
32
- text: parts.join("\n"),
33
- hasRichText,
34
- hasNativeData
35
- } : void 0;
36
- }
37
- function appendDistinctSlackText(base, addition) {
38
- if (!base) return addition;
39
- const comparableBase = `\n${base.replace(/\r\n?/g, "\n")}\n`;
40
- const comparableAddition = `\n${addition.replace(/\r\n?/g, "\n")}\n`;
41
- if (comparableBase.includes(comparableAddition)) return base;
42
- return `${base}\n${addition}`;
43
- }
44
- function resolveSlackAttachmentTableTexts(attachments) {
45
- const seen = /* @__PURE__ */ new Set();
46
- const texts = [];
47
- for (const attachment of attachments ?? []) {
48
- if (isSlackUnfurlAttachment(attachment)) continue;
49
- for (const block of attachment.blocks ?? []) {
50
- if (readSlackBlockType(block) !== "table") continue;
51
- const text = renderSlackBlockFallbackText(block, { nativeDataFormat: "plain" });
52
- if (!text || seen.has(text)) continue;
53
- seen.add(text);
54
- texts.push(text);
55
- }
56
- }
57
- return texts;
58
- }
59
- /** Resolve agent-visible Slack text while admitting only native tables from attachments. */
60
- function resolveSlackMessageText(message, options = {}) {
61
- let resolved = chooseSlackPrimaryText({
62
- messageText: options.preserveMessageTextWhitespace ? typeof message.text === "string" && message.text.trim().length > 0 ? message.text : void 0 : normalizeOptionalString(message.text),
63
- blocksText: resolveSlackBlocksText(message.blocks)
64
- });
65
- for (const tableText of resolveSlackAttachmentTableTexts(message.attachments)) resolved = appendDistinctSlackText(resolved, tableText);
66
- return resolved;
67
- }
68
- function chooseSlackPrimaryText(params) {
69
- const { messageText, blocksText } = params;
70
- if (!blocksText) return messageText;
71
- if (!messageText) return blocksText.text;
72
- if (blocksText.hasNativeData) {
73
- const comparableMessageText = messageText.replace(/\s+/g, " ").trim();
74
- const comparableBlocksText = blocksText.text.replace(/\s+/g, " ").trim();
75
- if (comparableMessageText.includes(comparableBlocksText)) return messageText;
76
- return comparableBlocksText.startsWith(comparableMessageText) ? blocksText.text : `${messageText}\n${blocksText.text}`;
77
- }
78
- if (blocksText.hasRichText && blocksText.text.length > messageText.length) return blocksText.text;
79
- return blocksText.text.length > messageText.length && blocksText.text.startsWith(messageText) ? blocksText.text : messageText;
80
- }
81
- //#endregion
82
- //#region extensions/slack/src/monitor/slack-client-kind.ts
83
- /** Detects the isolated GovSlack API plane without consulting mutable config. */
84
- function isGovSlackClient(client) {
85
- if (!client?.slackApiUrl) return false;
86
- try {
87
- const apiUrl = new URL(client.slackApiUrl);
88
- return apiUrl.protocol === "https:" && !apiUrl.port && normalizeHostname(apiUrl.hostname) === "slack-gov.com";
89
- } catch {
90
- return false;
91
- }
92
- }
93
- //#endregion
94
- export { hasSlackTableBlock as a, resolveSlackMessageText as c, hasSlackMessageTableBlock as i, fetchWithRuntimeDispatcher as n, isSlackUnfurlAttachment as o, saveRemoteMedia as r, resolveSlackBlocksText as s, isGovSlackClient as t };