feat: unify Slack + Telegram into dual-transport agents (inbox-buddy, hn-monitor, joke-bot, spotify-releases)
Merged
KH
4mo ago+1244+1244+0123456789012345678901234567890123456789-1484-1484-0123456789012345678901234567890123456789
What
Completes the dual-transport unification across the personal-use agents (piloted on hn-monitor in #88/#89). Each agent that had a separate *-telegram sibling is now one agent that runs over Slack, Telegram, or both — gated by the new workforce#252 optional integrations feature.
| agent | before | after |
|---|---|---|
| inbox-buddy | inbox-buddy + inbox-buddy-telegram | unified, dispatch by event type, reply-on-origin |
| joke-bot | joke-bot + joke-bot-telegram | unified; Slack @mention / relay DM / Telegram message + cron fan-out |
| spotify-releases | spotify-releases + spotify-releases-telegram | unified; cron delivers to each configured transport |
| hn-monitor | already unified, both providers always connected | migrated to enabledByInput gating |
workforce#252 optional integrations (the enabling mechanism)
- Each transport integration is
optional: true+enabledByInput: '<INPUT>'. The provider connection + trigger register only when that input is non-empty, so a single-transport deploy never wires up the other provider. - Gates: inbox-buddy/joke-bot
slack→SLACK_CHANNEL,telegram→TELEGRAM_CHAT; spotifyslack→SLACK_USER,telegram→TELEGRAM_CHAT. - These fields landed in persona-kit 4.1.12 (4.1.3 silently drops them) → bumped
@agentworkforce/persona-kit+agentworkforceCLI to^4.1.12.
Behavior notes
- inbox-buddy / joke-bot dispatch by
event.typeand reply on the origin transport (a Slack question is answered in Slack, never mirrored). joke-bot keeps its Slack-onlycapabilities.conversationalrouting + relay-inbox path; its daily "joke of the day" fans out to every configured transport. - spotify-releases adopts the Telegram sibling's robust checkpoint (notified-set dedup, per-transport delivery confirmation, advance only on full success); memory tags unified to
spotify-releases:{last-check,notified}. - Gate-on-id semantics: providing the channel/chat/user id both enables and restricts that transport. At least one must be set.
Tests
- Repointed the Telegram tests at the unified agents; added dual-transport dispatch / trigger-registration / optional-integration invariants, joke-bot Slack-mention + wrong-channel fail-closed + cron fan-out-to-both, and spotify Slack-DM coverage.
- Full suite 166/166 green;
tsc --noEmitclean; all four personas compile via the CLI with the gating fields emitted. - Deleted
inbox-buddy-telegram/,joke-bot-telegram/,spotify-releases-telegram/.
Follow-up (separate repo)
The creating-cloud-persona skill (in the skills repo) documents PersonaIntegrationConfig but not optional/enabledByInput or the dual-transport pattern — being updated separately.
🤖 Generated with Claude Code