@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.
- package/dist/{account-inspect-CN2hBsim.js → account-inspect-C3sePHWa.js} +3 -3
- package/dist/account-inspect-api.js +1 -1
- package/dist/{action-runtime-BoSeX09X.js → action-runtime-DftQWpI4.js} +84 -66
- package/dist/action-runtime.runtime-rHI3UAh4.js +2 -0
- package/dist/{actions-XdQyjG_p.js → actions-CFkvEv1d.js} +198 -54
- package/dist/api.js +14 -14
- package/dist/{approval-handler.runtime-DxXfGX_Z.js → approval-handler.runtime-BeILKdw4.js} +47 -25
- package/dist/{channel-C_vnTgxo.js → channel-CmOuxbOD.js} +76 -133
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-type-j-2lalcC.js → channel-type-BWt2CRaI.js} +2 -2
- package/dist/{channel.setup-aal8tokM.js → channel.setup-D5z1ReaT.js} +29 -23
- package/dist/{config-schema-CN3XZRX5.js → config-schema-JDx_f9Zb.js} +26 -17
- package/dist/{cursor-pages-eX7p8Wwt.js → cursor-pages-ByFwo-Py.js} +7 -1
- package/dist/{directory-config-DqfQ42OV.js → directory-config-Bmw4ykSy.js} +4 -3
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-lC6X_Ru-.js → directory-live-BuBPHmju.js} +3 -8
- package/dist/{doctor-contract-BAy7-EUQ.js → doctor-contract-BNjw9bxb.js} +5 -4
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{message-tool-api-CWosHSi5.js → message-tool-api-uNEfQYGY.js} +19 -2
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-DrNCGneD.js → monitor-DI07pfJl.js} +3 -3
- package/dist/{outbound-adapter-DkT2vUE9.js → outbound-adapter-B5QyTRpJ.js} +96 -91
- package/dist/{pipeline.runtime-CRRng_Nw.js → pipeline.runtime-BdIwZgm4.js} +596 -920
- package/dist/{policy-BoP6t88v.js → policy-Bh5TOqII.js} +7 -4
- package/dist/{probe-4_aHtVT3.js → probe-Biy--yhL.js} +251 -12
- package/dist/{provider-D4nDgxCh.js → provider-DoaUvAM4.js} +5621 -4944
- package/dist/{relay-source-CEmze11m.js → relay-source-D4uecp68.js} +6 -4
- package/dist/{replies-D9XMM_S0.js → replies-DENuTcPO.js} +21 -16
- package/dist/reply-blocks-PRkhyAN7.js +790 -0
- package/dist/{resolve-channels-DSamDgVs.js → resolve-channels-DQGV2VrE.js} +6 -10
- package/dist/{resolve-users-CIzwbaJR.js → resolve-users-DRGt_Q4I.js} +5 -4
- package/dist/runtime-api.js +10 -10
- package/dist/{scopes-BBrUzpBH.js → scopes-CZzeGdWV.js} +1 -1
- package/dist/{send-DtjEnlLh.js → send-DElUcgIs.js} +32 -24
- package/dist/send-results-eeOu_HYm.js +23 -0
- package/dist/{send.runtime-DQeNKa2J.js → send.runtime-C8D6cKGm.js} +1 -1
- package/dist/{group-policy-CU1tEGpS.js → session-status-BynwcZSO.js} +284 -1013
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-CsBCM4rP.js → setup-surface-B1_gpGBl.js} +5 -5
- package/dist/{shared-D9GeeR9K.js → shared-CNQsWJT7.js} +7 -5
- package/dist/{slash-dispatch.runtime-Chr3YHnT.js → slash-dispatch.runtime-DhsXavSY.js} +2 -2
- package/dist/{target-parsing-BnMD2ZqZ.js → target-parsing-PbxGDbr9.js} +11 -6
- package/dist/{targets-Cx5W_n3W.js → targets-7FexXJ62.js} +1 -1
- package/dist/{thread-ts-DUGhaYKq.js → thread-ts-CukseRVL.js} +5 -1
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/accept.js +54 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/charset.js +10 -34
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/encoding.js +9 -30
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/language.js +15 -36
- package/node_modules/@slack/bolt/node_modules/negotiator/lib/mediaType.js +16 -134
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/LICENSE +22 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/README.md +71 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.d.ts +46 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.js +176 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/node_modules/content-type/package.json +52 -0
- package/node_modules/@slack/bolt/node_modules/negotiator/package.json +16 -10
- package/node_modules/typebox/build/format/email.mjs +1 -1
- package/node_modules/typebox/build/format/idna/idn-hostname.mjs +19 -1
- package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
- package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
- package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
- package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
- package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
- package/node_modules/typebox/build/system/memory/create.mjs +3 -4
- package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
- package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
- package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
- package/node_modules/typebox/build/system/memory/update.mjs +3 -2
- package/node_modules/typebox/package.json +1 -1
- package/node_modules/undici/lib/dispatcher/balanced-pool.js +4 -2
- package/node_modules/undici/lib/dispatcher/client-h1.js +12 -4
- package/node_modules/undici/lib/dispatcher/client-h2.js +70 -14
- package/node_modules/undici/lib/dispatcher/client.js +6 -2
- package/node_modules/undici/lib/handler/cache-handler.js +21 -5
- package/node_modules/undici/lib/handler/retry-handler.js +42 -7
- package/node_modules/undici/lib/interceptor/cache.js +20 -1
- package/node_modules/undici/lib/interceptor/decompress.js +146 -14
- package/node_modules/undici/lib/interceptor/dump.js +10 -23
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +245 -150
- package/node_modules/undici/lib/web/websocket/connection.js +1 -1
- package/node_modules/undici/lib/web/websocket/permessage-deflate.js +5 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -10
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/interceptors.d.ts +2 -0
- package/openclaw.plugin.json +17 -9
- package/package.json +6 -6
- package/skills/_vendor/slack-skills-plugin.LICENSE +21 -0
- package/skills/_vendor/slack-skills-plugin.json +31 -0
- package/skills/block-kit/SKILL.md +37 -0
- package/skills/block-kit/references/official-block-kit.md +257 -0
- package/skills/block-kit/references/official-common-patterns.md +385 -0
- package/skills/slack/SKILL.md +1 -1
- package/dist/action-runtime.runtime-Dpa16J87.js +0 -2
- package/dist/conversation-binding-route-DFVLUdYF.js +0 -115
- package/dist/slack-client-kind-hSfjXyUM.js +0 -94
- package/node_modules/@slack/bolt/node_modules/negotiator/HISTORY.md +0 -114
package/openclaw.plugin.json
CHANGED
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"type": "boolean"
|
|
52
52
|
},
|
|
53
53
|
"dmPolicy": {
|
|
54
|
+
"default": "pairing",
|
|
54
55
|
"type": "string",
|
|
55
56
|
"enum": [
|
|
56
57
|
"pairing",
|
|
@@ -367,6 +368,9 @@
|
|
|
367
368
|
}
|
|
368
369
|
]
|
|
369
370
|
},
|
|
371
|
+
"joinIntro": {
|
|
372
|
+
"type": "boolean"
|
|
373
|
+
},
|
|
370
374
|
"postAs": {
|
|
371
375
|
"default": "bot",
|
|
372
376
|
"type": "string",
|
|
@@ -1779,6 +1783,9 @@
|
|
|
1779
1783
|
}
|
|
1780
1784
|
]
|
|
1781
1785
|
},
|
|
1786
|
+
"joinIntro": {
|
|
1787
|
+
"type": "boolean"
|
|
1788
|
+
},
|
|
1782
1789
|
"postAs": {
|
|
1783
1790
|
"type": "string",
|
|
1784
1791
|
"enum": [
|
|
@@ -2393,7 +2400,6 @@
|
|
|
2393
2400
|
]
|
|
2394
2401
|
},
|
|
2395
2402
|
"userTokenReadOnly": {
|
|
2396
|
-
"default": true,
|
|
2397
2403
|
"type": "boolean"
|
|
2398
2404
|
},
|
|
2399
2405
|
"allowBots": {
|
|
@@ -2835,9 +2841,6 @@
|
|
|
2835
2841
|
"type": "string"
|
|
2836
2842
|
}
|
|
2837
2843
|
},
|
|
2838
|
-
"required": [
|
|
2839
|
-
"userTokenReadOnly"
|
|
2840
|
-
],
|
|
2841
2844
|
"additionalProperties": false
|
|
2842
2845
|
}
|
|
2843
2846
|
},
|
|
@@ -2846,6 +2849,7 @@
|
|
|
2846
2849
|
}
|
|
2847
2850
|
},
|
|
2848
2851
|
"required": [
|
|
2852
|
+
"dmPolicy",
|
|
2849
2853
|
"groupPolicy",
|
|
2850
2854
|
"postAs",
|
|
2851
2855
|
"mode",
|
|
@@ -2935,7 +2939,7 @@
|
|
|
2935
2939
|
},
|
|
2936
2940
|
"streaming.nativeTransport": {
|
|
2937
2941
|
"label": "Slack Native Streaming",
|
|
2938
|
-
"help": "Enable native Slack text streaming (chat.startStream/chat.appendStream/chat.stopStream) when channels.slack.streaming.mode is partial (default: true). Native streaming and Slack
|
|
2942
|
+
"help": "Enable native Slack text streaming (chat.startStream/chat.appendStream/chat.stopStream) when channels.slack.streaming.mode is partial (default: true). Native streaming and Slack session status require a reply thread target; top-level DMs can still use draft post-and-edit preview streaming."
|
|
2939
2943
|
},
|
|
2940
2944
|
"streaming.preview.toolProgress": {
|
|
2941
2945
|
"label": "Slack Draft Tool Progress",
|
|
@@ -2947,7 +2951,7 @@
|
|
|
2947
2951
|
},
|
|
2948
2952
|
"streaming.progress.style": {
|
|
2949
2953
|
"label": "Slack Progress Style",
|
|
2950
|
-
"help": "Slack progress presentation: \"card\"
|
|
2954
|
+
"help": "Slack progress presentation: \"card\" uses structured task/session cards; \"compact\" keeps a temporary editable text draft. The final response is posted as a new message, then the draft is deleted after confirmed delivery. Defaults to \"compact\" when progress.toolProgress is explicitly false, otherwise \"card\"."
|
|
2951
2955
|
},
|
|
2952
2956
|
"streaming.progress.nativeTaskCards": {
|
|
2953
2957
|
"label": "Slack Native Progress Task Cards",
|
|
@@ -2971,12 +2975,16 @@
|
|
|
2971
2975
|
},
|
|
2972
2976
|
"streaming.progress.toolProgress": {
|
|
2973
2977
|
"label": "Slack Progress Tool Lines",
|
|
2974
|
-
"help": "Show
|
|
2978
|
+
"help": "Show individual tool activity in progress drafts (default: false). Quiet drafts retain plans, approval requests, failures, and authored progress text."
|
|
2975
2979
|
},
|
|
2976
2980
|
"streaming.progress.commandText": {
|
|
2977
2981
|
"label": "Slack Progress Command Text",
|
|
2978
2982
|
"help": "Command/exec detail in progress draft lines: \"status\" is the safe default; \"raw\" opts into command text."
|
|
2979
2983
|
},
|
|
2984
|
+
"joinIntro": {
|
|
2985
|
+
"label": "Slack Channel Join Introduction",
|
|
2986
|
+
"help": "Post one brief, room-specific introduction when the bot joins an allowed Slack channel (default: true). Account settings override the channel-wide setting."
|
|
2987
|
+
},
|
|
2980
2988
|
"allowBots": {
|
|
2981
2989
|
"label": "Slack Allow Bot Messages",
|
|
2982
2990
|
"help": "Allow bot-authored messages to trigger Slack replies (default: false)."
|
|
@@ -3035,7 +3043,7 @@
|
|
|
3035
3043
|
},
|
|
3036
3044
|
"execApprovals": {
|
|
3037
3045
|
"label": "Slack Exec Approvals",
|
|
3038
|
-
"help": "Slack-native exec approval routing and approver authorization.
|
|
3046
|
+
"help": "Slack-native exec approval routing and approver authorization. Set enabled to \"auto\" or true to enable DM-first native approvals when approvers can be resolved for this Slack account; unset or false disables them."
|
|
3039
3047
|
},
|
|
3040
3048
|
"presenceEvents": {
|
|
3041
3049
|
"label": "Slack Presence Events",
|
|
@@ -3059,7 +3067,7 @@
|
|
|
3059
3067
|
},
|
|
3060
3068
|
"execApprovals.enabled": {
|
|
3061
3069
|
"label": "Slack Exec Approvals Enabled",
|
|
3062
|
-
"help": "Controls Slack native exec approvals for this account:
|
|
3070
|
+
"help": "Controls Slack native exec approvals for this account: \"auto\" or true enables DM-first native approvals when approvers can be resolved; unset or false disables them."
|
|
3063
3071
|
},
|
|
3064
3072
|
"execApprovals.approvers": {
|
|
3065
3073
|
"label": "Slack Exec Approval Approvers",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/slack",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.2",
|
|
4
4
|
"description": "OpenClaw Slack channel plugin for channels, DMs, commands, and app events.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
"@slack/types": "3.0.0",
|
|
14
14
|
"@slack/web-api": "8.0.0",
|
|
15
15
|
"get-east-asian-width": "1.6.0",
|
|
16
|
-
"typebox": "1.3.
|
|
17
|
-
"undici": "7.29.
|
|
16
|
+
"typebox": "1.3.18",
|
|
17
|
+
"undici": "7.29.1",
|
|
18
18
|
"ws": "8.21.3",
|
|
19
19
|
"zod": "4.4.3"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"openclaw": ">=2026.9.
|
|
22
|
+
"openclaw": ">=2026.9.2"
|
|
23
23
|
},
|
|
24
24
|
"peerDependenciesMeta": {
|
|
25
25
|
"openclaw": {
|
|
@@ -151,10 +151,10 @@
|
|
|
151
151
|
"allowInvalidConfigRecovery": true
|
|
152
152
|
},
|
|
153
153
|
"compat": {
|
|
154
|
-
"pluginApi": ">=2026.9.
|
|
154
|
+
"pluginApi": ">=2026.9.2"
|
|
155
155
|
},
|
|
156
156
|
"build": {
|
|
157
|
-
"openclawVersion": "2026.9.
|
|
157
|
+
"openclawVersion": "2026.9.2",
|
|
158
158
|
"bundledDist": false
|
|
159
159
|
},
|
|
160
160
|
"release": {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020- Slack Technologies, LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"source": {
|
|
4
|
+
"repository": "https://github.com/slackapi/slack-skills-plugin.git",
|
|
5
|
+
"revision": "f3f404205cbbfa18fabc79cc9d06fb444efff075",
|
|
6
|
+
"version": "1.3.0",
|
|
7
|
+
"license": "MIT"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"source": "LICENSE",
|
|
12
|
+
"destination": "skills/_vendor/slack-skills-plugin.LICENSE",
|
|
13
|
+
"sourceSha256": "ccbd532eabd9c4a87884b19caa6738bd6541e047460a736aca3bf1ac4fd91300",
|
|
14
|
+
"vendoredSha256": "ccbd532eabd9c4a87884b19caa6738bd6541e047460a736aca3bf1ac4fd91300"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"source": "skills/block-kit/SKILL.md",
|
|
18
|
+
"destination": "skills/block-kit/references/official-block-kit.md",
|
|
19
|
+
"sourceSha256": "255f2ef5be5a6b5363b57931d5549227f375fe02fc2be7ce98226b33ed18f097",
|
|
20
|
+
"vendoredSha256": "5b5c792b21d6d9bc95d46a9f11e9b274beb45c3fd3b540b9deeec070ea1a57d2",
|
|
21
|
+
"adaptation": "Replaces unavailable Slack CLI, Slack API skill, and named tool handoffs with capability-gated OpenClaw guidance; corrects the relocated common-pattern reference; URL-encodes validation form values."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"source": "skills/block-kit/references/common-patterns.md",
|
|
25
|
+
"destination": "skills/block-kit/references/official-common-patterns.md",
|
|
26
|
+
"sourceSha256": "b372af9aa4367fbfc6561f6629db720595e0552711d83c7208fdba512443c05e",
|
|
27
|
+
"vendoredSha256": "b106cdeaf9a76dee386f489e37f709a3e56610c26e18246066a7ec540c90ca55",
|
|
28
|
+
"adaptation": "Formatted with the repository's Markdown formatter; content and examples are unchanged."
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: block-kit
|
|
3
|
+
description: "Use proactively for structured or interactive Slack replies, and when asked to author or validate native Slack Block Kit JSON."
|
|
4
|
+
metadata: { "openclaw": { "emoji": "🧱", "requires": { "config": ["channels.slack"] } } }
|
|
5
|
+
allowed-tools: ["message"]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Slack Block Kit
|
|
9
|
+
|
|
10
|
+
Make useful Slack replies feel native. When structure or one-click follow-up improves the outcome, send a rich message without waiting for the user to ask for Block Kit.
|
|
11
|
+
|
|
12
|
+
## Choose the surface
|
|
13
|
+
|
|
14
|
+
Use a `presentation` when the reply has at least one of these shapes:
|
|
15
|
+
|
|
16
|
+
- a decision, confirmation, or next action that belongs on buttons or a select
|
|
17
|
+
- a status, comparison, report, or plan that scans better as titled sections, a table, or a chart
|
|
18
|
+
- important context that should be visually separated from the primary result
|
|
19
|
+
|
|
20
|
+
Use plain text for short answers and casual conversation where structure adds no value.
|
|
21
|
+
|
|
22
|
+
## Send the result
|
|
23
|
+
|
|
24
|
+
For a reply in Slack, call the `message` tool with `action: "send"` and a portable `presentation`. The Slack plugin renders it as native Block Kit. Use the exact schema exposed by the current tool; supported block types can include `text`, `context`, `divider`, `buttons`, `select`, `chart`, and `table`.
|
|
25
|
+
|
|
26
|
+
- Put the outcome first. Keep titles, labels, and context concise.
|
|
27
|
+
- Give interactive controls real follow-up semantics. Use typed `callback` actions for conversational choices and `url` for an external destination. Do not use generic `command` actions for Slack controls; Slack renders them as text fallback rather than clickable controls.
|
|
28
|
+
- Include a useful `message` fallback that preserves the meaning without the rich layout.
|
|
29
|
+
- After the visible send succeeds, do not repeat the same content in the final response.
|
|
30
|
+
|
|
31
|
+
A control is complete only when its value is self-contained enough for the next agent turn to understand and act on. When an interaction returns, acknowledge the choice visibly and continue the requested workflow.
|
|
32
|
+
|
|
33
|
+
## Native Block Kit authoring
|
|
34
|
+
|
|
35
|
+
When the user is building a Slack app or explicitly requests raw Block Kit JSON, read [the adapted official Block Kit guide](references/official-block-kit.md) in full. For common message, modal, and App Home layouts, also read [the official patterns](references/official-common-patterns.md).
|
|
36
|
+
|
|
37
|
+
Follow the adapted guide's live-documentation and `blocks.validate` workflow for native JSON. Do not pass native Slack blocks to OpenClaw's `presentation` field; the plugin owns that conversion.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: block-kit
|
|
3
|
+
description: 'Use when a developer wants to build or validate Block Kit layouts for Slack messages, modals, or Home tabs: message layouts, modals/forms/dialogs, Home tab interfaces, interactive buttons or menus, or modifying existing Block Kit JSON. Also trigger on any Slack UI component (sections, actions, inputs, headers, alerts, tables, carousels), the words "blocks" or "Block Kit Builder", a request to preview rendered blocks, or pasted JSON like "type": "section". Validates via the blocks.validate API method.'
|
|
4
|
+
argument-hint: "[message | modal | home-tab]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Block Kit
|
|
8
|
+
|
|
9
|
+
Help the developer build a rich Block Kit layout. If `$0` is provided, it specifies the target surface (`message`, `modal`, or `home-tab`).
|
|
10
|
+
|
|
11
|
+
This skill walks through surface selection, layout planning, JSON generation, and validation. Block types, elements, and fields come from the live docs (see **Source of Truth** below) — discover them and read each component's schema there, never from memory.
|
|
12
|
+
|
|
13
|
+
> **OpenClaw adaptation:** This copy keeps Slack's authoring guidance while using capabilities available in the current agent session. Native Block Kit JSON is developer output; ordinary Slack replies use OpenClaw's portable `presentation` field.
|
|
14
|
+
|
|
15
|
+
> **Common Block Kit mistakes (and why):** A few errors recur often enough to flag up front. Most others are caught by `blocks.validate` in Step 5, so lean on validation rather than memorizing rules.
|
|
16
|
+
>
|
|
17
|
+
> - **`"type": "text"` is not a thing.** Text is a composition object: `{ "type": "plain_text", "text": "..." }` or `{ "type": "mrkdwn", "text": "..." }`.
|
|
18
|
+
> - **`markdown` is a _block_ type, not a text type.** A `markdown` block holds standard markdown; text objects inside other blocks use `mrkdwn` (see **mrkdwn vs. the `markdown` block** in Step 4). Slack's `mrkdwn` is `*bold*` / `_italic_` / `~strike~`, not `**bold**`.
|
|
19
|
+
> - **Messages need a top-level `text` fallback.** `blocks.validate` won't flag a missing one, but notifications and screen readers display it instead of the blocks — so summarize what the layout conveys rather than leaving it empty.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Source of Truth: the Live Docs
|
|
24
|
+
|
|
25
|
+
Every block, element, and composition object is documented on `docs.slack.dev`. Append `.md` to any reference URL to fetch it as markdown with an available web-documentation capability (no auth required).
|
|
26
|
+
|
|
27
|
+
- **Master index**: the authoritative list of every block, block element, and composition object, each linking to its own page: `https://docs.slack.dev/reference/block-kit.md`. Fetch it with an available web-documentation capability to confirm a type exists and to get the link to its page.
|
|
28
|
+
- **Per-component pages** carry the full field schema (a fields table with required/optional flags and constraints, plus JSON examples):
|
|
29
|
+
- Blocks: `https://docs.slack.dev/reference/block-kit/blocks/<slug>-block.md`
|
|
30
|
+
- Block elements: `https://docs.slack.dev/reference/block-kit/block-elements/<slug>-element.md`
|
|
31
|
+
- Composition objects: `https://docs.slack.dev/reference/block-kit/composition-objects/<slug>.md`
|
|
32
|
+
- **The slug is not always the type name.** For example `datepicker` maps to `date-picker-element.md`, and every `*_select` menu (`static_select`, `users_select`, `multi_channels_select`, and so on) is documented on `select-menu-element.md`. When unsure of a slug, follow the link from the master index rather than building the URL by hand.
|
|
33
|
+
- **Surface payload structure** lives in the surface guides: messages at `https://docs.slack.dev/messaging/formatting-message-text.md`, modals at `https://docs.slack.dev/surfaces/modals.md`, and Home tabs at `https://docs.slack.dev/surfaces/app-home.md`.
|
|
34
|
+
|
|
35
|
+
Never use a block type, element, or field you have not seen on a live page.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Fast Path (for clear, specific requests)
|
|
40
|
+
|
|
41
|
+
If the developer's request is specific enough to determine both the target surface and the desired layout, collapse Steps 1-4 into a single pass:
|
|
42
|
+
|
|
43
|
+
1. Determine the surface from `$0` or context
|
|
44
|
+
2. Fetch only the doc pages for the blocks and elements mentioned
|
|
45
|
+
3. Generate the JSON directly
|
|
46
|
+
4. Proceed to Step 5 (validation)
|
|
47
|
+
|
|
48
|
+
**Fast-path indicators** (skip the full workflow):
|
|
49
|
+
|
|
50
|
+
- Developer provides existing JSON to modify → use Modification Mode instead
|
|
51
|
+
- Developer names specific block types: "add an actions block with two buttons"
|
|
52
|
+
- Developer describes a well-known pattern: "approval message", "feedback form", "settings modal"
|
|
53
|
+
- Developer provides a complete description in one message with enough detail to build
|
|
54
|
+
|
|
55
|
+
**Full-workflow indicators** (use Steps 1-7):
|
|
56
|
+
|
|
57
|
+
- Vague requests: "make something cool", "build a dashboard"
|
|
58
|
+
- Exploratory: "what can Block Kit do?", "show me my options"
|
|
59
|
+
- Complex layouts: 10+ blocks, nested modals, conditional logic
|
|
60
|
+
- Developer asks for help deciding what to build
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Modification Mode
|
|
65
|
+
|
|
66
|
+
If the developer provides existing Block Kit JSON (pasted inline, in a file, or referenced from code), enter Modification Mode instead of the full creation workflow:
|
|
67
|
+
|
|
68
|
+
1. **Parse the existing structure:**
|
|
69
|
+
- List each block by index, type, and a short description of its content
|
|
70
|
+
- Infer the surface: `"type": "modal"` = modal, `"type": "home"` = home tab, bare `blocks` array = message
|
|
71
|
+
|
|
72
|
+
2. **Ask what changes they want:**
|
|
73
|
+
- Add blocks (where in the sequence?)
|
|
74
|
+
- Remove blocks (which ones?)
|
|
75
|
+
- Modify blocks (which block, what change?)
|
|
76
|
+
- Reorder blocks
|
|
77
|
+
|
|
78
|
+
3. **Apply changes while preserving:**
|
|
79
|
+
- All existing `block_id` values (these are referenced in app interaction handlers)
|
|
80
|
+
- All existing `action_id` values (these map to event listeners)
|
|
81
|
+
- Existing styles, text content, and structure for unchanged blocks
|
|
82
|
+
|
|
83
|
+
4. **Validate the modified JSON**: proceed to Step 5 (validation)
|
|
84
|
+
|
|
85
|
+
**Detection:** If the developer's message contains a JSON array starting with `[{"type":` or a view object with `"blocks":`, enter Modification Mode automatically. If they say "edit", "update", "modify", or "change" in reference to existing blocks, ask them to provide the current JSON.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Step 1: Determine the Target Surface
|
|
90
|
+
|
|
91
|
+
If `$0` is provided and matches one of `message`, `modal`, or `home-tab`, use it directly.
|
|
92
|
+
|
|
93
|
+
Otherwise, ask the developer:
|
|
94
|
+
|
|
95
|
+
- **Message**: Conversational content posted to a channel or DM. Max 50 blocks.
|
|
96
|
+
- **Modal**: A dialog or form opened by a user action. Max 100 blocks.
|
|
97
|
+
- **Home tab**: A persistent, per-user dashboard in the App Home. Max 100 blocks.
|
|
98
|
+
|
|
99
|
+
Once the surface is determined, use the correct payload structure for it:
|
|
100
|
+
|
|
101
|
+
- **Message**: a `{ "text": "Fallback text", "blocks": [...] }` object posted via `chat.postMessage` (and friends). The `text` field is the notification/accessibility fallback. For message text formatting (mrkdwn, mentions, dates), see `https://docs.slack.dev/messaging/formatting-message-text.md`.
|
|
102
|
+
- **Modal**: a view object (`{ "type": "modal", "title": ..., "blocks": [...] }`). For the full view object structure, lifecycle, and the rule that `submit` is required when the view contains any `input` block, see `https://docs.slack.dev/surfaces/modals.md`.
|
|
103
|
+
- **Home tab**: a view object (`{ "type": "home", "blocks": [...] }`) published via `views.publish`. For structure and behavior, see `https://docs.slack.dev/surfaces/app-home.md`.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Step 2: Understand What to Build
|
|
108
|
+
|
|
109
|
+
Ask the developer to describe what they want their layout to look like or accomplish.
|
|
110
|
+
|
|
111
|
+
If they need inspiration, suggest examples — several map directly onto a ready-made template in `official-common-patterns.md` (named in parentheses), which you can start from in Step 3:
|
|
112
|
+
|
|
113
|
+
- "A feedback form with a text input and a category selector" (Simple Form Modal)
|
|
114
|
+
- "A notification message with an alert banner, description, and Approve/Reject buttons" (Notification Alert / Approval Message)
|
|
115
|
+
- "A dashboard home tab with a welcome header, key metrics in fields, and quick-action buttons" (Dashboard Home Tab)
|
|
116
|
+
- "A settings modal with dropdowns, checkboxes, and a time picker" (Settings Modal with Multiple Input Types)
|
|
117
|
+
- "A table of sprint tasks with status and points" (Data Table)
|
|
118
|
+
|
|
119
|
+
Get enough detail to plan the layout before generating any JSON.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Step 3: Plan the Block Layout
|
|
124
|
+
|
|
125
|
+
Based on the developer's description:
|
|
126
|
+
|
|
127
|
+
1. **Fetch only what you need** from the live docs:
|
|
128
|
+
- Fetch the master index (`https://docs.slack.dev/reference/block-kit.md`) with an available web-documentation capability to confirm the block and element types you plan to use exist and to grab links to their pages.
|
|
129
|
+
- Check `official-common-patterns.md` (the one local reference file) if the request matches a common pattern; start from the template instead of building from scratch.
|
|
130
|
+
- Defer reading individual component pages until Step 4, when you build each block's fields.
|
|
131
|
+
2. Propose a numbered block outline. For example:
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
1. header: "Weekly Report"
|
|
135
|
+
2. section: Summary text with a datepicker accessory
|
|
136
|
+
3. divider
|
|
137
|
+
4. section: Status fields (Name, Role, Team)
|
|
138
|
+
5. actions: "Approve" button (primary) and "Reject" button (danger)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
3. Present the outline to the developer and ask for approval or changes before generating JSON.
|
|
142
|
+
|
|
143
|
+
**Surface constraints to check:**
|
|
144
|
+
|
|
145
|
+
- Block count limit: 50 for messages, 100 for modals/home tabs
|
|
146
|
+
- Modal-specific: if using `input` blocks, the modal payload must include a `submit` field
|
|
147
|
+
- Table: only one `table` block per message
|
|
148
|
+
- Surface compatibility (whether a block is valid on the chosen surface) and element compatibility (whether an element is allowed inside a given block) are not always spelled out on a component's doc page. Build the layout from the docs, and let `blocks.validate` in Step 5 confirm it. It is the authoritative check.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Step 4: Generate the Block Kit JSON
|
|
153
|
+
|
|
154
|
+
Once the layout is approved, build each block from its live doc page, fetching each page's fields table (required vs optional, constraints) and JSON example with an available web-documentation capability. The URL patterns are in **Source of Truth** above; the one slug to remember is that every `*_select` menu (`static_select`, `users_select`, `multi_channels_select`, …) lives on `select-menu-element.md`. Fetch pages as you need them and reuse what you have already fetched — don't re-fetch the same page for every block of the same type. Then build the payload block-by-block and wrap it in the surface structure from Step 1.
|
|
155
|
+
|
|
156
|
+
**Guidelines:**
|
|
157
|
+
|
|
158
|
+
- Use descriptive `action_id` values (e.g., `"approve_report_btn"` not `"action_1"`) — they identify the element in your interaction handlers
|
|
159
|
+
- Include `block_id` values where the developer will need them for interaction handling
|
|
160
|
+
- For modals, include `title`, `submit`, `close`, and `callback_id`; for home tabs, the `type: "home"` wrapper
|
|
161
|
+
- Use `mrkdwn` text for rich formatting, `plain_text` where required (headers, labels, modal title)
|
|
162
|
+
|
|
163
|
+
**mrkdwn vs. the `markdown` block:** `section` and `context` blocks format text with Slack's `mrkdwn` (`*bold*`, `_italic_`, `~strike~`, `` `code` ``) — use these for short, interactive layouts. The separate `markdown` block (Messages only) renders _standard_ markdown (`**bold**`, headings, tables, numbered lists) and is meant for AI/LLM-generated or long-form content that already exists in standard markdown. Reach for it when the developer has such content or needs those features in the message body; there is a cumulative 12,000-character limit across all `markdown` blocks in one message.
|
|
164
|
+
|
|
165
|
+
**Accessibility** is easy to skip and hard to retrofit, so build it in now:
|
|
166
|
+
|
|
167
|
+
- Give images descriptive `alt_text` (what the image shows, not just "image"), and make sure image-heavy layouts also carry the key information as text
|
|
168
|
+
- Summarize the layout in the message's `text` fallback (notifications and screen readers show it instead of the blocks)
|
|
169
|
+
- Use `header` blocks for logical section headings — they convey document structure to assistive tech
|
|
170
|
+
|
|
171
|
+
Present the complete payload to the developer in the Step 1 surface structure.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Step 5: Validate
|
|
176
|
+
|
|
177
|
+
**Always validate.** `blocks.validate` is a public Web API method, so no auth token is required.
|
|
178
|
+
|
|
179
|
+
The authoritative reference for this method (its parameters, auth requirements, and response/error shape) is the live doc. Fetch it before relying on any detail here: `https://docs.slack.dev/reference/methods/blocks.validate.md`. It documents the accepted parameters (`blocks` for a message's blocks array, `view` for a modal/home-tab view, `message` for a full message payload; send exactly one) and the response shape.
|
|
180
|
+
|
|
181
|
+
### 5a. Build the validation request
|
|
182
|
+
|
|
183
|
+
Use an available HTTP capability to POST to `https://slack.com/api/blocks.validate`. The API uses form-urlencoded encoding, so pass the JSON directly as the parameter value. If the current session has no HTTP capability, deliver the payload with a clear note that live validation remains pending.
|
|
184
|
+
|
|
185
|
+
**For messages**, send the `blocks` array as a form-encoded parameter:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
curl -s -X POST 'https://slack.com/api/blocks.validate' \
|
|
189
|
+
--data-urlencode 'blocks=[ ... the blocks array ... ]'
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**For modals and home tabs**, send the complete view object in the `view` field:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
curl -s -X POST 'https://slack.com/api/blocks.validate' \
|
|
196
|
+
--data-urlencode 'view={ "type": "modal", "title": ..., "blocks": [...] }'
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 5b. Handle the response
|
|
200
|
+
|
|
201
|
+
**Success:**
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{ "ok": true }
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Tell the developer their blocks are valid.
|
|
208
|
+
|
|
209
|
+
**Failure:**
|
|
210
|
+
|
|
211
|
+
```json
|
|
212
|
+
{
|
|
213
|
+
"ok": false,
|
|
214
|
+
"error": "invalid_blocks",
|
|
215
|
+
"errors": [
|
|
216
|
+
{
|
|
217
|
+
"code": "missing_field",
|
|
218
|
+
"message": "missing required field: type",
|
|
219
|
+
"field": "type",
|
|
220
|
+
"pointer": "/0"
|
|
221
|
+
}
|
|
222
|
+
]
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
When validation fails:
|
|
227
|
+
|
|
228
|
+
1. Read each error. `pointer` is a JSON pointer to the offending node (e.g., `/0` = first block, `/2/elements/1` = second element of the third block, `/0/text/type` = the `type` field of the first block's text object). `message` describes the problem, and `constraint` (when present) names the rule that failed and its expected values.
|
|
229
|
+
2. Fix the JSON. For the authoritative meaning of an error code and the field requirements behind it, consult the live method doc (`https://docs.slack.dev/reference/methods/blocks.validate.md`) and the relevant block/element/composition-object page you fetched in Steps 3-4.
|
|
230
|
+
3. Re-validate. Repeat until `"ok": true`.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Step 6: Deliver the Final Output
|
|
235
|
+
|
|
236
|
+
Present the validated payload, then help the developer put it to use.
|
|
237
|
+
|
|
238
|
+
### Send it
|
|
239
|
+
|
|
240
|
+
Building the native payload is this skill's job. Return it for the developer's Slack app integration. Do not pass native Slack blocks to OpenClaw's `presentation` field; translate the result into the portable presentation schema when the user instead wants the current OpenClaw agent to post it.
|
|
241
|
+
|
|
242
|
+
### Preview it
|
|
243
|
+
|
|
244
|
+
Help the developer view their layout with the **Block Kit Builder**. Offer `https://app.slack.com/block-kit-builder` so they can paste the JSON in and tweak visually. Builder needs an object (`{ "blocks": [...] }` or a full view object), not a bare array.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Step 7: Iterate
|
|
249
|
+
|
|
250
|
+
Ask whether the developer wants to add, modify, remove, or reorder blocks, or build a layout for a different surface. If they want to change the layout you just produced, re-enter **Modification Mode** (it preserves their `block_id`/`action_id` values); for a fresh layout, loop back to Step 3.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Notes
|
|
255
|
+
|
|
256
|
+
- **Scope:** this skill owns building and validating native Block Kit payloads for a developer. OpenClaw conversation delivery uses portable `presentation` instead.
|
|
257
|
+
- **`blocks.validate` needs no auth** — it's a public method. Always validate before finalizing when the current session has an HTTP capability (Step 5).
|