- Remove trailing whitespace and normalize blank lines
- Unify string quotes and line breaks for long lines
- Sort imports alphabetically across modules
The slackify_markdown library (markdown-it) fails to convert **bold** when
the closing ** is immediately followed by non-space text (e.g. **Status:**OK).
This is a very common LLM output pattern that results in raw ** showing up
in Slack messages.
Add _fixup_mrkdwn() post-processor that:
- Converts leftover **bold** → *bold* (Slack mrkdwn)
- Converts leftover ## headers → *bold* (safety net)
- Fixes over-escaped & in bare URLs
- Protects code fences and inline code from being mangled
Co-authored-by: Cursor <cursoragent@cursor.com>
The slackify_markdown library misses several patterns that LLMs commonly
produce, causing raw Markdown symbols (**bold**, ##headers) to appear
in Slack messages.
Add _fixup_mrkdwn() post-processor that:
- Converts leftover **bold** patterns (e.g. **Status:**OK where closing
** is adjacent to non-space chars)
- Fixes & over-escaping in bare URLs
- Protects code blocks from false-positive fixups
Co-authored-by: Cursor <cursoragent@cursor.com>
Each Slack thread now gets its own conversation session instead of
sharing one session per channel. DM sessions are unchanged.
Added as a generic feature to also support if Feishu threads support
is added in the future.
_handle_message() in _on_socket_request() had no try/except. If it
throws (bus full, permission error, etc.), the exception propagates up
and crashes the Socket Mode event loop, causing missed messages.
Other channels like Telegram already have explicit error handlers.
Fixes#895
Use files_upload_v2 API to upload media attachments in Slack messages.
This enables the message tool's media parameter to work correctly
when sending images or other files through the Slack channel.
Requires files:write OAuth scope.
Slack has no native table support, so Markdown tables are passed
through verbatim by slackify-markdown. Pre-process tables into
readable key-value rows before converting to mrkdwn.
Assisted-by: Claude 4.6 Opus (Anthropic)
Replace the regex-based Markdown-to-Slack converter with the
slackify-markdown library, which uses a proper Markdown parser
(markdown-it-py, already a dependency) to correctly handle headings,
bold/italic, code blocks, links, bullet lists, and strikethrough.
The regex approach didn't handle headings (###), bullet lists (* ),
or code block protection, causing raw Markdown to leak into Slack
messages.
Net -40 lines.
Assisted-by: Claude 4.6 Opus (Anthropic)
Slack doesn't accept an empty string in the `text` parameter. However, Nanobot sometimes sends an empty response. This may need a change in the bot's logic as well; still, it should also be handled by the channel. I suggest changing the default message to '<empty_response_from_the_bot>' when the content is empty, so the user will know that the bot was trying to respond with an empty message.