process.title contains non-ASCII charactersf1fb7bf: feat: add thinking steps types
Added types for Thinking Steps features:
PlanBlock and TaskCard for displaying task progress in messagesMarkdownTextChunk, PlanUpdateChunk, TaskUpdateChunk for streamingUrlSourceElements for displaying sources within task cardsRelated PRs:
await client.chat.postMessage({
channel: CHANNEL_ID,
text: "Task progress update",
blocks: [
{
type: "plan",
plan_id: "plan-123",
title: "My Task",
tasks: [
{
type: "task_card",
task_id: "task-124",
title: "Task 1",
status: "complete",
},
{
type: "task_card",
task_id: "task-125",
title: "Task 2",
status: "pending",
},
],
},
],
});
https://github.com/user-attachments/assets/1a6478c2-37aa-48c2-84e9-69375b20177e
https://github.com/user-attachments/assets/984f84e5-c0e0-47ef-a1c2-994ac51a25ba
Now, you can display a mixture of structured content called "chunks":
Available in:
chat.startStream, chat.appendStream, and chat.stopStreamconst stream = new ChatStreamer(...);, stream.append(...)$ slack create
# → AI Agent App
# → Bolt for JavaScript
# Bolt for Python
1fbce32: feat: add thinking steps support to streaming methods
chat.appendStream, chat.startStream, and chat.stopStream now accept a chunks parameter for streaming structured content including markdown text, plan updates, and task updates.
Related PRs:
const stream = new ChatStreamer(client, client.logger, {
channel: CHANNEL_ID,
thread_ts: threadTs,
});
await stream.append({
chunks: [
{
type: "markdown_text",
text: "**Hello!** I am starting to process your request...\n\n",
},
],
});
await stream.append({
chunks: [
{
type: "plan_update",
title: "Processing tasks...",
},
{
type: "task_update",
id: "task-1",
title: "Fetching data from API",
status: "complete",
output: "Successfully retrieved 42 records",
},
],
});
await stream.stop({
chunks: [
{
type: "markdown_text",
text: "\n\n---\n\n✅ **All tasks completed successfully!**\n",
},
],
});
0abdc91: feat(cli-hooks): add default app and manifest watch config
This package now provides default watch configurations for automatic file watching during slack run. The CLI will restart your app server when source files change and reinstall your app when the manifest changes.
Requirements: These features require Slack CLI v3.12.0+ with file watching support.
The following watch settings are provided automatically when using this package:
{
"config": {
"watch": {
"app": {
"filter-regex": "\\.js$",
"paths": ["."]
},
"manifest": {
"paths": ["manifest.json"]
}
}
}
}
Note: Manifest watching requires a local manifest source in your .slack/config.json file. Remote manifests will not be updated on file changes.
{
"manifest": {
"source": "local"
}
}
You can override these defaults in your .slack/hooks.json file to reduce the paths searched or change the file patterns. Read Watch Configurations for more options.
TypeScript developers should run tsc --watch in a separate terminal during development. This compiles .ts files to .js on changes, and the default watch configuration will detect changes to the compiled dist/*.js files and restart the app server. This approach works best with the default settings.
8962739: fix(cli-hooks): stop app process if the start hook exits
Fixes a CLI issue where daemon app processes were spawned if the CLI was exited without being interrupted.
9318ec9: build(cli-test): document the compatible version of slack cli with each release
The minimum supported Slack CLI version is now documented in the README instead of being encoded in the package version using build metadata (e.g. +cli.2.32.2). Build metadata is stripped by npm during publish, causing version conflicts with previously published versions and breaking the automated release workflow.
const list = await app.client.slackLists.create({
name: 'Test List - SlackLists API',
description_blocks: [
{
type: 'rich_text',
elements: [
{
type: 'rich_text_section',
elements: [
{
type: 'text',
text: 'List to keep track of tasks!',
},
],
},
],
},
],
schema: [
{
key: 'task_name',
name: 'Task Name',
type: 'text',
is_primary_column: true,
},
{
key: 'due_date',
name: 'Due Date',
type: 'date',
},
{
key: 'status',
name: 'Status',
type: 'select',
options: {
choices: [
{ value: 'not_started', label: 'Not Started', color: 'red' },
{ value: 'in_progress', label: 'In Progress', color: 'yellow' },
{ value: 'completed', label: 'Completed', color: 'green' },
],
},
},
{
key: 'assignee',
name: 'Assignee',
type: 'user',
},
],
});
console.log('List created:', list);
const listId = list.list_id;
// extract column IDs from the response (map key -> id)
const keyToId = {};
if (list.list_metadata?.schema) {
for (const col of list.list_metadata.schema) {
keyToId[col.key] = col.id;
}
}
const taskNameColId = keyToId['task_name'];
console.log('Column IDs:', keyToId);
const response = await app.client.slackLists.access.set({
list_id: listId,
access_level: 'write',
user_ids: ['U09G4FG3TRN'],
});
console.log('Access set:', response);
const createItemResponse = await app.client.slackLists.items.create({
list_id: listId,
initial_fields: [
{
column_id: taskNameColId,
rich_text: [
{
type: 'rich_text',
elements: [
{
type: 'rich_text_section',
elements: [
{
type: 'text',
text: 'CLI app unlink command',
},
],
},
],
},
],
},
],
});
console.log('Item created:', createItemResponse);
const itemId = createItemResponse.id;
if (itemId) {
await app.client.slackLists.items.info({
list_id: listId,
id: itemId,
include_is_subscribed: true,
});
console.log('Item info retrieved');
await app.client.slackLists.items.update({
list_id: listId,
cells: [
{
row_id: itemId,
column_id: taskNameColId,
checkbox: true,
},
],
});
console.log('Item updated');
}
const listItemsResponse = await app.client.slackLists.items.list({
list_id: listId,
limit: 50,
});
console.log('Items listed:', listItemsResponse);
const downloadStartResponse = await app.client.slackLists.download.start({
list_id: listId,
include_archived: false,
});
console.log('Download started:', downloadStartResponse);
const jobId = downloadStartResponse.job_id;
if (jobId) {
await app.client.slackLists.download.get({
list_id: listId,
job_id: jobId,
});
console.log('Download status retrieved');
}
if (itemId) {
await app.client.slackLists.items.delete({
list_id: listId,
id: itemId,
});
console.log('Item deleted');
}
await app.client.slackLists.items.deleteMultiple({
list_id: listId,
ids: ['item1', 'item2'],
});
console.log('Multiple items deleted');
await app.client.slackLists.access.delete({
list_id: listId,
user_ids: ['U09G4FG3TRN'],
});
console.log('Access removed');
</details>
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/types@2.19.0...@slack/web-api@7.13.0 Milestone: https://github.com/slackapi/node-slack-sdk/milestone/159 npm Release: https://www.npmjs.com/package/@slack/web-api/v/7.13.0
feat(types): add underline to rich text section block element in #2414 - Thanks @zimeg! feat(types): add table block in #2426 - Thanks @zimeg! feat(types): update work object types in #2431 - Thanks @vegeris!
docs: link to streaming methods and context actions block reference in #2429 - Thanks @zimeg!
docs(types): remove note of maximum length for raw_text in #2440 - Thanks @zimeg!
chore(types): release @slack/types@2.19.0 in #2441 - Thanks @mwbrooks!
Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/types@2.18.0...@slack/types@2.19.0 Milestone: https://github.com/slackapi/node-slack-sdk/milestone/158?closed=1 npm Release: https://www.npmjs.com/package/@slack/types/v/2.19.0
👾 Enhancements
🧰 Maintenance
📚 Changelog https://docs.slack.dev/changelog/2025/10/22/work-objects/
Package: https://www.npmjs.com/package/@slack/web-api@7.12.0 Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/web-api@7.11.0...@slack/web-api@7.12.0 Milestone: https://github.com/slackapi/node-slack-sdk/milestone/156?closed=1
👾 Enhancements
🧰 Maintenance
📚 Changelog https://docs.slack.dev/changelog/2025/10/22/work-objects/
Package: https://www.npmjs.com/package/@slack/types/v/2.18.0 Full Changelog: https://github.com/slackapi/node-slack-sdk/compare/@slack/types@2.17.0...@slack/types@2.18.0 Milestone: https://github.com/slackapi/node-slack-sdk/milestone/157?closed=1