From telegram-topics
Set up the Telegram Topics channel — save the bot token, configure the supergroup chat ID, set topic names, or get the launch recipe for a secondary same-project instance. Use when the user pastes a bot token, asks to configure Telegram Topics, wants to check channel status, or needs to run a second Claude session in the same directory with its own topic.
How this skill is triggered — by the user, by Claude, or both
Slash command
/telegram-topics:configureThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Manages bot token, supergroup chat ID, and per-project topic names.
Manages bot token, supergroup chat ID, and per-project topic names.
State lives in ~/.claude/channels/telegram-topics/.
Arguments passed: $ARGUMENTS
Read state files and show a complete picture:
Token — check ~/.claude/channels/telegram-topics/.env for
CLAUDE_TELEGRAM_TOPICS_BOT_TOKEN. Show set/not-set; if set, show first
10 chars masked (123456789:...).
Chat ID — read ~/.claude/channels/telegram-topics/access.json for
chatId. Show set/not-set.
Topics — read ~/.claude/channels/telegram-topics/topics.json. List
project paths and their topic names (these are what the daemon has actually
created in Telegram).
Labels — read ~/.claude/channels/telegram-topics/labels.json. List
any user-configured label overrides. A label set here but not yet reflected
in topics.json means the rename is pending a session restart.
Access — read access.json. Show DM policy, allowed senders count.
Daemon — check ~/.claude/channels/telegram-topics/daemon.pid. If
present, check if process is alive via kill -0 <pid>.
What next — guide based on state. Pairing is required: default
dmPolicy is pairing, and the gate drops every message from a sender
who isn't in allowFrom. Until the user pairs, nothing reaches Claude.
/telegram-topics:configure <token> with the token from BotFather."/telegram-topics:configure chat <id> with your supergroup's chat ID (negative number)."allowFrom empty → full remaining flow:
--dangerously-load-development-channels plugin:telegram-topics@wilfoa-plugins./telegram-topics:pair <code> to add your Telegram user to the allowlist./telegram-topics:access policy allowlist to close the pairing window.allowFrom non-empty) but dmPolicy still pairing → "Lock down with /telegram-topics:access policy allowlist."--dangerously-load-development-channels plugin:telegram-topics@wilfoa-plugins."<token> — save bot tokenIf $ARGUMENTS looks like a bot token (digits, colon, alphanumeric string):
mkdir -p ~/.claude/channels/telegram-topics.env if present; update/add the CLAUDE_TELEGRAM_TOPICS_BOT_TOKEN= line.chmod 600 ~/.claude/channels/telegram-topics/.env./reload-plugins."clear — remove tokenDelete the CLAUDE_TELEGRAM_TOPICS_BOT_TOKEN= line from .env.
chat <chat_id> — set supergroup chat ID~/.claude/channels/telegram-topics/access.json (create default if missing).<chat_id> is auto, tell the user:
"Send any message in the supergroup. The daemon will detect the chat ID on next startup.
For now, you'll need to find the chat ID manually. Send a message in the group,
then use @userinfobot or check the bot's getUpdates for the chat.id value."<chat_id> is a number (possibly negative), set chatId to that string in access.json.instance [<name>] — list or plan a secondary session in the same projectAuto-suffix is the default behavior: the first bare-cwd session gets the primary topic, the second is auto-assigned ${cwd}#2, etc. This dispatch is only useful when you want a stable, human-chosen name (TELEGRAM_TOPICS_INSTANCE=exp) instead of an integer. It does not persist anything — the env var is a per-shell concept.
$ARGUMENTS. Parse off the leading instance prefix; treat the remainder as <name>.topics.json and list entries whose key starts with ${cwd}#. Group them:
^[1-9]\d*$): show suffix and topicId.#N with topicId.topics.json.<name> as a placeholder, noting the env var is only needed for named instances.<name> is given, validate: lowercase alphanumerics + dashes/underscores, 1–20 chars, and must NOT match ^[1-9]\d*$ (pure integers are reserved for auto-suffix). Reject anything else.If you just need a second session, just launch Claude Code normally in the same directory — you'll automatically get a
(#2)topic. This command is for when you want a stable named instance instead:TELEGRAM_TOPICS_INSTANCE=<name> claude --dangerously-load-development-channels plugin:telegram-topics@wilfoa-pluginsRegisters as
<baseLabel> (<name>)under<cwd>#<name>. Named instances don't consume integer slots — your other sessions keep their auto-assigned numbers.To remove the named topic later:
/telegram-topics:project remove <cwd>#<name>.
topic "<name>" [--instance <inst>] — rename the topic (live, no restart needed)The rename goes through the shim's rename_topic MCP tool, which targets this
session's OWN registered topic. That matters for auto-suffixed sessions: if the
daemon auto-suffixed this shim to #2, a rename with no --instance must target
${cwd}#2 — not the primary ${cwd} topic that a different session holds. Using
the MCP tool puts the shim (which knows its effective projectPath) in charge of
that decision, instead of the skill guessing from ${cwd}. The shim also
persists the preferred label to labels.json for future sessions.
Parse $ARGUMENTS:
topic "My Project" or topic proj).--instance <inst>. Values:
1 → the bare cwd (primary slot).2, 3, … → an integer auto-suffix slot ${cwd}#<n>.foo, exp, …) → a named instance ${cwd}#<name>.Steps:
rename_topic MCP tool (tool name looks like mcp__telegram-topics__rename_topic — use whichever variant Claude Code surfaces):
name: the new name (string).instance: the string passed to --instance, or omit the arg if no flag was given.label also saved to labels.json; on failure (Telegram error) the label is saved anyway so the preference applies on the next session.Notes:
labels.json write from the skill. The MCP tool handles persistence. Writing labels.json from the skill separately would race with the shim and create duplicate entries.bun "${CLAUDE_PLUGIN_ROOT}/rename-topic.ts" "/abs/path/to/project" "New Name"
This path is strictly for admin/offline use — the MCP tool is the right default.-1001234567890). Store as string..env once at boot. Token changes need a restart. Say so after saving.npx claudepluginhub wilfoa/claude-plugins --plugin telegram-topicsCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.