Skip to content

feat(slack): pick an org from one dropdown in the shared-channel route prompt - #1142

Merged
kmonsoe merged 2 commits into
mainfrom
feat/slack-shared-route-picker
Oct 7, 2026
Merged

kmonsoe merged 2 commits into
mainfrom
feat/slack-shared-route-picker

Conversation

@kmonsoe

@kmonsoe kmonsoe commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

What

When several Munin orgs share a Slack workspace and the bot joins a channel, the route prompt repeated Mirror all conversations / Escalation alerts only / Not now once per org. With four orgs that's four identical button rows.

The prompt now has:

  • a bold title (":wave: Munin joined this channel") with a one-line explanation, then a divider
  • one org picker (static_select) with an All orgs option first, followed by All conversations / Escalations only / Not now once
  • All conversations as the primary (green) button — also in the single-org prompt
  • one compact context line per routed org underneath: ":white_check_mark: Org · all conversations · set by @user"

Behaviour

  • Pick an org (or All orgs), then a button. The picked value is read from state.values on the button's block_actions payload; buttons carry value: "shared".
  • A button pressed before anything is picked gets an ephemeral "Pick an org from the list first."
  • Each org still needs an owner/admin of that org. All orgs routes every org the clicker administers and lists the skipped ones (unlinked / not admin / conflict) in one ephemeral.
  • A routed org drops out of the picker; All orgs disappears once a single org is left; the picker disappears when none are left.
  • Not now closes the prompt for every org still waiting (clicker must be linked to at least one of them); lines for already-routed orgs stay.
  • The single-org prompt keeps its layout and labels.

The per-org routing (user mapping → owner/admin check → setRouting under bypass_rls) is extracted into routeOrg so the single and shared paths share it.

Block budget: intro + divider + actions + up to 40 done lines ≤ 50 blocks, so MAX_SHARED_ROUTE_PROMPT_ORGS goes from 20 to 40. Option labels are cut at Slack's 75-char limit.

Relation to #1141

#1141 (merged first) made this prompt name no orgs, so the channel would not learn who else uses the workspace. This PR deliberately brings the names back in the picker. What it keeps from #1141:

  • Routing from the picker (single org or All orgs) goes through the shared-channel membership check (verifiedSlackUserId → slack_not_channel_member).
  • An unexpected routing failure shows an ephemeral warning instead of failing silently.
  • Prompts already posted with feat(slack): guard channels several orgs share #1141's unnamed buttons (workspace:<teamId>) still work through its handler.

Compatibility

Shared prompts already posted (per-org buttons whose value is an integration id) take the single-org path: pressing one routes that org and replaces the whole prompt with its confirmation. The remaining orgs can be routed from the dashboard or slack_set_routing.

Testing

  • slack-projection.test.ts: picker contents, All orgs visibility, option truncation, block/option limits, resolve and dismiss shapes, primary style.
  • slack-interactions.integration.test.ts: routing the picked org, All orgs with a skipped org, no pick, dismiss, unlinked clicker.
  • slack-inbound.integration.test.ts: the join prompt carries a single picker with every unrouted org.
  • slack-interactions.integration.test.ts also covers a picked org refused with slack_not_channel_member.
  • After merging main: all 290 Slack tests pass locally against a freshly migrated DB; typecheck and lint clean.
  • Not yet verified in a live workspace that Slack includes the select's state.values on the button click (documented behaviour, mocked in tests).

Skill connect-slack.md and docs-fixtures/skills.json updated.

🤖 Generated with Claude Code

kmonsoe and others added 2 commits October 4, 2026 23:14
…e prompt

When several Munin orgs share a workspace, the prompt posted on channel
join repeated a row of three buttons per org. It now shows one org picker
(with an "All orgs" option) and the buttons once. Routed orgs drop out of
the picker and are listed underneath as one compact line each; "Not now"
closes the prompt for every org still waiting. "All conversations" is the
primary button in both the shared and the single-org prompt.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Resolves the conflicts with #1141 (guard channels several orgs share).
The org picker stays, so the shared join prompt names the waiting orgs
again. Routing from the picker now goes through the channel-membership
check #1141 added, and unexpected routing failures surface as an
ephemeral instead of silence. Prompts posted with #1141's unnamed
workspace buttons are still handled.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@kmonsoe
kmonsoe merged commit 327cfcd into main Oct 7, 2026
7 checks passed
@kmonsoe
kmonsoe deleted the feat/slack-shared-route-picker branch October 14, 2026 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant