Installs into .claude/skills of the current project.
Are you the author of Channels?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/danielfebrero-channels)
---
name: channels
description: >-
When you are woken by an [inbound] message or reaction from an outside
messaging channel, or the user asks to connect or disconnect one.
---
# Channels
Never ask the user to paste a token, API key, or password into the chat, and never write one into a file: that would persist it in the transcript or somewhere you can read it back. To collect any credential, send a SendToUser of type secret-request (connector + field + a clear label). The user types it into a masked field and the value goes straight to the secret store; you only learn that it was provided, never the value. You do not need the credential to check status; never cat the connection file expecting one.
Every conversation on a channel has an address shaped like platform:chat (e.g. slack:C0123ABCD:1712345678.000100 for a Slack channel thread, slack:U0123ABCD for a Slack person). An address names one chat; that is all routing needs. On Slack, a channel thread is addressed slack:<channel id>:<thread ts>, the channel id and the thread's top-level message ts joined by a colon (e.g. slack:C0123ABCD:1712345678.000100). A bare slack:C… or slack:G… channel id posts a new top-level message in that channel, which the whole channel sees and which needs the bot to have been added to the channel; use it only when someone asks for a new post there or a routine says to post to the channel, and answer a message in its own thread otherwise. A person (slack:U…, which opens a DM with them) or an existing DM (slack:D…) is addressed bare, which posts at the DM's root; a thread inside a DM is addressed slack:<DM id>:<thread ts>. An [inbound] wake or a routine fire hands you the exact address; when you compose one yourself, build it from the channel id and the (ts: …) of the message you are answering.
INBOUND: when someone messages you on a connected channel, you are woken with a hidden message that opens with the cue [inbound] and names the source address and sender. That is a real person reaching out on that platform, not the user typing in this app. Reply to them on that same channel by calling SendToUser with a channel target set to their address; if you instead omit the channel, your message goes to this in-app Grok Bot chat (the user at their desk), not to them. In a Slack session (your current session's id starts with slack:) there is no in-app chat: a send that omits the channel is posted in that Slack conversation.
REACTIONS: the same [inbound] cue also wakes you when someone reacts to one of your messages (e.g. ❤️). A reaction is a lightweight acknowledgement, not a question: you usually do not need to reply, only act on it if it is useful.
OUTBOUND: SendToUser takes an optional channel target. Set it to an address (e.g. the slack:C…:<thread ts> address of the thread you are answering, slack:U… for a person, or a bare slack:C… to start a new top-level post in a channel you have been added to) to deliver there; leave it off and the message lands in this in-app chat exactly as before, or, in a Slack session, in that Slack conversation. You choose where each message goes, so be deliberate: by default answer an inbound message on the channel it came from, in its thread.
Pace a channel reply exactly like the in-app chat: open with a quick one-line acknowledgement, then send each progress beat and the final result as its own SendToUser as it happens. Each SendToUser is delivered to the platform immediately as a separate message, so the person sees you respond in real time; never hold it all back for one long message at the end, the worst way to reply on a channel. Keep every one of those messages extra concise: a channel is a messaging app, so write the short, to-the-point messages a person texts, terser than your in-app replies. Lead with the answer, prefer one or two short sentences, and skip long multi-paragraph messages, exhaustive detail, and unprompted caveats; expand only if they ask.
A channel only carries text and attachments, never the in-app widget or cursor-agent cards (those render only in this app), so degrade them to text when the conversation is on a channel: ask a multiple-choice question as plain text with the options as a numbered list and tell them to reply with their choice; reference a Cursor cloud agent as a plain https://cursor.com/agents/<bcId> link instead of a card; and for an attachment pass either a local file:// path or an https URL: the file is uploaded to the platform so they receive the real image or file, never a path.