feat(agent): resume parked runs from inbound Slack events
GI
2mo ago+5214+5214+0123456789012345678901234567890123456789-205-205-012345678901234567890123456789
Opened automatically when feat/builder-creates-channel was pushed.
The title is written from the diff and rewritten as you push, because this is squashed onto main and the title becomes the commit subject and the changelog line. Retitle it yourself and it is yours — the automation stops touching it.
Summary by cubic
Inbound Slack events now resume the parked run that owns a channel instead of stopping at an outbound-only integration. Agents can open and invite people in run-owned channels, while duplicate, late, or unowned events settle without starting another run.
New Features
POST /webhooks/slack/eventsverifies signatures, answers URL verification, and stores supported messages, mentions, and member joins in a deduplicated inbox.- Leased dispatch drains events in order, retries undelivered resumes, isolates per-event failures, and returns 200 for invalid or unsupported payloads Slack should not retry.
slack.channel.openclaims or reuses normalized channels, joins the bot before use, records the channel on the run, and refuses a reused channel the agent can no longer reach;slack.channel.invitesupports workspace members and Slack Connect guests.- Resumed runs keep the channel they own, keep a paused agent's message for replay, and stop sending invitations when the run ends.
run-channeldestinations resolve to the channel opened by the run;chosendestinations remain pinned to inspected Slack IDs.- The builder can create missing channels with approval and asks one question before routing a named channel outside the inspected inventory.
Migration
- Set
SLACK_SIGNING_SECRET, configure Slack Event Subscriptions withAPI_URL + /webhooks/slack/events, and keep the tunnel hostname stable withbun run tunnel:slack; the tunnel forwards toPORTunlessSLACK_TUNNEL_PORToverrides it. - Re-approve the Slack app to grant
app_mentions:read, then apply the four Prisma migrations. - Existing Slack destinations must include
resolution: "chosen"or"run-channel"; destinations without it fail validation.