@openclaw/slack 2026.7.2-beta.7 → 2026.8.1-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{account-inspect-DEKpg9Ip.js → account-inspect-YJvFBbCR.js} +1 -1
- package/dist/account-inspect-api.js +1 -1
- package/dist/{accounts-CHAeNZOX.js → accounts-BlzxuYle.js} +7 -3
- package/dist/{accounts.runtime-BHD4Ma2R.js → accounts.runtime-CbabBL8x.js} +1 -1
- package/dist/{action-runtime-DfuYoMjG.js → action-runtime-D6jg2CQd.js} +193 -125
- package/dist/action-runtime.runtime-JtoOK9l5.js +2 -0
- package/dist/{actions-D3NuJvva.js → actions-DFk0ANVB.js} +116 -235
- package/dist/actions.runtime-CYLsYRai.js +2 -0
- package/dist/api.js +17 -17
- package/dist/{approval-handler.runtime-BA05P0QT.js → approval-handler.runtime-BNvAoKdK.js} +53 -14
- package/dist/{channel-B9fVdW3s.js → channel-CA5w7qDF.js} +209 -110
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-type-DXyos1d2.js → channel-type-CZWv55Wu.js} +9 -12
- package/dist/{config-adapter-CxBQH8fq.js → channel.setup-CpyYsEXH.js} +83 -25
- package/dist/{config-schema-SgZT6nXV.js → config-schema-CN3XZRX5.js} +27 -17
- package/dist/conversation-binding-route-DFVLUdYF.js +115 -0
- package/dist/{directory-config-CnCIAktf.js → directory-config-BGYyuzWh.js} +3 -3
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-DKunWh3A.js → directory-live-DjUJQLbq.js} +13 -22
- package/dist/{doctor-contract-CsGH1Dfc.js → doctor-contract-BAy7-EUQ.js} +30 -3
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{group-policy-NQZti9t-.js → group-policy-DyfB_ZIE.js} +282 -183
- package/dist/index.js +4 -1
- package/dist/{message-tool-api-DkhFpMoy.js → message-tool-api-CqMr5Rmc.js} +14 -3
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-CmKz0wtI.js → monitor-Chrecrb9.js} +3 -3
- package/dist/{outbound-adapter-BkuMp2Vs.js → outbound-adapter-DuRqAQXK.js} +35 -23
- package/dist/{pipeline.runtime-DgtmuYCP.js → pipeline.runtime-Bbfd5VFW.js} +1386 -929
- package/dist/{policy-PRysPn23.js → policy-BKXSxrIS.js} +18 -14
- package/dist/{probe-CgDsSops.js → probe-BVA65leh.js} +38 -18
- package/dist/{provider-DmRizMZt.js → provider-CUUiwsg2.js} +3454 -2601
- package/dist/{relay-source-Blxj8xb4.js → relay-source-mhpMMRG-.js} +11 -21
- package/dist/{replies-4s_Vq_z9.js → replies-SnWyXcsL.js} +84 -27
- package/dist/{resolve-channels-yEqmM-3I.js → resolve-channels-BSpqC8jU.js} +39 -12
- package/dist/{resolve-users-BOrt5K-5.js → resolve-users-Dvz9pDe0.js} +28 -5
- package/dist/{runtime-api-QMb-Q5Ko.js → runtime-api-DBi7xc_g.js} +3 -3
- package/dist/runtime-api.js +11 -11
- package/dist/{scopes-BJSrkAp6.js → scopes-BSk4GZvZ.js} +1 -1
- package/dist/security-contract-api.js +1 -1
- package/dist/{send-DsLeZpST.js → send-CtnOxKCc.js} +249 -163
- package/dist/{send.runtime-gUdK6V3h.js → send.runtime-kYctMHSd.js} +1 -1
- package/dist/setup-entry.js +1 -4
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-BeNzrMrJ.js → setup-surface-BPFfp6So.js} +6 -6
- package/dist/{shared-DgIN3Dcr.js → shared-DJBaslN7.js} +45 -45
- package/dist/{block-text-DkHaoGem.js → slack-client-kind-BXyOOICI.js} +17 -2
- package/dist/{slash-dispatch.runtime-zPkyl7dB.js → slash-dispatch.runtime-Cf2FTrnf.js} +2 -2
- package/dist/{streaming-compat-3_X-21wW.js → streaming-compat-B-e0mqM0.js} +3 -8
- package/dist/{target-parsing-N6lHogYZ.js → target-parsing-BnMD2ZqZ.js} +40 -2
- package/dist/{targets-KmjP2E8s.js → targets-Cx5W_n3W.js} +1 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/crypto.d.ts +1 -1
- package/node_modules/@slack/bolt/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/socket-mode/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/crypto.d.ts +1 -1
- package/node_modules/@slack/socket-mode/node_modules/@types/node/package.json +2 -2
- package/node_modules/@slack/web-api/node_modules/@types/node/README.md +1 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/crypto.d.ts +1 -1
- package/node_modules/@slack/web-api/node_modules/@types/node/package.json +2 -2
- package/node_modules/undici/lib/cache/memory-cache-store.js +54 -9
- package/node_modules/undici/lib/cache/sqlite-cache-store.js +7 -1
- package/node_modules/undici/lib/core/request.js +12 -1
- package/node_modules/undici/lib/dispatcher/client-h1.js +11 -2
- package/node_modules/undici/lib/handler/cache-handler.js +246 -64
- package/node_modules/undici/lib/handler/cache-revalidation-handler.js +3 -3
- package/node_modules/undici/lib/handler/retry-handler.js +24 -0
- package/node_modules/undici/lib/interceptor/cache.js +159 -52
- package/node_modules/undici/lib/util/cache.js +324 -62
- package/node_modules/undici/lib/util/date.js +23 -6
- package/node_modules/undici/lib/web/cookies/util.js +79 -9
- package/node_modules/undici/package.json +1 -1
- package/openclaw.plugin.json +280 -33
- package/package.json +9 -11
- package/skills/slack/SKILL.md +10 -68
- package/dist/account-reply-mode-DrUXogvO.js +0 -14
- package/dist/action-runtime.runtime-DQErZYpz.js +0 -2
- package/dist/actions.runtime-BIRU_G4M.js +0 -2
- package/dist/channel.setup-CLP5oTvh.js +0 -56
- package/dist/preflight-audio.runtime-D5Bgags0.js +0 -3
- package/dist/slash-plugin-commands.runtime-Dosfcx3X.js +0 -2
- package/node_modules/p-map/index.d.ts +0 -155
- package/node_modules/p-map/index.js +0 -285
- package/node_modules/p-map/license +0 -9
- package/node_modules/p-map/package.json +0 -57
- package/node_modules/p-map/readme.md +0 -190
- package/dist/{security-audit-DR097212.js → security-audit-B_yKr7MW.js} +1 -1
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { a as resolveSlackAccount, l as resolveSlackOperationToken } from "./accounts-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { a as resolveSlackAccount, l as resolveSlackOperationToken } from "./accounts-BlzxuYle.js";
|
|
3
|
+
import { g as assertSlackDetachedTargetAllowed, u as normalizeAllowListLower } from "./group-policy-DyfB_ZIE.js";
|
|
4
|
+
import { a as createSlackReadClient, c as createSlackWebClient } from "./probe-BVA65leh.js";
|
|
5
5
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
8
8
|
//#region extensions/slack/src/channel-type.ts
|
|
9
9
|
var channel_type_exports = /* @__PURE__ */ __exportAll({
|
|
10
|
-
__resetSlackChannelTypeCacheForTest: () => resetSlackChannelTypeCacheForTest,
|
|
11
|
-
resetSlackChannelTypeCacheForTest: () => resetSlackChannelTypeCacheForTest,
|
|
12
10
|
resolveSlackChannelType: () => resolveSlackChannelType,
|
|
13
11
|
resolveSlackConversationInfo: () => resolveSlackConversationInfo
|
|
14
12
|
});
|
|
@@ -47,12 +45,14 @@ async function resolveSlackConversationInfo(params) {
|
|
|
47
45
|
cfg: params.cfg,
|
|
48
46
|
accountId: params.accountId
|
|
49
47
|
});
|
|
48
|
+
assertSlackDetachedTargetAllowed(account.accountId, params.teamId);
|
|
50
49
|
const operation = params.operation ?? "read";
|
|
51
50
|
const token = resolveSlackOperationToken(account, operation);
|
|
52
51
|
const userToken = normalizeOptionalString(account.userToken);
|
|
53
52
|
const credentialRole = token ? token === userToken ? "user" : "bot" : "none";
|
|
54
53
|
const credentialFingerprint = token ? fingerprintSlackCredential(token) : "none";
|
|
55
|
-
const
|
|
54
|
+
const teamId = normalizeLowercaseStringOrEmpty(params.teamId) || "no-team-id";
|
|
55
|
+
const cacheKey = `${account.accountId}:${teamId}:${operation}:${credentialRole}:${credentialFingerprint}:${channelId}`;
|
|
56
56
|
if (!params.requireFreshName) {
|
|
57
57
|
const cached = getCachedSlackConversationInfo(cacheKey);
|
|
58
58
|
if (cached) return cached;
|
|
@@ -64,7 +64,7 @@ async function resolveSlackConversationInfo(params) {
|
|
|
64
64
|
});
|
|
65
65
|
if (token) try {
|
|
66
66
|
if (isNativeImChannel && operation === "write") {
|
|
67
|
-
const opened = await createSlackWebClient(token).conversations.open({
|
|
67
|
+
const opened = await createSlackWebClient(token, { teamId: params.teamId }).conversations.open({
|
|
68
68
|
channel: channelId,
|
|
69
69
|
prevent_creation: true,
|
|
70
70
|
return_im: true
|
|
@@ -77,7 +77,7 @@ async function resolveSlackConversationInfo(params) {
|
|
|
77
77
|
if (user) setCachedSlackConversationInfo(cacheKey, result);
|
|
78
78
|
return result;
|
|
79
79
|
}
|
|
80
|
-
const channel = (await createSlackReadClient(token).conversations.info({ channel: channelId })).channel;
|
|
80
|
+
const channel = (await createSlackReadClient(token, { teamId: params.teamId }).conversations.info({ channel: channelId })).channel;
|
|
81
81
|
const type = channel?.is_im ? "dm" : channel?.is_mpim ? "group" : "channel";
|
|
82
82
|
const name = normalizeOptionalString(channel?.name);
|
|
83
83
|
const user = normalizeOptionalString(channel?.user);
|
|
@@ -101,8 +101,5 @@ async function resolveSlackConversationInfo(params) {
|
|
|
101
101
|
async function resolveSlackChannelType(params) {
|
|
102
102
|
return (await resolveSlackConversationInfo(params)).type;
|
|
103
103
|
}
|
|
104
|
-
function resetSlackChannelTypeCacheForTest() {
|
|
105
|
-
SLACK_CONVERSATION_INFO_CACHE.clear();
|
|
106
|
-
}
|
|
107
104
|
//#endregion
|
|
108
|
-
export {
|
|
105
|
+
export { resolveSlackChannelType as n, resolveSlackConversationInfo as r, channel_type_exports as t };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { a as resolveSlackAccount, c as resolveSlackConfigAccessorAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds } from "./accounts-
|
|
2
|
-
import { t as inspectSlackAccount } from "./account-inspect-
|
|
1
|
+
import { a as resolveSlackAccount, c as resolveSlackConfigAccessorAccount, i as resolveDefaultSlackAccountId, n as listSlackAccountIds } from "./accounts-BlzxuYle.js";
|
|
2
|
+
import { t as inspectSlackAccount } from "./account-inspect-YJvFBbCR.js";
|
|
3
3
|
import { t as isSlackPluginAccountConfigured } from "./account-configured-BwfXBo_F.js";
|
|
4
|
+
import { t as SlackChannelConfigSchema } from "./config-schema-CN3XZRX5.js";
|
|
4
5
|
import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
5
6
|
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
7
|
import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
@@ -247,7 +248,12 @@ const slackSetupAdapterBase = createPatchedAccountSetupAdapter({
|
|
|
247
248
|
const identity = setupInput.identity ?? account.config.postAs ?? "bot";
|
|
248
249
|
const mode = setupInput.mode ?? account.config.mode ?? "socket";
|
|
249
250
|
if (identity === "user" && mode === "relay") return "Slack user identity setup supports mode \"socket\" or \"http\", not \"relay\".";
|
|
250
|
-
if (setupInput.useEnv)
|
|
251
|
+
if (setupInput.useEnv) {
|
|
252
|
+
if (identity === "user") return "Slack user identity setup does not support --use-env; configure userToken and the transport credential explicitly.";
|
|
253
|
+
if (mode === "socket" && !normalizeOptionalString(setupInput.appToken) && account.appTokenStatus === "missing") return "Slack Socket Mode requires SLACK_APP_TOKEN when using --use-env.";
|
|
254
|
+
if (mode === "http" && !normalizeOptionalString(setupInput.signingSecret) && account.signingSecretStatus === "missing") return "Slack HTTP mode requires a configured signing secret when using --use-env.";
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
251
257
|
if (hasSlackSetupCredentials({
|
|
252
258
|
input: setupInput,
|
|
253
259
|
identity,
|
|
@@ -268,25 +274,6 @@ const slackSetupAdapterBase = createPatchedAccountSetupAdapter({
|
|
|
268
274
|
};
|
|
269
275
|
}
|
|
270
276
|
});
|
|
271
|
-
const slackSetupAdapter = {
|
|
272
|
-
...slackSetupAdapterBase,
|
|
273
|
-
singleAccountKeysToMove: ["appToken"],
|
|
274
|
-
applyAccountConfig: ({ cfg, accountId, input }) => {
|
|
275
|
-
const setupInput = input;
|
|
276
|
-
const identity = setupInput.identity ?? inspectSlackAccount({
|
|
277
|
-
cfg,
|
|
278
|
-
accountId
|
|
279
|
-
}).config.postAs;
|
|
280
|
-
return slackSetupAdapterBase.applyAccountConfig({
|
|
281
|
-
cfg,
|
|
282
|
-
accountId,
|
|
283
|
-
input: identity === "user" ? {
|
|
284
|
-
...setupInput,
|
|
285
|
-
identity
|
|
286
|
-
} : setupInput
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
277
|
const slackSetupContract = defineChannelSetupContract({
|
|
291
278
|
fields: {
|
|
292
279
|
botToken: {
|
|
@@ -342,10 +329,29 @@ const slackSetupContract = defineChannelSetupContract({
|
|
|
342
329
|
cli: {
|
|
343
330
|
flags: "--use-env",
|
|
344
331
|
description: "Use Slack environment credentials"
|
|
345
|
-
}
|
|
332
|
+
},
|
|
333
|
+
envVars: ["SLACK_BOT_TOKEN"]
|
|
346
334
|
}
|
|
347
335
|
},
|
|
348
|
-
legacyAdapter:
|
|
336
|
+
legacyAdapter: {
|
|
337
|
+
...slackSetupAdapterBase,
|
|
338
|
+
singleAccountKeysToMove: ["appToken"],
|
|
339
|
+
applyAccountConfig: ({ cfg, accountId, input }) => {
|
|
340
|
+
const setupInput = input;
|
|
341
|
+
const identity = setupInput.identity ?? inspectSlackAccount({
|
|
342
|
+
cfg,
|
|
343
|
+
accountId
|
|
344
|
+
}).config.postAs;
|
|
345
|
+
return slackSetupAdapterBase.applyAccountConfig({
|
|
346
|
+
cfg,
|
|
347
|
+
accountId,
|
|
348
|
+
input: identity === "user" ? {
|
|
349
|
+
...setupInput,
|
|
350
|
+
identity
|
|
351
|
+
} : setupInput
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
349
355
|
});
|
|
350
356
|
function createSlackSetupWizardBase(handlers) {
|
|
351
357
|
const slackDmPolicy = createChannelDmPolicy({
|
|
@@ -563,4 +569,56 @@ const slackBaseConfigAdapter = createScopedChannelConfigAdapter({
|
|
|
563
569
|
resolveDefaultTo: (account) => account.defaultTo
|
|
564
570
|
});
|
|
565
571
|
//#endregion
|
|
566
|
-
|
|
572
|
+
//#region extensions/slack/src/channel.setup.ts
|
|
573
|
+
const slackSetupWizard = createSlackSetupWizardProxy(async () => ({ slackSetupWizard: (await import("./setup-surface-BPFfp6So.js")).slackSetupWizard }));
|
|
574
|
+
const slackSetupPlugin = {
|
|
575
|
+
id: SLACK_CHANNEL,
|
|
576
|
+
meta: {
|
|
577
|
+
id: SLACK_CHANNEL,
|
|
578
|
+
label: "Slack",
|
|
579
|
+
selectionLabel: "Slack (Socket Mode)",
|
|
580
|
+
detailLabel: "Slack Bot",
|
|
581
|
+
docsPath: "/channels/slack",
|
|
582
|
+
docsLabel: "slack",
|
|
583
|
+
blurb: "supported (Socket Mode).",
|
|
584
|
+
systemImage: "number",
|
|
585
|
+
markdownCapable: true,
|
|
586
|
+
preferSessionLookupForAnnounceTarget: true
|
|
587
|
+
},
|
|
588
|
+
setupWizard: slackSetupWizard,
|
|
589
|
+
capabilities: {
|
|
590
|
+
chatTypes: [
|
|
591
|
+
"direct",
|
|
592
|
+
"channel",
|
|
593
|
+
"thread"
|
|
594
|
+
],
|
|
595
|
+
reactions: true,
|
|
596
|
+
threads: true,
|
|
597
|
+
media: true,
|
|
598
|
+
nativeCommands: true
|
|
599
|
+
},
|
|
600
|
+
commands: {
|
|
601
|
+
nativeCommandsAutoEnabled: false,
|
|
602
|
+
nativeSkillsAutoEnabled: false,
|
|
603
|
+
resolveNativeCommandName: ({ commandKey, defaultName }) => commandKey === "status" ? "agentstatus" : defaultName
|
|
604
|
+
},
|
|
605
|
+
streaming: { blockStreamingCoalesceDefaults: {
|
|
606
|
+
minChars: 1500,
|
|
607
|
+
idleMs: 1e3
|
|
608
|
+
} },
|
|
609
|
+
reload: { configPrefixes: ["channels.slack"] },
|
|
610
|
+
configSchema: SlackChannelConfigSchema,
|
|
611
|
+
config: {
|
|
612
|
+
...slackBaseConfigAdapter,
|
|
613
|
+
hasConfiguredState: ({ env }) => [
|
|
614
|
+
"SLACK_APP_TOKEN",
|
|
615
|
+
"SLACK_BOT_TOKEN",
|
|
616
|
+
"SLACK_USER_TOKEN"
|
|
617
|
+
].some((key) => typeof env?.[key] === "string" && env[key]?.trim().length > 0),
|
|
618
|
+
isConfigured: (account) => isSlackSetupAccountConfigured(account),
|
|
619
|
+
describeAccount: (account) => describeSlackSetupAccount(account)
|
|
620
|
+
},
|
|
621
|
+
setupContract: slackSetupContract
|
|
622
|
+
};
|
|
623
|
+
//#endregion
|
|
624
|
+
export { slackSetupContract as a, createSlackSetupWizardProxy as i, slackBaseConfigAdapter as n, SLACK_CHANNEL as o, createSlackSetupWizardBase as r, slackSetupPlugin as t };
|
|
@@ -8,10 +8,6 @@ const slackChannelConfigUiHints = {
|
|
|
8
8
|
label: "Slack",
|
|
9
9
|
help: "Slack channel provider configuration for bot/app tokens, streaming behavior, and DM policy controls. Keep token handling and thread behavior explicit to avoid noisy workspace interactions."
|
|
10
10
|
},
|
|
11
|
-
enterpriseOrgInstall: {
|
|
12
|
-
label: "Slack Enterprise Grid Org Install",
|
|
13
|
-
help: "Enable only for an Enterprise Grid org-wide bot installation. OpenClaw verifies the token with Slack auth.test at startup; DMs must be disabled or use dmPolicy=\"open\" with allowFrom=[\"*\"]."
|
|
14
|
-
},
|
|
15
11
|
postAs: {
|
|
16
12
|
label: "Slack Identity",
|
|
17
13
|
help: "Select \"bot\" (default) for the classic Slack app/bot identity or \"user\" to post as the authorizing human through a user token while the app carries event transport."
|
|
@@ -28,16 +24,16 @@ const slackChannelConfigUiHints = {
|
|
|
28
24
|
nativeCommands: true,
|
|
29
25
|
implicitMentions: true,
|
|
30
26
|
streaming: {
|
|
31
|
-
"": "Unified Slack stream preview mode: \"off\" | \"partial\" | \"block\" | \"progress\". Legacy boolean/streamMode keys are auto-mapped.",
|
|
32
|
-
mode: "Canonical Slack preview mode: \"off\" | \"partial\" | \"block\" | \"progress\".",
|
|
27
|
+
"": "Unified Slack stream preview mode: \"off\" | \"partial\" | \"block\" | \"progress\" (default). Legacy boolean/streamMode keys are auto-mapped.",
|
|
28
|
+
mode: "Canonical Slack preview mode: \"off\" | \"partial\" | \"block\" | \"progress\" (default).",
|
|
33
29
|
chunkMode: "Chunking mode for outbound Slack text delivery: \"length\" (default) or \"newline\".",
|
|
34
30
|
"block.enabled": "Enable chunked block-style Slack preview delivery when channels.slack.streaming.mode=\"block\".",
|
|
35
31
|
"block.coalesce": "Merge streamed Slack block replies before final delivery.",
|
|
36
32
|
nativeTransport: "Enable native Slack text streaming (chat.startStream/chat.appendStream/chat.stopStream) when channels.slack.streaming.mode is partial (default: true). Native streaming and Slack assistant thread status require a reply thread target; top-level DMs can still use draft post-and-edit preview streaming.",
|
|
37
33
|
"preview.toolProgress": "Show tool/progress activity in the live draft preview message (default: true). Set false to hide interim tool updates while the draft preview stays active.",
|
|
38
|
-
"preview.commandText": "Command/exec detail in preview tool-progress lines: \"
|
|
39
|
-
"progress.
|
|
40
|
-
"progress.nativeTaskCards": "
|
|
34
|
+
"preview.commandText": "Command/exec detail in preview tool-progress lines: \"status\" is the safe default; \"raw\" opts into command text.",
|
|
35
|
+
"progress.style": "Slack progress presentation: \"card\" (default) uses structured task/session cards; \"compact\" keeps one editable text draft that the final answer replaces in place when Slack can safely edit it.",
|
|
36
|
+
"progress.nativeTaskCards": "Slack native task-card progress updates when channels.slack.streaming.mode=\"progress\", progress.style=\"card\", and streaming.nativeTransport is enabled. Set false to fall back to the Block Kit progress card. Default: true."
|
|
41
37
|
},
|
|
42
38
|
progress: { labels: "openclaw" }
|
|
43
39
|
}),
|
|
@@ -99,7 +95,7 @@ const slackChannelConfigUiHints = {
|
|
|
99
95
|
},
|
|
100
96
|
execApprovals: {
|
|
101
97
|
label: "Slack Exec Approvals",
|
|
102
|
-
help: "Slack-native exec approval routing and approver authorization. When unset, OpenClaw auto-enables DM-first native approvals if approvers can be resolved for this
|
|
98
|
+
help: "Slack-native exec approval routing and approver authorization. When unset, OpenClaw auto-enables DM-first native approvals if approvers can be resolved for this Slack account."
|
|
103
99
|
},
|
|
104
100
|
presenceEvents: {
|
|
105
101
|
label: "Slack Presence Events",
|
|
@@ -109,10 +105,18 @@ const slackChannelConfigUiHints = {
|
|
|
109
105
|
label: "Slack Presence Event Mode",
|
|
110
106
|
help: "\"off\" disables polling; \"auto\" covers DMs, MPIMs, and recent threads with up to 8 observed people; \"on\" also covers larger threads and top-level channels."
|
|
111
107
|
},
|
|
108
|
+
"presenceEvents.prompt": {
|
|
109
|
+
label: "Slack Presence Event Prompt",
|
|
110
|
+
help: "Replace the default greeting guidance appended after presence facts. Use an empty string to omit event-specific guidance and let workspace instructions such as AGENTS.md govern behavior. Maximum: 20,000 characters."
|
|
111
|
+
},
|
|
112
112
|
"channels.*.presenceEvents.mode": {
|
|
113
113
|
label: "Slack Channel Presence Event Mode",
|
|
114
114
|
help: "Override presence events for one Slack channel. Use \"on\" to include large threads or top-level channel sessions."
|
|
115
115
|
},
|
|
116
|
+
"channels.*.presenceEvents.prompt": {
|
|
117
|
+
label: "Slack Channel Presence Event Prompt",
|
|
118
|
+
help: "Override the account-level presence-event prompt for one Slack channel. Maximum: 20,000 characters."
|
|
119
|
+
},
|
|
116
120
|
"execApprovals.enabled": {
|
|
117
121
|
label: "Slack Exec Approvals Enabled",
|
|
118
122
|
help: "Controls Slack native exec approvals for this account: unset or \"auto\" enables DM-first native approvals when approvers can be resolved, true forces native approvals on, and false disables them."
|
|
@@ -149,7 +153,11 @@ const slackChannelConfigUiHints = {
|
|
|
149
153
|
//#endregion
|
|
150
154
|
//#region extensions/slack/src/config-schema.ts
|
|
151
155
|
const SecretInputSchema = buildSecretInputSchema();
|
|
152
|
-
const
|
|
156
|
+
const SLACK_PRESENCE_EVENT_PROMPT_MAX_CHARS = 2e4;
|
|
157
|
+
const SlackStreamingProgressSchema = ChannelStreamingProgressSchema.extend({
|
|
158
|
+
style: z.enum(["card", "compact"]).optional(),
|
|
159
|
+
nativeTaskCards: z.boolean().optional()
|
|
160
|
+
}).strict();
|
|
153
161
|
const SlackStreamingConfigSchema = ChannelPreviewStreamingConfigSchema.extend({
|
|
154
162
|
nativeTransport: z.boolean().optional(),
|
|
155
163
|
progress: SlackStreamingProgressSchema.optional()
|
|
@@ -159,11 +167,14 @@ const SlackDmSchema = z.object({
|
|
|
159
167
|
groupEnabled: z.boolean().optional(),
|
|
160
168
|
groupChannels: z.array(z.union([z.string(), z.number()])).optional()
|
|
161
169
|
}).strict();
|
|
162
|
-
const SlackPresenceEventsSchema = z.object({
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
170
|
+
const SlackPresenceEventsSchema = z.object({
|
|
171
|
+
mode: z.enum([
|
|
172
|
+
"off",
|
|
173
|
+
"auto",
|
|
174
|
+
"on"
|
|
175
|
+
]).optional(),
|
|
176
|
+
prompt: z.string().max(SLACK_PRESENCE_EVENT_PROMPT_MAX_CHARS).optional()
|
|
177
|
+
}).strict();
|
|
167
178
|
const SlackChannelSchema = buildGroupEntrySchema({
|
|
168
179
|
ignoreOtherMentions: z.boolean().optional(),
|
|
169
180
|
replyToMode: ReplyToModeSchema.optional(),
|
|
@@ -199,7 +210,6 @@ const SlackAccountSchema = z.object({
|
|
|
199
210
|
"http",
|
|
200
211
|
"relay"
|
|
201
212
|
]).optional(),
|
|
202
|
-
enterpriseOrgInstall: z.boolean().optional(),
|
|
203
213
|
relay: SlackRelaySchema.optional(),
|
|
204
214
|
signingSecret: SecretInputSchema.optional(),
|
|
205
215
|
webhookPath: z.string().optional(),
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { a as parseSlackTarget } from "./target-parsing-BnMD2ZqZ.js";
|
|
2
|
+
import "./targets-Cx5W_n3W.js";
|
|
3
|
+
import { resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
|
|
4
|
+
//#region extensions/slack/src/account-reply-mode.ts
|
|
5
|
+
function normalizeSlackChatType(raw) {
|
|
6
|
+
const value = raw?.trim().toLowerCase();
|
|
7
|
+
if (!value) return;
|
|
8
|
+
if (value === "direct" || value === "dm") return "direct";
|
|
9
|
+
if (value === "group" || value === "channel") return value;
|
|
10
|
+
}
|
|
11
|
+
function resolveSlackReplyToMode(account, chatType) {
|
|
12
|
+
const normalized = normalizeSlackChatType(chatType ?? void 0);
|
|
13
|
+
if (normalized && account.replyToModeByChatType?.[normalized] !== void 0) return account.replyToModeByChatType[normalized] ?? "off";
|
|
14
|
+
return account.replyToMode ?? "off";
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region extensions/slack/src/conversation-binding-route.ts
|
|
18
|
+
const slackRouteBindingConfigCache = /* @__PURE__ */ new WeakMap();
|
|
19
|
+
function slackTargetDefaultKindForPeer(kind) {
|
|
20
|
+
return kind === "direct" ? "user" : "channel";
|
|
21
|
+
}
|
|
22
|
+
function slackTargetKindMatchesPeer(peerKind, targetKind) {
|
|
23
|
+
if (targetKind === "user") return peerKind === "direct";
|
|
24
|
+
return peerKind === "channel" || peerKind === "group";
|
|
25
|
+
}
|
|
26
|
+
function normalizeSlackRouteBindingPeer(peer) {
|
|
27
|
+
const rawId = peer.id.trim();
|
|
28
|
+
if (!rawId || rawId === "*") return peer;
|
|
29
|
+
const target = (() => {
|
|
30
|
+
try {
|
|
31
|
+
return parseSlackTarget(rawId, { defaultKind: slackTargetDefaultKindForPeer(peer.kind) });
|
|
32
|
+
} catch {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
})();
|
|
36
|
+
if (!target || !slackTargetKindMatchesPeer(peer.kind, target.kind)) return peer;
|
|
37
|
+
const normalizedId = target.teamId ? `team:${target.teamId}:${target.kind}:${target.id}` : target.id;
|
|
38
|
+
return normalizedId === peer.id ? peer : {
|
|
39
|
+
...peer,
|
|
40
|
+
id: normalizedId
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function normalizeSlackRouteBindingConfig(cfg) {
|
|
44
|
+
const bindings = cfg.bindings;
|
|
45
|
+
const cached = slackRouteBindingConfigCache.get(cfg);
|
|
46
|
+
if (cached && cached.bindingsRef === bindings) return cached.normalizedCfg;
|
|
47
|
+
if (!Array.isArray(bindings)) return cfg;
|
|
48
|
+
let changed = false;
|
|
49
|
+
const normalizedBindings = bindings.map((binding) => {
|
|
50
|
+
if (binding.type === "acp" || binding.match.channel.trim().toLowerCase() !== "slack") return binding;
|
|
51
|
+
const peer = binding.match.peer;
|
|
52
|
+
if (!peer) return binding;
|
|
53
|
+
const normalizedPeer = normalizeSlackRouteBindingPeer(peer);
|
|
54
|
+
if (normalizedPeer === peer) return binding;
|
|
55
|
+
changed = true;
|
|
56
|
+
return {
|
|
57
|
+
...binding,
|
|
58
|
+
match: {
|
|
59
|
+
...binding.match,
|
|
60
|
+
peer: normalizedPeer
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
const normalizedCfg = changed ? {
|
|
65
|
+
...cfg,
|
|
66
|
+
bindings: normalizedBindings
|
|
67
|
+
} : cfg;
|
|
68
|
+
slackRouteBindingConfigCache.set(cfg, {
|
|
69
|
+
bindingsRef: bindings,
|
|
70
|
+
normalizedCfg
|
|
71
|
+
});
|
|
72
|
+
return normalizedCfg;
|
|
73
|
+
}
|
|
74
|
+
function resolveSlackConversationBindingRoute(params) {
|
|
75
|
+
const boundThreadRoute = params.bindingsEnabled && params.runtimeBindingThreadId ? resolveRuntimeConversationBindingRoute({
|
|
76
|
+
route: params.route,
|
|
77
|
+
touchBinding: params.touchBinding,
|
|
78
|
+
conversation: {
|
|
79
|
+
channel: "slack",
|
|
80
|
+
accountId: params.accountId,
|
|
81
|
+
conversationId: params.runtimeBindingThreadId,
|
|
82
|
+
parentConversationId: params.baseConversationId
|
|
83
|
+
}
|
|
84
|
+
}) : null;
|
|
85
|
+
const runtimeRoute = !params.bindingsEnabled ? {
|
|
86
|
+
bindingOwnerAvailable: true,
|
|
87
|
+
route: params.route,
|
|
88
|
+
bindingRecord: null,
|
|
89
|
+
boundSessionKey: void 0
|
|
90
|
+
} : boundThreadRoute?.boundSessionKey || boundThreadRoute?.bindingRecord ? boundThreadRoute : resolveRuntimeConversationBindingRoute({
|
|
91
|
+
route: params.route,
|
|
92
|
+
touchBinding: params.touchBinding,
|
|
93
|
+
conversation: {
|
|
94
|
+
channel: "slack",
|
|
95
|
+
accountId: params.accountId,
|
|
96
|
+
conversationId: params.baseConversationId
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
const configuredRoute = params.bindingsEnabled && !runtimeRoute.boundSessionKey && !runtimeRoute.bindingRecord ? resolveConfiguredBindingRoute({
|
|
100
|
+
cfg: params.cfg,
|
|
101
|
+
route: params.route,
|
|
102
|
+
conversation: {
|
|
103
|
+
channel: "slack",
|
|
104
|
+
accountId: params.accountId,
|
|
105
|
+
conversationId: params.baseConversationId
|
|
106
|
+
}
|
|
107
|
+
}) : null;
|
|
108
|
+
return {
|
|
109
|
+
runtimeRoute,
|
|
110
|
+
configuredRoute,
|
|
111
|
+
route: runtimeRoute.boundSessionKey ? runtimeRoute.route : configuredRoute?.route ?? params.route
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
export { resolveSlackConversationBindingRoute as n, resolveSlackReplyToMode as r, normalizeSlackRouteBindingConfig as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-
|
|
3
|
-
import {
|
|
4
|
-
import "./targets-
|
|
2
|
+
import { i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-BlzxuYle.js";
|
|
3
|
+
import { a as parseSlackTarget } from "./target-parsing-BnMD2ZqZ.js";
|
|
4
|
+
import "./targets-Cx5W_n3W.js";
|
|
5
5
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
|
|
6
6
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
7
7
|
import { createResolvedDirectoryEntriesLister } from "openclaw/plugin-sdk/directory-config-runtime";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-
|
|
1
|
+
import { n as listSlackDirectoryGroupsFromConfig, r as listSlackDirectoryPeersFromConfig } from "./directory-config-BGYyuzWh.js";
|
|
2
2
|
export { listSlackDirectoryGroupsFromConfig, listSlackDirectoryPeersFromConfig };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { a as resolveSlackAccount } from "./accounts-
|
|
3
|
-
import {
|
|
2
|
+
import { a as resolveSlackAccount } from "./accounts-BlzxuYle.js";
|
|
3
|
+
import { i as createSlackLookupClient } from "./probe-BVA65leh.js";
|
|
4
|
+
import { t as collectSlackCursorPages } from "./cursor-pages-eX7p8Wwt.js";
|
|
4
5
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
6
|
//#region extensions/slack/src/directory-live.ts
|
|
6
7
|
var directory_live_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -67,18 +68,13 @@ async function listSlackDirectoryPeersLive(params) {
|
|
|
67
68
|
const client = createSlackDirectoryClient(params);
|
|
68
69
|
if (!client) return [];
|
|
69
70
|
const query = normalizeQuery(params.query);
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
do {
|
|
73
|
-
const res = await client.users.list({
|
|
71
|
+
const rows = (await collectSlackCursorPages({
|
|
72
|
+
fetchPage: (cursor) => client.users.list({
|
|
74
73
|
limit: 200,
|
|
75
74
|
cursor
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
cursor = next ? next : void 0;
|
|
80
|
-
} while (cursor);
|
|
81
|
-
const rows = members.filter((member) => {
|
|
75
|
+
}),
|
|
76
|
+
collectPageItems: (res) => Array.isArray(res.members) ? res.members : []
|
|
77
|
+
})).filter((member) => {
|
|
82
78
|
const candidates = [
|
|
83
79
|
member.profile?.display_name || member.profile?.real_name || member.real_name,
|
|
84
80
|
member.name,
|
|
@@ -94,20 +90,15 @@ async function listSlackDirectoryGroupsLive(params) {
|
|
|
94
90
|
const client = createSlackDirectoryClient(params);
|
|
95
91
|
if (!client) return [];
|
|
96
92
|
const query = normalizeQuery(params.query);
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
do {
|
|
100
|
-
const res = await client.conversations.list({
|
|
93
|
+
const rows = (await collectSlackCursorPages({
|
|
94
|
+
fetchPage: (cursor) => client.conversations.list({
|
|
101
95
|
types: "public_channel,private_channel",
|
|
102
96
|
exclude_archived: false,
|
|
103
97
|
limit: 1e3,
|
|
104
98
|
cursor
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
cursor = next ? next : void 0;
|
|
109
|
-
} while (cursor);
|
|
110
|
-
const rows = channels.filter((channel) => {
|
|
99
|
+
}),
|
|
100
|
+
collectPageItems: (res) => Array.isArray(res.channels) ? res.channels : []
|
|
101
|
+
})).filter((channel) => {
|
|
111
102
|
const name = normalizeOptionalLowercaseString(channel.name);
|
|
112
103
|
if (!query) return true;
|
|
113
104
|
return Boolean(name && name.includes(query));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { asObjectRecord, defineChannelAliasMigration, defineKeyMoveMigration, hasLegacyAccountStreamingAliases, normalizeChannelConfigEntries } from "openclaw/plugin-sdk/runtime-doctor";
|
|
1
|
+
import { n as resolveSlackStreamingMode, t as resolveSlackNativeStreaming } from "./streaming-compat-B-e0mqM0.js";
|
|
2
|
+
import { asObjectRecord, defineChannelAliasMigration, defineKeyMoveMigration, hasLegacyAccountStreamingAliases, normalizeChannelConfigEntries, stripRetiredChannelKeys } from "openclaw/plugin-sdk/runtime-doctor-migrations";
|
|
3
3
|
//#region extensions/slack/src/doctor-contract.ts
|
|
4
4
|
const streamingAliasMigration = defineChannelAliasMigration({
|
|
5
5
|
channelId: "slack",
|
|
@@ -35,6 +35,9 @@ function hasInteractiveRepliesCapability(value) {
|
|
|
35
35
|
const capabilitiesRecord = asObjectRecord(capabilities);
|
|
36
36
|
return Boolean(capabilitiesRecord && (Object.keys(capabilitiesRecord).length === 0 || Object.hasOwn(capabilitiesRecord, "interactiveReplies")));
|
|
37
37
|
}
|
|
38
|
+
function hasEnterpriseOrgInstall(value) {
|
|
39
|
+
return Object.hasOwn(asObjectRecord(value) ?? {}, "enterpriseOrgInstall");
|
|
40
|
+
}
|
|
38
41
|
function removeInteractiveRepliesCapability(params) {
|
|
39
42
|
const capabilities = params.entry.capabilities;
|
|
40
43
|
let nextCapabilities;
|
|
@@ -66,6 +69,23 @@ function removeInteractiveRepliesCapability(params) {
|
|
|
66
69
|
}
|
|
67
70
|
const legacyConfigRules = [
|
|
68
71
|
...streamingAliasMigration.legacyConfigRules,
|
|
72
|
+
{
|
|
73
|
+
path: [
|
|
74
|
+
"channels",
|
|
75
|
+
"slack",
|
|
76
|
+
"enterpriseOrgInstall"
|
|
77
|
+
],
|
|
78
|
+
message: "channels.slack.enterpriseOrgInstall is retired; Slack now detects org-wide installations automatically. Run \"openclaw doctor --fix\"."
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
path: [
|
|
82
|
+
"channels",
|
|
83
|
+
"slack",
|
|
84
|
+
"accounts"
|
|
85
|
+
],
|
|
86
|
+
message: "channels.slack.accounts.<id>.enterpriseOrgInstall is retired; Slack now detects org-wide installations automatically. Run \"openclaw doctor --fix\".",
|
|
87
|
+
match: (value) => hasLegacyAccountStreamingAliases(value, hasEnterpriseOrgInstall)
|
|
88
|
+
},
|
|
69
89
|
{
|
|
70
90
|
path: ["channels", "slack"],
|
|
71
91
|
message: "channels.slack.capabilities.interactiveReplies is retired; use typed presentation actions instead. Run \"openclaw doctor --fix\".",
|
|
@@ -144,9 +164,16 @@ function normalizeSlackEntry(params) {
|
|
|
144
164
|
}
|
|
145
165
|
function normalizeCompatibilityConfig({ cfg }) {
|
|
146
166
|
const changes = [];
|
|
167
|
+
const retired = stripRetiredChannelKeys({
|
|
168
|
+
cfg,
|
|
169
|
+
channelId: "slack",
|
|
170
|
+
keys: /* @__PURE__ */ new Set(["enterpriseOrgInstall"]),
|
|
171
|
+
scope: "root-and-accounts",
|
|
172
|
+
onRemove: ({ key, pathPrefix }) => changes.push(`Removed retired ${pathPrefix}.${key}; Slack detects org-wide installations automatically.`)
|
|
173
|
+
});
|
|
147
174
|
return normalizeChannelConfigEntries({
|
|
148
175
|
cfg: streamingAliasMigration.normalizeChannelConfig({
|
|
149
|
-
cfg,
|
|
176
|
+
cfg: retired.config,
|
|
150
177
|
changes
|
|
151
178
|
}).config,
|
|
152
179
|
channelId: "slack",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-
|
|
1
|
+
import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-BAy7-EUQ.js";
|
|
2
2
|
export { legacyConfigRules, normalizeCompatibilityConfig };
|