From 4cd3734c19185458ef6a5c42b75291f40e4e8a5a Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Wed, 11 Feb 2026 19:32:00 -0800 Subject: [PATCH 1/5] feat: add task_card block example Add example for the experimental task_card block type which displays a single task with status, output, and sources. Co-Authored-By: Claude --- block-kit/src/blocks/task_card.py | 43 ++++++++++++++++++++++++ block-kit/tests/blocks/test_task_card.py | 41 ++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 block-kit/src/blocks/task_card.py create mode 100644 block-kit/tests/blocks/test_task_card.py diff --git a/block-kit/src/blocks/task_card.py b/block-kit/src/blocks/task_card.py new file mode 100644 index 0000000..0042618 --- /dev/null +++ b/block-kit/src/blocks/task_card.py @@ -0,0 +1,43 @@ +from slack_sdk.models.blocks import RichTextBlock, TaskCardBlock +from slack_sdk.models.blocks.block_elements import ( + RichTextElementParts, + RichTextSectionElement, + UrlSourceElement, +) + + +def example01() -> TaskCardBlock: + """ + Displays a single task which represents a single action. + This is an experimental block type that requires a toggle to preview. + https://docs.slack.dev/reference/block-kit/blocks/task-card-block/ + + A task card with output and sources. + """ + block = TaskCardBlock( + task_id="task_1", + title="Fetching weather data", + status="pending", + output=RichTextBlock( + elements=[ + RichTextSectionElement( + elements=[ + RichTextElementParts.Text( + text="Found weather data for Chicago from 2 sources" + ) + ] + ) + ] + ), + sources=[ + UrlSourceElement( + url="https://weather.com/", + text="weather.com", + ), + UrlSourceElement( + url="https://www.accuweather.com/", + text="accuweather.com", + ), + ], + ) + return block diff --git a/block-kit/tests/blocks/test_task_card.py b/block-kit/tests/blocks/test_task_card.py new file mode 100644 index 0000000..802b924 --- /dev/null +++ b/block-kit/tests/blocks/test_task_card.py @@ -0,0 +1,41 @@ +import json + +from src.blocks import task_card + + +def test_example01(): + block = task_card.example01() + actual = block.to_dict() + expected = { + "type": "task_card", + "task_id": "task_1", + "title": "Fetching weather data", + "status": "pending", + "output": { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Found weather data for Chicago from 2 sources", + } + ], + } + ], + }, + "sources": [ + { + "type": "url", + "url": "https://weather.com/", + "text": "weather.com", + }, + { + "type": "url", + "url": "https://www.accuweather.com/", + "text": "accuweather.com", + }, + ], + } + assert json.dumps(actual, sort_keys=True) == json.dumps(expected, sort_keys=True) From deab4f1294e39489dfe5a71dc287f47b3e873263 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Wed, 11 Feb 2026 19:34:48 -0800 Subject: [PATCH 2/5] feat: add plan block example Add example for the experimental plan block type which displays a sequence of task cards representing multiple actions. Co-Authored-By: Claude --- block-kit/src/blocks/plan.py | 66 ++++++++++++++++++++++++ block-kit/tests/blocks/test_plan.py | 78 +++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 block-kit/src/blocks/plan.py create mode 100644 block-kit/tests/blocks/test_plan.py diff --git a/block-kit/src/blocks/plan.py b/block-kit/src/blocks/plan.py new file mode 100644 index 0000000..e3ab5d2 --- /dev/null +++ b/block-kit/src/blocks/plan.py @@ -0,0 +1,66 @@ +from slack_sdk.models.blocks import PlanBlock, RichTextBlock, TaskCardBlock +from slack_sdk.models.blocks.block_elements import ( + RichTextElementParts, + RichTextSectionElement, +) + + +def example01() -> PlanBlock: + """ + Displays a plan with multiple task cards representing a sequence of actions. + This is an experimental block type that requires a toggle to preview. + https://docs.slack.dev/reference/block-kit/blocks/plan-block/ + + A plan block with multiple task cards in various states. + """ + block = PlanBlock( + title="Thinking completed", + tasks=[ + TaskCardBlock( + task_id="call_001", + title="Fetched user profile information", + status="in_progress", + details=RichTextBlock( + block_id="viMWO", + elements=[ + RichTextSectionElement( + elements=[ + RichTextElementParts.Text(text="Searched database...") + ] + ) + ], + ), + output=RichTextBlock( + block_id="viMWO", + elements=[ + RichTextSectionElement( + elements=[ + RichTextElementParts.Text(text="Profile data loaded") + ] + ) + ], + ), + ), + TaskCardBlock( + task_id="call_002", + title="Checked user permissions", + status="pending", + ), + TaskCardBlock( + task_id="call_003", + title="Generated comprehensive user report", + status="complete", + output=RichTextBlock( + block_id="crsk", + elements=[ + RichTextSectionElement( + elements=[ + RichTextElementParts.Text(text="15 data points compiled") + ] + ) + ], + ), + ), + ], + ) + return block diff --git a/block-kit/tests/blocks/test_plan.py b/block-kit/tests/blocks/test_plan.py new file mode 100644 index 0000000..e806350 --- /dev/null +++ b/block-kit/tests/blocks/test_plan.py @@ -0,0 +1,78 @@ +import json + +from src.blocks import plan + + +def test_example01(): + block = plan.example01() + actual = block.to_dict() + expected = { + "type": "plan", + "title": "Thinking completed", + "tasks": [ + { + "type": "task_card", + "task_id": "call_001", + "title": "Fetched user profile information", + "status": "in_progress", + "details": { + "type": "rich_text", + "block_id": "viMWO", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Searched database...", + } + ], + } + ], + }, + "output": { + "type": "rich_text", + "block_id": "viMWO", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Profile data loaded", + } + ], + } + ], + }, + }, + { + "type": "task_card", + "task_id": "call_002", + "title": "Checked user permissions", + "status": "pending", + }, + { + "type": "task_card", + "task_id": "call_003", + "title": "Generated comprehensive user report", + "status": "complete", + "output": { + "type": "rich_text", + "block_id": "crsk", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "15 data points compiled", + } + ], + } + ], + }, + }, + ], + } + assert json.dumps(actual, sort_keys=True) == json.dumps(expected, sort_keys=True) From 79e47c052752f62b80b12662e6fb621701ba06a2 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Wed, 11 Feb 2026 19:39:19 -0800 Subject: [PATCH 3/5] docs: update descriptions and README Co-Authored-By: Claude --- block-kit/README.md | 2 ++ block-kit/src/blocks/plan.py | 3 +-- block-kit/src/blocks/task_card.py | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/block-kit/README.md b/block-kit/README.md index 5f7a51c..ddb3c0e 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -19,4 +19,6 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes - **[Markdown](https://docs.slack.dev/reference/block-kit/blocks/markdown-block)**: Displays formatted markdown. [Implementation](./src/blocks/markdown.py). - **[Rich text](https://docs.slack.dev/reference/block-kit/blocks/rich-text-block)**: Displays formatted, structured representation of text. [Implementation](./src/blocks/rich_text.py). - **[Section](https://docs.slack.dev/reference/block-kit/blocks/section-block)**: Displays text, possibly alongside elements. [Implementation](./src/blocks/section.py). +- **[Plan](https://docs.slack.dev/reference/block-kit/blocks/plan-block)**: Displays a collection of related tasks. [Implementation](./src/blocks/plan.py). +- **[Task card](https://docs.slack.dev/reference/block-kit/blocks/task-card-block)**: Displays a single task, representing a single action. [Implementation](./src/blocks/task_card.py). - **[Video](https://docs.slack.dev/reference/block-kit/blocks/video-block)**: Displays an embedded video player. [Implementation](./src/blocks/video.py). diff --git a/block-kit/src/blocks/plan.py b/block-kit/src/blocks/plan.py index e3ab5d2..799e283 100644 --- a/block-kit/src/blocks/plan.py +++ b/block-kit/src/blocks/plan.py @@ -7,8 +7,7 @@ def example01() -> PlanBlock: """ - Displays a plan with multiple task cards representing a sequence of actions. - This is an experimental block type that requires a toggle to preview. + Displays a collection of related tasks. https://docs.slack.dev/reference/block-kit/blocks/plan-block/ A plan block with multiple task cards in various states. diff --git a/block-kit/src/blocks/task_card.py b/block-kit/src/blocks/task_card.py index 0042618..9e2a0fb 100644 --- a/block-kit/src/blocks/task_card.py +++ b/block-kit/src/blocks/task_card.py @@ -8,8 +8,7 @@ def example01() -> TaskCardBlock: """ - Displays a single task which represents a single action. - This is an experimental block type that requires a toggle to preview. + Displays a single task, representing a single action. https://docs.slack.dev/reference/block-kit/blocks/task-card-block/ A task card with output and sources. From b9fd99da678ed91f62ffc86525eb58248f2997d3 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Wed, 11 Feb 2026 19:42:03 -0800 Subject: [PATCH 4/5] docs: alphabetize README block entries Co-Authored-By: Claude --- block-kit/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/block-kit/README.md b/block-kit/README.md index ddb3c0e..ee77ff0 100644 --- a/block-kit/README.md +++ b/block-kit/README.md @@ -9,16 +9,16 @@ Read the [docs](https://docs.slack.dev/block-kit/) to learn concepts behind thes ### Blocks - **[Actions](https://docs.slack.dev/reference/block-kit/blocks/actions-block)**: Holds multiple interactive elements. [Implementation](./src/blocks/actions.py). -- **[Context actions](https://docs.slack.dev/reference/block-kit/blocks/context-actions-block)**: Displays actions as contextual info, which can include both feedback buttons and icon buttons. [Implementation](./src/blocks/context_actions.py). - **[Context](https://docs.slack.dev/reference/block-kit/blocks/context-block)**: Provides contextual info, which can include both images and text. [Implementation](./src/blocks/context.py). +- **[Context actions](https://docs.slack.dev/reference/block-kit/blocks/context-actions-block)**: Displays actions as contextual info, which can include both feedback buttons and icon buttons. [Implementation](./src/blocks/context_actions.py). - **[Divider](https://docs.slack.dev/reference/block-kit/blocks/divider-block)**: Visually separates pieces of info inside of a message. [Implementation](./src/blocks/divider.py). - **[File](https://docs.slack.dev/reference/block-kit/blocks/file-block)**: Displays info about remote files. [Implementation](./src/blocks/file.py). - **[Header](https://docs.slack.dev/reference/block-kit/blocks/header-block)**: Displays a larger-sized text. [Implementation](./src/blocks/header.py). - **[Image](https://docs.slack.dev/reference/block-kit/blocks/image-block)**: Displays an image. [Implementation](./src/blocks/image.py). - **[Input](https://docs.slack.dev/reference/block-kit/blocks/input-block)**: Collects information from users via elements. [Implementation](./src/blocks/input.py). - **[Markdown](https://docs.slack.dev/reference/block-kit/blocks/markdown-block)**: Displays formatted markdown. [Implementation](./src/blocks/markdown.py). +- **[Plan](https://docs.slack.dev/reference/block-kit/blocks/plan-block)**: Displays a collection of related tasks. [Implementation](./src/blocks/plan.py). - **[Rich text](https://docs.slack.dev/reference/block-kit/blocks/rich-text-block)**: Displays formatted, structured representation of text. [Implementation](./src/blocks/rich_text.py). - **[Section](https://docs.slack.dev/reference/block-kit/blocks/section-block)**: Displays text, possibly alongside elements. [Implementation](./src/blocks/section.py). -- **[Plan](https://docs.slack.dev/reference/block-kit/blocks/plan-block)**: Displays a collection of related tasks. [Implementation](./src/blocks/plan.py). - **[Task card](https://docs.slack.dev/reference/block-kit/blocks/task-card-block)**: Displays a single task, representing a single action. [Implementation](./src/blocks/task_card.py). - **[Video](https://docs.slack.dev/reference/block-kit/blocks/video-block)**: Displays an embedded video player. [Implementation](./src/blocks/video.py). From d88af7405e5e45e8a2cd5706cae487978a76ddfa Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Wed, 11 Feb 2026 19:46:30 -0800 Subject: [PATCH 5/5] style: fix ruff formatting Co-Authored-By: Claude --- block-kit/src/blocks/plan.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/block-kit/src/blocks/plan.py b/block-kit/src/blocks/plan.py index 799e283..8872d9d 100644 --- a/block-kit/src/blocks/plan.py +++ b/block-kit/src/blocks/plan.py @@ -54,7 +54,9 @@ def example01() -> PlanBlock: elements=[ RichTextSectionElement( elements=[ - RichTextElementParts.Text(text="15 data points compiled") + RichTextElementParts.Text( + text="15 data points compiled" + ) ] ) ],