Skip to content

feat: add shimmer typing indicator to Slack channel skill#653

Open
takeru wants to merge 2 commits intoqwibitai:mainfrom
takeru:feat/slack-shimmer-typing-indicator
Open

feat: add shimmer typing indicator to Slack channel skill#653
takeru wants to merge 2 commits intoqwibitai:mainfrom
takeru:feat/slack-shimmer-typing-indicator

Conversation

@takeru
Copy link
Copy Markdown
Contributor

@takeru takeru commented Mar 2, 2026

Summary

  • Implement Slack's Agents & Assistants API (assistant.threads.setStatus) in the add-slack skill to show a shimmer/typing indicator while the bot processes messages
  • Track the latest user message timestamp per channel so the typing status can be set on the correct thread
  • Silently degrade when the assistant:write scope is missing or when used outside of DM threads

How it works

When the orchestrator calls setTyping(jid, true), the Slack channel now calls assistant.threads.setStatus with status: 'is thinking...' on the thread of the last user message. When called with false, it clears the status by sending an empty string. Bot messages are excluded from timestamp tracking so the indicator only activates in response to real user messages.

Slack-side configuration

To enable the shimmer typing indicator:

  1. Go to your Slack app settings at api.slack.com/apps
  2. Navigate to Features > Agents & AI Apps and enable it
  3. This grants the assistant:write scope needed for assistant.threads.setStatus
  4. Reinstall the app to your workspace if prompted

If the scope is not configured, the feature silently no-ops -- no errors will be thrown.

Files changed

  • .claude/skills/add-slack/add/src/channels/slack.ts -- Implementation
  • .claude/skills/add-slack/add/src/channels/slack.test.ts -- Tests (5 new test cases)

Test plan

  • Verify setTyping(jid, true) calls assistant.threads.setStatus with 'is thinking...' status
  • Verify setTyping(jid, false) clears the status with empty string
  • Verify no-op when no user message has been received for the channel
  • Verify API errors are silently caught
  • Verify bot messages do not populate the tracked timestamp

🤖 Generated with Claude Code

Use Slack's Agents & Assistants API (assistant.threads.setStatus) to show
a shimmer effect on the bot's name while processing. Requires enabling
"Agents & AI Apps" in the Slack app settings for the assistant:write scope.
Silently degrades when the scope is missing or in non-DM channels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0cf763427d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +218 to +219
const threadTs = this.lastUserMessageTs.get(jid);
if (!threadTs) return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep typing thread stable between start and stop

setTyping(false) always reads the current value from lastUserMessageTs, but that map is overwritten on every new user message in the channel. If another user message arrives while the agent is still processing, the false call will clear a different thread_ts than the one used for setTyping(true), leaving the original thread stuck showing “is thinking…”.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — setTyping(true) now pins the thread_ts into an activeTypingTs map, and setTyping(false) reads from there instead of lastUserMessageTs. This ensures the correct thread is cleared even if new messages arrive during processing.

Comment on lines +123 to +125
if (!isBotMessage) {
this.lastUserMessageTs.set(jid, msg.ts);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Track thread root timestamp instead of message timestamp

The handler stores msg.ts for typing status, but for replies inside an existing Slack thread the thread identifier is msg.thread_ts (with msg.ts being only the reply’s own timestamp). Using msg.ts causes assistant.threads.setStatus to target the wrong thread context for follow-up replies, so the shimmer indicator silently fails in threaded conversations.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — now using msg.thread_ts ?? msg.ts so threaded replies correctly target the thread root timestamp.

- Store the thread_ts used for setTyping(true) so that setTyping(false)
  always clears the correct thread, even if new messages arrive mid-processing.
- Use msg.thread_ts (thread root) instead of msg.ts for threaded replies,
  since assistant.threads.setStatus targets threads by their root timestamp.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@TomGranot
Copy link
Copy Markdown
Collaborator

Shimmer typing indicator for Slack — that's a nice touch for UX. Small and self-contained. @gavrielc should be quick to review.

@Andy-NanoClaw-AI Andy-NanoClaw-AI added PR: Feature New feature or enhancement Status: Needs Review Ready for maintainer review labels Mar 5, 2026
@Andy-NanoClaw-AI Andy-NanoClaw-AI added Status: Blocked Blocked by merge conflicts or dependencies Status: Needs Review Ready for maintainer review and removed Status: Needs Review Ready for maintainer review Status: Blocked Blocked by merge conflicts or dependencies labels Mar 14, 2026
vongohren added a commit to vongohren/nanoclaw that referenced this pull request Apr 6, 2026
Slack replies now go into threads instead of the channel root. When
SLACK_ALWAYS_REPLY_IN_THREAD=true, root messages start a new thread;
threaded replies respond in the same thread; DMs reply directly.

Also adds shimmer typing indicator via Slack's assistant.threads.setStatus
API (requires assistant:write scope, silent no-op without it).

Opts out of setup/update diagnostics telemetry.

Based on upstream PRs qwibitai#682 and qwibitai#653.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: Feature New feature or enhancement Status: Blocked Blocked by merge conflicts or dependencies

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants