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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/dist/{account-configured-DzC407uv.js → account-configured-BwfXBo_F.js} +1 -1
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{account-inspect-Di7ditqZ.js → account-inspect-jn1xLaVi.js} +9 -2
  4. package/dist/account-reply-mode-DrUXogvO.js +14 -0
  5. package/dist/{accounts-BOJJiHSr.js → accounts-BSr252c_.js} +13 -25
  6. package/dist/accounts.runtime-CjULMLTa.js +2 -0
  7. package/dist/{action-runtime-Cee2ih0s.js → action-runtime-CFU52n4W.js} +11 -17
  8. package/dist/action-runtime.runtime-9-17zvKH.js +2 -0
  9. package/dist/{actions-BZiuSTIq.js → actions-D51foiwR.js} +5 -5
  10. package/dist/{actions.runtime-DoD0-gxw.js → actions.runtime-BMJwtf5C.js} +1 -1
  11. package/dist/api.js +15 -15
  12. package/dist/{approval-handler.runtime-CUPtIM4k.js → approval-handler.runtime-3b4-wxMl.js} +2 -2
  13. package/dist/{channel-DaIiGUOp.js → channel-Ds8NKvfr.js} +75 -41
  14. package/dist/channel-config-api.js +1 -1
  15. package/dist/channel-plugin-api.js +1 -1
  16. package/dist/{channel-type-Cfm6_6n1.js → channel-type-DXkUajFP.js} +3 -3
  17. package/dist/{channel.setup-C-mLz50O.js → channel.setup-DOSTEDfA.js} +8 -5
  18. package/dist/{config-schema-xPSnK2VK.js → config-schema-B4j4tCOI.js} +236 -30
  19. package/dist/{directory-config-DRkFujwG.js → directory-config-B08pm5ZT.js} +1 -1
  20. package/dist/directory-contract-api.js +1 -1
  21. package/dist/{directory-live-D_yZhjgp.js → directory-live-DpPKzPrn.js} +2 -2
  22. package/dist/doctor-contract-U6oVntbM.js +173 -0
  23. package/dist/doctor-contract-api.js +1 -1
  24. package/dist/{group-policy-85UWiriS.js → group-policy-CdnQzQBI.js} +98 -125
  25. package/dist/{interactive-replies-BilWUdcI.js → interactive-replies-C3ffk6oN.js} +1 -1
  26. package/dist/interactive-replies-api.js +1 -1
  27. package/dist/{message-tool-api-CA9jZrCY.js → message-tool-api-ByVyIVOh.js} +3 -3
  28. package/dist/message-tool-api.js +1 -1
  29. package/dist/{monitor-CalGciTs.js → monitor-CnB_WKvF.js} +3 -3
  30. package/dist/{outbound-adapter-BiLKcnyH.js → outbound-adapter-DuPz2HHt.js} +49 -5
  31. package/dist/{pipeline.runtime-DofAvTtb.js → pipeline.runtime-5rRYZuX5.js} +490 -345
  32. package/dist/{policy-BVs4LiSa.js → policy-C31RYSuT.js} +1 -1
  33. package/dist/probe-CVRuArHA.js +340 -0
  34. package/dist/{provider-CmeoUiIM.js → provider-htuIJGFD.js} +791 -359
  35. package/dist/{relay-source-DMmgtvg4.js → relay-source-Df9EaiTF.js} +6 -11
  36. package/dist/{replies-CJJCp6qz.js → replies-Cgr2Gli4.js} +3 -3
  37. package/dist/{resolve-channels-Rfts6POK.js → resolve-channels-DodP2TFx.js} +1 -1
  38. package/dist/{resolve-users-y6wAxR8E.js → resolve-users-M9eF8891.js} +1 -1
  39. package/dist/{runtime-api-BGDyOt1D.js → runtime-api-D5XYMMsf.js} +3 -2
  40. package/dist/runtime-api.js +11 -11
  41. package/dist/{scopes-CuxNQZ6v.js → scopes-CJRpHkDC.js} +1 -2
  42. package/dist/{secret-contract-CMohXFWS.js → secret-contract-DxmvbxBF.js} +1 -0
  43. package/dist/secret-contract-api.js +1 -1
  44. package/dist/{security-audit-CikQhBUY.js → security-audit-Cz6erklv.js} +0 -10
  45. package/dist/security-contract-api.js +1 -1
  46. package/dist/{send-DYp8ca-l.js → send-BZ1tPv7-.js} +28 -11
  47. package/dist/send.runtime-a2pilFor.js +2 -0
  48. package/dist/setup-core-tPxMuFez.js +600 -0
  49. package/dist/setup-plugin-api.js +1 -1
  50. package/dist/{setup-surface-oSd3NX9J.js → setup-surface-wV-S1dE_.js} +58 -32
  51. package/dist/{shared-D9yz5Otg.js → shared-BfMskaMx.js} +57 -10
  52. package/dist/{slash-dispatch.runtime-CSja9VuD.js → slash-dispatch.runtime-lfeIsXTX.js} +1 -1
  53. package/node_modules/@types/node/README.md +1 -1
  54. package/node_modules/@types/node/fs/promises.d.ts +16 -6
  55. package/node_modules/@types/node/package.json +2 -2
  56. package/node_modules/agent-base/README.md +145 -0
  57. package/node_modules/agent-base/dist/src/index.d.ts +78 -0
  58. package/node_modules/agent-base/dist/src/index.js +203 -0
  59. package/node_modules/agent-base/dist/src/index.js.map +1 -0
  60. package/node_modules/agent-base/dist/src/promisify.d.ts +4 -0
  61. package/node_modules/agent-base/dist/src/promisify.js +18 -0
  62. package/node_modules/agent-base/dist/src/promisify.js.map +1 -0
  63. package/node_modules/agent-base/package.json +64 -0
  64. package/node_modules/agent-base/src/index.ts +345 -0
  65. package/node_modules/agent-base/src/promisify.ts +33 -0
  66. package/node_modules/axios/CHANGELOG.md +197 -1
  67. package/node_modules/axios/README.md +424 -256
  68. package/node_modules/axios/dist/axios.js +589 -204
  69. package/node_modules/axios/dist/axios.min.js +3 -3
  70. package/node_modules/axios/dist/axios.min.js.map +1 -1
  71. package/node_modules/axios/dist/browser/axios.cjs +630 -185
  72. package/node_modules/axios/dist/esm/axios.js +630 -185
  73. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  74. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  75. package/node_modules/axios/dist/node/axios.cjs +949 -301
  76. package/node_modules/axios/index.d.cts +28 -5
  77. package/node_modules/axios/index.d.ts +24 -3
  78. package/node_modules/axios/lib/adapters/adapters.js +1 -1
  79. package/node_modules/axios/lib/adapters/fetch.js +223 -49
  80. package/node_modules/axios/lib/adapters/http.js +408 -193
  81. package/node_modules/axios/lib/adapters/xhr.js +3 -1
  82. package/node_modules/axios/lib/core/Axios.js +4 -2
  83. package/node_modules/axios/lib/core/AxiosError.js +13 -1
  84. package/node_modules/axios/lib/core/AxiosHeaders.js +13 -42
  85. package/node_modules/axios/lib/core/buildFullPath.js +29 -1
  86. package/node_modules/axios/lib/core/mergeConfig.js +35 -0
  87. package/node_modules/axios/lib/defaults/transitional.js +2 -0
  88. package/node_modules/axios/lib/env/data.js +1 -1
  89. package/node_modules/axios/lib/helpers/AxiosURLSearchParams.js +1 -3
  90. package/node_modules/axios/lib/helpers/Http2Sessions.js +119 -0
  91. package/node_modules/axios/lib/helpers/buildURL.js +7 -4
  92. package/node_modules/axios/lib/helpers/composeSignals.js +48 -47
  93. package/node_modules/axios/lib/helpers/cookies.js +5 -1
  94. package/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js +16 -11
  95. package/node_modules/axios/lib/helpers/formDataToJSON.js +26 -4
  96. package/node_modules/axios/lib/helpers/formDataToStream.js +2 -2
  97. package/node_modules/axios/lib/helpers/fromDataURI.js +20 -5
  98. package/node_modules/axios/lib/helpers/progressEventReducer.js +3 -0
  99. package/node_modules/axios/lib/helpers/resolveConfig.js +26 -13
  100. package/node_modules/axios/lib/helpers/sanitizeHeaderValue.js +60 -0
  101. package/node_modules/axios/lib/helpers/shouldBypassProxy.js +33 -1
  102. package/node_modules/axios/lib/helpers/toFormData.js +48 -12
  103. package/node_modules/axios/lib/helpers/validator.js +1 -1
  104. package/node_modules/axios/lib/utils.js +105 -19
  105. package/node_modules/axios/package.json +31 -13
  106. package/node_modules/https-proxy-agent/README.md +137 -0
  107. package/node_modules/https-proxy-agent/dist/agent.d.ts +30 -0
  108. package/node_modules/https-proxy-agent/dist/agent.js +177 -0
  109. package/node_modules/https-proxy-agent/dist/agent.js.map +1 -0
  110. package/node_modules/https-proxy-agent/dist/index.d.ts +23 -0
  111. package/node_modules/https-proxy-agent/dist/index.js +14 -0
  112. package/node_modules/https-proxy-agent/dist/index.js.map +1 -0
  113. package/node_modules/https-proxy-agent/dist/parse-proxy-response.d.ts +7 -0
  114. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
  115. package/node_modules/https-proxy-agent/dist/parse-proxy-response.js.map +1 -0
  116. package/node_modules/https-proxy-agent/package.json +56 -0
  117. package/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
  118. package/node_modules/iconv-lite/encodings/utf32.js +10 -3
  119. package/node_modules/iconv-lite/package.json +2 -2
  120. package/node_modules/iconv-lite/types/encodings.d.ts +2 -0
  121. package/node_modules/path-to-regexp/Readme.md +3 -3
  122. package/node_modules/path-to-regexp/dist/index.js +135 -158
  123. package/node_modules/path-to-regexp/dist/index.js.map +1 -1
  124. package/node_modules/path-to-regexp/package.json +2 -2
  125. package/node_modules/qs/CHANGELOG.md +11 -0
  126. package/node_modules/qs/dist/qs.js +17 -17
  127. package/node_modules/qs/lib/parse.js +19 -8
  128. package/node_modules/qs/lib/utils.js +47 -8
  129. package/node_modules/qs/package.json +6 -5
  130. package/node_modules/qs/test/parse.js +230 -0
  131. package/node_modules/qs/test/utils.js +194 -0
  132. package/node_modules/typebox/build/compile/validator.d.mts +1 -4
  133. package/node_modules/typebox/build/guard/guard.d.mts +1 -1
  134. package/node_modules/typebox/build/guard/guard.mjs +5 -2
  135. package/node_modules/typebox/build/guard/string.mjs +16 -4
  136. package/node_modules/typebox/build/schema/engine/_functions.mjs +34 -15
  137. package/node_modules/typebox/build/type/action/readonly_object.d.mts +5 -0
  138. package/node_modules/typebox/build/type/action/readonly_object.mjs +8 -0
  139. package/node_modules/typebox/build/typebox.d.mts +1 -1
  140. package/node_modules/typebox/build/typebox.mjs +1 -1
  141. package/node_modules/typebox/package.json +1 -1
  142. package/node_modules/typebox/readme.md +29 -32
  143. package/node_modules/ws/lib/receiver.js +15 -32
  144. package/node_modules/ws/lib/websocket-server.js +4 -4
  145. package/node_modules/ws/lib/websocket.js +4 -4
  146. package/node_modules/ws/package.json +5 -1
  147. package/npm-shrinkwrap.json +54 -27
  148. package/openclaw.plugin.json +1331 -1424
  149. package/package.json +92 -14
  150. package/dist/accounts.runtime-KvftRRek.js +0 -2
  151. package/dist/action-runtime.runtime-DZfd7IFr.js +0 -2
  152. package/dist/client-WIPAS3Yr.js +0 -160
  153. package/dist/config-api-Df9a1B8C.js +0 -3
  154. package/dist/doctor-contract-DddfkMlF.js +0 -134
  155. package/dist/probe-CN0ssfLN.js +0 -48
  156. package/dist/send.runtime-CJLxAt26.js +0 -2
  157. package/dist/setup-core-CkwVLzFO.js +0 -337
  158. package/node_modules/axios/dist/axios.js.map +0 -1
  159. package/node_modules/axios/dist/browser/axios.cjs.map +0 -1
  160. package/node_modules/axios/dist/esm/axios.js.map +0 -1
  161. package/node_modules/axios/dist/node/axios.cjs.map +0 -1
@@ -0,0 +1,600 @@
1
+ import { t as inspectSlackAccount } from "./account-inspect-jn1xLaVi.js";
2
+ import { t as isSlackPluginAccountConfigured } from "./account-configured-BwfXBo_F.js";
3
+ import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
4
+ import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
5
+ import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
6
+ import { DEFAULT_ACCOUNT_ID, createAccountScopedAllowFromSection, createAccountScopedGroupAccessSection, createAllowlistSetupWizardProxy, createPatchedAccountSetupAdapter, createSetupTranslator, createStandardChannelSetupStatus, defineTokenCredential, mergeAllowFromEntries, parseMentionOrPrefixedId, patchChannelConfigForAccount, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup-runtime";
7
+ import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
8
+ import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
9
+ //#region extensions/slack/src/setup-shared.ts
10
+ const SLACK_CHANNEL = "slack";
11
+ function buildSlackManifest(botName = "OpenClaw") {
12
+ const safeName = botName.trim() || "OpenClaw";
13
+ const manifest = {
14
+ display_information: {
15
+ name: safeName,
16
+ description: `${safeName} connector for OpenClaw`
17
+ },
18
+ features: {
19
+ bot_user: {
20
+ display_name: safeName,
21
+ always_online: true
22
+ },
23
+ app_home: {
24
+ home_tab_enabled: true,
25
+ messages_tab_enabled: true,
26
+ messages_tab_read_only_enabled: false
27
+ },
28
+ agent_view: {
29
+ agent_description: `${safeName} connects Slack Agent View conversations to OpenClaw agents.`,
30
+ suggested_prompts: [
31
+ {
32
+ title: "What can you do?",
33
+ message: "What can you help me with?"
34
+ },
35
+ {
36
+ title: "Summarize this channel",
37
+ message: "Summarize the recent activity in this channel."
38
+ },
39
+ {
40
+ title: "Draft a reply",
41
+ message: "Help me draft a reply."
42
+ }
43
+ ]
44
+ },
45
+ slash_commands: [{
46
+ command: "/openclaw",
47
+ description: "Send a message to OpenClaw",
48
+ should_escape: false
49
+ }]
50
+ },
51
+ oauth_config: { scopes: { bot: [
52
+ "app_mentions:read",
53
+ "assistant:write",
54
+ "channels:history",
55
+ "channels:read",
56
+ "chat:write",
57
+ "commands",
58
+ "emoji:read",
59
+ "files:read",
60
+ "files:write",
61
+ "groups:history",
62
+ "groups:read",
63
+ "im:history",
64
+ "im:read",
65
+ "im:write",
66
+ "mpim:history",
67
+ "mpim:read",
68
+ "mpim:write",
69
+ "pins:read",
70
+ "pins:write",
71
+ "reactions:read",
72
+ "reactions:write",
73
+ "usergroups:read",
74
+ "users:read"
75
+ ] } },
76
+ settings: {
77
+ socket_mode_enabled: true,
78
+ event_subscriptions: { bot_events: [
79
+ "app_home_opened",
80
+ "app_mention",
81
+ "app_context_changed",
82
+ "channel_rename",
83
+ "member_joined_channel",
84
+ "member_left_channel",
85
+ "message.channels",
86
+ "message.groups",
87
+ "message.im",
88
+ "message.mpim",
89
+ "pin_added",
90
+ "pin_removed",
91
+ "reaction_added",
92
+ "reaction_removed"
93
+ ] }
94
+ }
95
+ };
96
+ return JSON.stringify(manifest, null, 2);
97
+ }
98
+ function buildSlackSetupLines() {
99
+ return [
100
+ "1) Slack API -> Create App -> From scratch or From manifest (with the JSON below)",
101
+ "2) Add Socket Mode + enable it to get the app-level token (xapp-...)",
102
+ "3) Install App to workspace to get the xoxb- bot token",
103
+ "4) Enable Event Subscriptions (socket) for message, App Home, and Agent View events",
104
+ "5) App Home -> enable the Home tab, Messages tab for DMs, and Agent View",
105
+ "Manifest JSON follows as plain text for copy/paste.",
106
+ "Tip: set SLACK_BOT_TOKEN + SLACK_APP_TOKEN in your env.",
107
+ `Docs: ${formatDocsLink("/slack", "slack")}`
108
+ ];
109
+ }
110
+ function setSlackChannelAllowlist(cfg, accountId, channelKeys) {
111
+ const channels = Object.fromEntries(channelKeys.map((key) => [key, { enabled: true }]));
112
+ return patchChannelConfigForAccount({
113
+ cfg,
114
+ channel: SLACK_CHANNEL,
115
+ accountId,
116
+ patch: { channels }
117
+ });
118
+ }
119
+ function isSlackSetupAccountConfigured(account) {
120
+ if (account.config.mode === "relay") return isSlackPluginAccountConfigured(account);
121
+ const hasConfiguredUserToken = Boolean(account.userToken?.trim()) || hasConfiguredSecretInput(account.config.userToken);
122
+ const hasConfiguredBotToken = Boolean(account.botToken?.trim()) || hasConfiguredSecretInput(account.config.botToken);
123
+ const hasConfiguredAppToken = Boolean(account.appToken?.trim()) || hasConfiguredSecretInput(account.config.appToken);
124
+ if (account.identity === "user") {
125
+ const hasTransportCredential = account.config.mode === "http" ? hasConfiguredSecretInput(account.config.signingSecret) : hasConfiguredAppToken;
126
+ return hasConfiguredUserToken && hasTransportCredential;
127
+ }
128
+ return hasConfiguredBotToken && hasConfiguredAppToken;
129
+ }
130
+ function describeSlackSetupAccount(account) {
131
+ return describeAccountSnapshot({
132
+ account,
133
+ configured: isSlackSetupAccountConfigured(account),
134
+ extra: {
135
+ botTokenSource: account.botTokenSource,
136
+ appTokenSource: account.appTokenSource,
137
+ ...account.identity === "user" ? {
138
+ identity: account.identity,
139
+ userTokenSource: account.userTokenSource
140
+ } : {}
141
+ }
142
+ });
143
+ }
144
+ //#endregion
145
+ //#region extensions/slack/src/setup-core.ts
146
+ const t = createSetupTranslator();
147
+ function enableSlackAccount(cfg, accountId) {
148
+ return patchChannelConfigForAccount({
149
+ cfg,
150
+ channel: SLACK_CHANNEL,
151
+ accountId,
152
+ patch: { enabled: true }
153
+ });
154
+ }
155
+ function setSlackSetupIdentity(params) {
156
+ const next = patchChannelConfigForAccount({
157
+ cfg: params.cfg,
158
+ channel: SLACK_CHANNEL,
159
+ accountId: params.accountId,
160
+ patch: params.identity === "user" ? { postAs: "user" } : {}
161
+ });
162
+ if (params.identity === "user") return next;
163
+ const slack = next.channels?.slack;
164
+ if (!slack) return next;
165
+ if (params.accountId === DEFAULT_ACCOUNT_ID) {
166
+ const nextSlack = { ...slack };
167
+ delete nextSlack.postAs;
168
+ return {
169
+ ...next,
170
+ channels: {
171
+ ...next.channels,
172
+ slack: nextSlack
173
+ }
174
+ };
175
+ }
176
+ const account = slack.accounts?.[params.accountId];
177
+ if (!account) return next;
178
+ const nextAccount = { ...account };
179
+ if (slack.postAs === "user") nextAccount.postAs = "bot";
180
+ else delete nextAccount.postAs;
181
+ return {
182
+ ...next,
183
+ channels: {
184
+ ...next.channels,
185
+ slack: {
186
+ ...slack,
187
+ accounts: {
188
+ ...slack.accounts,
189
+ [params.accountId]: nextAccount
190
+ }
191
+ }
192
+ }
193
+ };
194
+ }
195
+ function hasSlackInteractiveRepliesConfig(cfg, accountId) {
196
+ const capabilities = inspectSlackAccount({
197
+ cfg,
198
+ accountId
199
+ }).config.capabilities;
200
+ if (Array.isArray(capabilities)) return capabilities.some((entry) => normalizeLowercaseStringOrEmpty(entry) === "interactivereplies");
201
+ if (!capabilities || typeof capabilities !== "object") return false;
202
+ return "interactiveReplies" in capabilities;
203
+ }
204
+ function setSlackInteractiveReplies(cfg, accountId, interactiveReplies) {
205
+ const capabilities = inspectSlackAccount({
206
+ cfg,
207
+ accountId
208
+ }).config.capabilities;
209
+ return patchChannelConfigForAccount({
210
+ cfg,
211
+ channel: SLACK_CHANNEL,
212
+ accountId,
213
+ patch: { capabilities: Array.isArray(capabilities) ? interactiveReplies ? uniqueStrings([...capabilities, "interactiveReplies"]) : capabilities.filter((entry) => normalizeLowercaseStringOrEmpty(entry) !== "interactivereplies") : {
214
+ ...capabilities && typeof capabilities === "object" ? capabilities : {},
215
+ interactiveReplies
216
+ } }
217
+ });
218
+ }
219
+ function createSlackTokenCredential(params) {
220
+ return defineTokenCredential({
221
+ inputKey: params.inputKey,
222
+ configKey: params.inputKey,
223
+ providerHint: params.providerHint,
224
+ credentialLabel: params.credentialLabel,
225
+ preferredEnvVar: params.preferredEnvVar,
226
+ envPrompt: params.preferredEnvVar ? `${params.preferredEnvVar} detected. Use env var?` : "Use the configured Slack credential?",
227
+ keepPrompt: params.keepPrompt,
228
+ inputPrompt: params.inputPrompt,
229
+ allowEnv: ({ accountId }) => Boolean(params.preferredEnvVar) && accountId === DEFAULT_ACCOUNT_ID,
230
+ resolveAccount: ({ cfg, accountId }) => inspectSlackAccount({
231
+ cfg,
232
+ accountId
233
+ }),
234
+ resolvedValue: (account) => {
235
+ if (params.inputKey === "botToken") return normalizeOptionalString(account.botToken);
236
+ if (params.inputKey === "appToken") return normalizeOptionalString(account.appToken);
237
+ if (params.inputKey === "userToken") return normalizeOptionalString(account.userToken);
238
+ return normalizeSecretInputString(account.config.signingSecret);
239
+ },
240
+ envValue: ({ accountId }) => params.preferredEnvVar && accountId === DEFAULT_ACCOUNT_ID ? normalizeOptionalString(process.env[params.preferredEnvVar]) : void 0,
241
+ patchAccount: ({ cfg, accountId, mode, patch }) => mode === "env" ? enableSlackAccount(cfg, accountId) : patchChannelConfigForAccount({
242
+ cfg,
243
+ channel: SLACK_CHANNEL,
244
+ accountId,
245
+ patch: {
246
+ enabled: true,
247
+ ...patch
248
+ }
249
+ }),
250
+ useEnv: { clearFields: [] },
251
+ set: {},
252
+ shouldPrompt: params.shouldPrompt
253
+ });
254
+ }
255
+ function hasSlackSetupCredentials(params) {
256
+ if (params.identity !== "user") {
257
+ const { input } = params;
258
+ return Boolean(input.botToken && input.appToken);
259
+ }
260
+ if (params.mode === "http") return Boolean(params.input.userToken && params.input.signingSecret);
261
+ return params.mode === "socket" && Boolean(params.input.userToken && params.input.appToken);
262
+ }
263
+ const slackSetupAdapterBase = createPatchedAccountSetupAdapter({
264
+ channelKey: SLACK_CHANNEL,
265
+ validateInput: ({ cfg, accountId, input }) => {
266
+ const setupInput = input;
267
+ if (setupInput.useEnv && accountId !== DEFAULT_ACCOUNT_ID) return "Slack env tokens can only be used for the default account.";
268
+ const account = inspectSlackAccount({
269
+ cfg,
270
+ accountId
271
+ });
272
+ const identity = setupInput.identity ?? account.config.postAs ?? "bot";
273
+ const mode = setupInput.mode ?? account.config.mode ?? "socket";
274
+ if (identity === "user" && mode === "relay") return "Slack user identity setup supports mode \"socket\" or \"http\", not \"relay\".";
275
+ if (setupInput.useEnv) return identity === "user" ? "Slack user identity setup does not support --use-env; configure userToken and the transport credential explicitly." : null;
276
+ if (hasSlackSetupCredentials({
277
+ input: setupInput,
278
+ identity,
279
+ mode
280
+ })) return null;
281
+ if (identity === "user") return mode === "http" ? "Slack user identity requires --user-token and --signing-secret." : "Slack user identity requires --user-token and --app-token.";
282
+ return "Slack requires --bot-token and --app-token (or --use-env).";
283
+ },
284
+ buildPatch: (input) => {
285
+ const setupInput = input;
286
+ return {
287
+ ...setupInput.identity ? { postAs: setupInput.identity } : {},
288
+ ...setupInput.identity === "user" && setupInput.mode ? { mode: setupInput.mode } : {},
289
+ ...setupInput.botToken ? { botToken: setupInput.botToken } : {},
290
+ ...setupInput.appToken ? { appToken: setupInput.appToken } : {},
291
+ ...setupInput.userToken ? { userToken: setupInput.userToken } : {},
292
+ ...setupInput.signingSecret ? { signingSecret: setupInput.signingSecret } : {}
293
+ };
294
+ }
295
+ });
296
+ const slackSetupAdapter = {
297
+ ...slackSetupAdapterBase,
298
+ singleAccountKeysToMove: ["appToken"],
299
+ applyAccountConfig: ({ cfg, accountId, input }) => {
300
+ const setupInput = input;
301
+ const identity = setupInput.identity ?? inspectSlackAccount({
302
+ cfg,
303
+ accountId
304
+ }).config.postAs;
305
+ return slackSetupAdapterBase.applyAccountConfig({
306
+ cfg,
307
+ accountId,
308
+ input: identity === "user" ? {
309
+ ...setupInput,
310
+ identity
311
+ } : setupInput
312
+ });
313
+ }
314
+ };
315
+ const slackSetupContract = defineChannelSetupContract({
316
+ fields: {
317
+ botToken: {
318
+ kind: "string",
319
+ sensitive: true,
320
+ cli: {
321
+ flags: "--bot-token <token>",
322
+ description: "Slack bot token"
323
+ }
324
+ },
325
+ appToken: {
326
+ kind: "string",
327
+ sensitive: true,
328
+ cli: {
329
+ flags: "--app-token <token>",
330
+ description: "Slack app token"
331
+ }
332
+ },
333
+ userToken: {
334
+ kind: "string",
335
+ sensitive: true,
336
+ cli: {
337
+ flags: "--user-token <token>",
338
+ description: "Slack user token"
339
+ }
340
+ },
341
+ signingSecret: {
342
+ kind: "string",
343
+ sensitive: true,
344
+ cli: {
345
+ flags: "--signing-secret <secret>",
346
+ description: "Slack signing secret"
347
+ }
348
+ },
349
+ identity: {
350
+ kind: "choice",
351
+ choices: ["bot", "user"],
352
+ cli: {
353
+ flags: "--identity <kind>",
354
+ description: "Slack identity"
355
+ }
356
+ },
357
+ mode: {
358
+ kind: "choice",
359
+ choices: ["socket", "http"],
360
+ cli: {
361
+ flags: "--mode <mode>",
362
+ description: "Slack connection mode"
363
+ }
364
+ },
365
+ useEnv: {
366
+ kind: "boolean",
367
+ cli: {
368
+ flags: "--use-env",
369
+ description: "Use Slack environment credentials"
370
+ }
371
+ }
372
+ },
373
+ legacyAdapter: slackSetupAdapter
374
+ });
375
+ function createSlackSetupWizardBase(handlers) {
376
+ const slackDmPolicy = {
377
+ label: "Slack",
378
+ channel: SLACK_CHANNEL,
379
+ policyKey: "channels.slack.dmPolicy",
380
+ allowFromKey: "channels.slack.allowFrom",
381
+ resolveConfigKeys: (_cfg, accountId) => accountId && accountId !== DEFAULT_ACCOUNT_ID ? {
382
+ policyKey: `channels.slack.accounts.${accountId}.dmPolicy`,
383
+ allowFromKey: `channels.slack.accounts.${accountId}.allowFrom`
384
+ } : {
385
+ policyKey: "channels.slack.dmPolicy",
386
+ allowFromKey: "channels.slack.allowFrom"
387
+ },
388
+ getCurrent: (cfg, accountId) => inspectSlackAccount({
389
+ cfg,
390
+ accountId
391
+ }).config.dmPolicy ?? "pairing",
392
+ setPolicy: (cfg, policy, accountId) => {
393
+ const account = inspectSlackAccount({
394
+ cfg,
395
+ accountId
396
+ });
397
+ return patchChannelConfigForAccount({
398
+ cfg,
399
+ channel: SLACK_CHANNEL,
400
+ accountId: account.accountId,
401
+ patch: {
402
+ dmPolicy: policy,
403
+ ...policy === "open" ? { allowFrom: mergeAllowFromEntries(account.config.allowFrom ?? [], ["*"]) } : {},
404
+ dm: {
405
+ ...account.config.dm,
406
+ enabled: typeof account.config.dm?.enabled === "boolean" ? account.config.dm.enabled : true
407
+ }
408
+ }
409
+ });
410
+ },
411
+ promptAllowFrom: handlers.promptAllowFrom
412
+ };
413
+ return {
414
+ channel: SLACK_CHANNEL,
415
+ status: createStandardChannelSetupStatus({
416
+ channelLabel: "Slack",
417
+ configuredLabel: t("wizard.channels.statusConfigured"),
418
+ unconfiguredLabel: t("wizard.channels.statusNeedsTokens"),
419
+ configuredHint: t("wizard.channels.statusConfigured"),
420
+ unconfiguredHint: t("wizard.channels.statusNeedsTokens"),
421
+ configuredScore: 2,
422
+ unconfiguredScore: 1,
423
+ resolveConfigured: ({ cfg, accountId }) => inspectSlackAccount({
424
+ cfg,
425
+ accountId
426
+ }).configured
427
+ }),
428
+ prepare: async ({ cfg, accountId, prompter }) => {
429
+ const currentAccount = inspectSlackAccount({
430
+ cfg,
431
+ accountId
432
+ });
433
+ if (currentAccount.configured && currentAccount.config.postAs !== "user") return { cfg };
434
+ const identity = await prompter.select({
435
+ message: "How should OpenClaw appear in Slack?",
436
+ options: [{
437
+ value: "bot",
438
+ label: "Slack bot",
439
+ hint: "Post as the Slack app (default)"
440
+ }, {
441
+ value: "user",
442
+ label: "Slack user",
443
+ hint: "Post as the authorizing human"
444
+ }],
445
+ initialValue: currentAccount.config.postAs ?? "bot"
446
+ });
447
+ const next = setSlackSetupIdentity({
448
+ cfg,
449
+ accountId,
450
+ identity
451
+ });
452
+ if (currentAccount.configured && identity === currentAccount.config.postAs) return { cfg: next };
453
+ if (identity === "user") {
454
+ if (currentAccount.config.mode === "relay") throw new Error("Slack user identity setup supports mode \"socket\" or \"http\", not \"relay\".");
455
+ await prompter.note([
456
+ "Use a Slack user OAuth token with the User Token Scopes listed in the Slack docs.",
457
+ "Subscribe the companion app under 'Subscribe to events on behalf of users' using the documented user events.",
458
+ "Socket Mode needs an app-level token; HTTP mode needs the app signing secret.",
459
+ "No bot token or bot user is required.",
460
+ `Docs: ${formatDocsLink("/channels/slack#user-identity-post-as-a-real-person", "channels/slack")}`
461
+ ].join("\n"), "Slack user identity");
462
+ } else {
463
+ await prompter.note(buildSlackSetupLines().join("\n"), t("wizard.slack.socketModeTokensTitle"));
464
+ const manifest = buildSlackManifest();
465
+ if (prompter.plain) await prompter.plain(manifest);
466
+ else await prompter.note(manifest, "Slack manifest JSON");
467
+ }
468
+ return { cfg: next };
469
+ },
470
+ envShortcut: {
471
+ prompt: t("wizard.slack.envPrompt"),
472
+ preferredEnvVar: "SLACK_BOT_TOKEN",
473
+ isAvailable: ({ cfg, accountId }) => accountId === DEFAULT_ACCOUNT_ID && (inspectSlackAccount({
474
+ cfg,
475
+ accountId
476
+ }).config.postAs ?? "bot") === "bot" && Boolean(process.env.SLACK_BOT_TOKEN?.trim()) && Boolean(process.env.SLACK_APP_TOKEN?.trim()) && !inspectSlackAccount({
477
+ cfg,
478
+ accountId
479
+ }).configured,
480
+ apply: ({ cfg, accountId }) => enableSlackAccount(cfg, accountId)
481
+ },
482
+ credentials: [
483
+ createSlackTokenCredential({
484
+ inputKey: "botToken",
485
+ providerHint: "slack-bot",
486
+ credentialLabel: t("wizard.slack.botToken"),
487
+ preferredEnvVar: "SLACK_BOT_TOKEN",
488
+ keepPrompt: t("wizard.slack.botTokenKeep"),
489
+ inputPrompt: t("wizard.slack.botTokenInput"),
490
+ shouldPrompt: ({ cfg, accountId }) => (inspectSlackAccount({
491
+ cfg,
492
+ accountId
493
+ }).config.postAs ?? "bot") === "bot"
494
+ }),
495
+ createSlackTokenCredential({
496
+ inputKey: "userToken",
497
+ providerHint: "slack-user",
498
+ credentialLabel: "Slack user OAuth token",
499
+ preferredEnvVar: "SLACK_USER_TOKEN",
500
+ keepPrompt: "Slack user OAuth token already configured. Keep it?",
501
+ inputPrompt: "Enter Slack user OAuth token",
502
+ shouldPrompt: ({ cfg, accountId }) => inspectSlackAccount({
503
+ cfg,
504
+ accountId
505
+ }).config.postAs === "user"
506
+ }),
507
+ createSlackTokenCredential({
508
+ inputKey: "appToken",
509
+ providerHint: "slack-app",
510
+ credentialLabel: t("wizard.slack.appToken"),
511
+ preferredEnvVar: "SLACK_APP_TOKEN",
512
+ keepPrompt: t("wizard.slack.appTokenKeep"),
513
+ inputPrompt: t("wizard.slack.appTokenInput"),
514
+ shouldPrompt: ({ cfg, accountId }) => {
515
+ const account = inspectSlackAccount({
516
+ cfg,
517
+ accountId
518
+ });
519
+ return (account.config.postAs ?? "bot") === "bot" || (account.config.mode ?? "socket") === "socket";
520
+ }
521
+ }),
522
+ createSlackTokenCredential({
523
+ inputKey: "signingSecret",
524
+ providerHint: "slack-signing-secret",
525
+ credentialLabel: "Slack signing secret",
526
+ keepPrompt: "Slack signing secret already configured. Keep it?",
527
+ inputPrompt: "Enter Slack signing secret",
528
+ shouldPrompt: ({ cfg, accountId }) => {
529
+ const account = inspectSlackAccount({
530
+ cfg,
531
+ accountId
532
+ });
533
+ return account.config.postAs === "user" && account.config.mode === "http";
534
+ }
535
+ })
536
+ ],
537
+ dmPolicy: slackDmPolicy,
538
+ allowFrom: createAccountScopedAllowFromSection({
539
+ channel: SLACK_CHANNEL,
540
+ helpTitle: t("wizard.slack.allowlistTitle"),
541
+ helpLines: [
542
+ t("wizard.slack.allowlistIntro"),
543
+ t("wizard.slack.examples"),
544
+ "- U12345678",
545
+ "- @alice",
546
+ t("wizard.slack.multipleEntries"),
547
+ t("wizard.channels.docs", { link: formatDocsLink("/slack", "slack") })
548
+ ],
549
+ message: t("wizard.slack.allowFromPrompt"),
550
+ placeholder: "@alice, U12345678",
551
+ invalidWithoutCredentialNote: t("wizard.slack.allowFromInvalidWithoutToken"),
552
+ parseId: (value) => parseMentionOrPrefixedId({
553
+ value,
554
+ mentionPattern: /^<@([A-Z0-9]+)>$/i,
555
+ prefixPattern: /^(slack:|user:)/i,
556
+ idPattern: /^[A-Z][A-Z0-9]+$/i,
557
+ normalizeId: (id) => id.toUpperCase()
558
+ }),
559
+ resolveEntries: handlers.resolveAllowFromEntries
560
+ }),
561
+ groupAccess: createAccountScopedGroupAccessSection({
562
+ channel: SLACK_CHANNEL,
563
+ label: t("wizard.slack.channelsLabel"),
564
+ placeholder: "#general, #private, C123",
565
+ currentPolicy: ({ cfg, accountId }) => inspectSlackAccount({
566
+ cfg,
567
+ accountId
568
+ }).config.groupPolicy ?? "allowlist",
569
+ currentEntries: ({ cfg, accountId }) => Object.entries(inspectSlackAccount({
570
+ cfg,
571
+ accountId
572
+ }).config.channels ?? {}).filter(([, value]) => value?.enabled !== false).map(([key]) => key),
573
+ updatePrompt: ({ cfg, accountId }) => Boolean(inspectSlackAccount({
574
+ cfg,
575
+ accountId
576
+ }).config.channels),
577
+ resolveAllowlist: handlers.resolveGroupAllowlist,
578
+ fallbackResolved: (entries) => entries,
579
+ applyAllowlist: ({ cfg, accountId, resolved }) => setSlackChannelAllowlist(cfg, accountId, resolved)
580
+ }),
581
+ finalize: async ({ cfg, accountId, options, prompter }) => {
582
+ if (hasSlackInteractiveRepliesConfig(cfg, accountId)) return;
583
+ if (options?.quickstartDefaults) return { cfg: setSlackInteractiveReplies(cfg, accountId, true) };
584
+ return { cfg: setSlackInteractiveReplies(cfg, accountId, await prompter.confirm({
585
+ message: t("wizard.slack.interactiveRepliesPrompt"),
586
+ initialValue: true
587
+ })) };
588
+ },
589
+ disable: (cfg) => setSetupChannelEnabled(cfg, SLACK_CHANNEL, false)
590
+ };
591
+ }
592
+ function createSlackSetupWizardProxy(loadWizard) {
593
+ return createAllowlistSetupWizardProxy({
594
+ loadWizard: async () => (await loadWizard()).slackSetupWizard,
595
+ createBase: createSlackSetupWizardBase,
596
+ fallbackResolvedGroupAllowlist: (entries) => entries
597
+ });
598
+ }
599
+ //#endregion
600
+ export { SLACK_CHANNEL as a, slackSetupContract as i, createSlackSetupWizardProxy as n, describeSlackSetupAccount as o, slackSetupAdapter as r, isSlackSetupAccountConfigured as s, createSlackSetupWizardBase as t };
@@ -1,2 +1,2 @@
1
- import { t as slackSetupPlugin } from "./channel.setup-C-mLz50O.js";
1
+ import { t as slackSetupPlugin } from "./channel.setup-DOSTEDfA.js";
2
2
  export { slackSetupPlugin };