Skip to content

feat(messaging): compact conversation rows and relabel External connectors (#1113) - #1122

Merged
DoodleBears merged 11 commits into
mainfrom
claude/1113-connectors-relabel
Oct 7, 2026
Merged

DoodleBears merged 11 commits into
mainfrom
claude/1113-connectors-relabel

Conversation

@DoodleBears

@DoodleBears DoodleBears commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Vain · project thread

Closes #1113 · part of #1107 · ADR-0142 · stacked on #1121 (base switches to main once #1120 and #1121 merge)

Before: External connectors mixed saved delivery targets, per-conversation authorization and Channel syncs. The Lark setup guide had five steps (account, target, identity, grant, verify), and the Lark, Slack and WeChat guides still taught saved targets and per-conversation authorization.

After: External connectors lists existing syncs and keeps Save a send target (advanced) for apps that can't post to conversations directly. A conversation row shows where it is synced, and its actions (Mute, Rules, Block) are outline DSH buttons on their own row, each with a tooltip. The Lark setup guide is one compact list of three numbered steps. The guides, CONTEXT terms and architecture follow ADR-0142.

Per review, syncing that hangs off a bound app's conversation is the wrong model. Adding a sync will be redesigned around External connectors, taking any connected app's conversation whether or not a Bot has it bound (separate spec). So this PR adds no new way to create a sync; the Host fixes below still apply to existing and future syncs.

How

  • Host (real bugs found on the live instance).
    • Adding a sync to an implicit entry failed with provider-unavailable, because channelBridge inspected the entry by its saved target, and implicit entries have none. It now uses the same inspectGrant as reception, which checks the account.
    • Once synced, the account consumer had already admitted a mention, so the entry's own consumer saw an existing source and skipped placement. For an implicit entry's DM or mention, the route consumer now places into synced Channels and leaves admission to default traffic, so nothing is admitted twice and mute still applies.
    • An implicit entry's built-in Inbox route no longer shows as an "Inbox only" row in External connectors.
  • Client.
    • ExternalConversations puts row actions on a separate row of outline Buttons wrapped in Tooltips, so the name and meta keep the full width. Cards in the edit-identity modal no longer get the generic list indent.
    • ChannelBridgeList drops + Add connector; with no syncs it shows No external sources connected. The authorize row is relabelled Save a send target (advanced).
    • larkSetupState and LarkSetupGuide drop the target picker and use app → bind → verify. Platform and account sit side by side, each step is one numbered line (✓ when confirmed) with its hint behind an info icon and a short Locate button, and the test text sits under the verify step.
  • Docs. Lark, Slack and WeChat guides (zh/en) rewritten around Bind app, with saved targets in an advanced section. External connectors/identities pages, sidebar index, CONTEXT.md/CONTEXT.zh.md, the architecture Messaging section and CHANGELOG zh/en.

Screenshots

From a real Host with a simulated Lark provider. All variants: https://github.com/BotHarness/BotHarness/tree/claude/1113-connectors-relabel/docs/assets/pr/1113-connectors-relabel

zh light en dark
Conversation rows
External connectors
Three-step setup guide

Tests

  • messaging-default-traffic.test.ts: an implicit group entry synced into a Group Channel gets its next mention placed there; the Channel lists one sync and the Bot DM lists no Inbox-only row.
  • Client: a synced entry shows Synced to … and offers no Sync button; the setup guide walks three steps and falls back on disconnection; External connectors lists the sync then the advanced row.
  • Client 120 files / 891 tests and docs 13 files / 89 tests pass. tsc, lint, oxfmt and pnpm changelog:check are clean.

Real Host (DSH 0.2.0-rc.1, OpenCode Go model): an implicit group entry synced into Ada's DM received an @mention there, and Ada replied SYNC-OK through the app in 3 s. Hovering Mute shows its tooltip.

Merge risk

  • Until the External connectors redesign lands, there is no UI to add a new sync. Existing syncs keep working and can be edited, paused or removed.
  • Saved-target proactive grants are unchanged and still reached from the advanced row.
  • The video in the Lark guide still shows the earlier five-step flow; the text says so.

Human verification

  1. Open an app under External identities. Each conversation shows its actions on a row below the name; hovering one explains it.
  2. Open Connect Lark / Feishu. Three numbered steps, each with an info icon.
  3. Open External connectors: existing syncs plus Save a send target (advanced).

🤖 Generated with Claude Code

https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH


Generated by Claude Code

claude added 3 commits October 7, 2026 15:27
…llow again (#1109)

The app's Conversations list in Edit identity sorts entries into Waiting,
Active, Muted and Blocked. Mute admits silently, Rules reuses the group
reception editor, Block revokes the entry, cancels unsent replies and
writes a durable block per Bot, app fingerprint and conversation that
survives restart and rebind; Allow again creates a fresh entry with no
backfill. New conversations can be admitted automatically or held for
the user, and new entries are bounded to 20 per hour and 500 active per
app with at most 200 held.

Issue: #1109
Agent-Task: claude-code/cloud/session_01WXjBatxGTRyRSxZYeJpqgH
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH
A Bot can now bind several apps of the same platform; one app still
belongs to one Bot. Generation 63 drops messaging_binding_bot_platform
and the bind and authorize commands no longer refuse a second app of a
platform. A new apps projection lists every Provider account with its
bound Bot; Bind app hides apps another Bot uses, External identities
groups apps by platform, and Bot settings gets an IM apps list that
refreshes on roster changes. Shared replies from a Bot with two apps in
the same group refuse with reply-target-ambiguous.

Issue: #1110
Agent-Task: claude-code/cloud/session_01WXjBatxGTRyRSxZYeJpqgH
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH
…tors

A conversation of a bound app now syncs into a Channel from its own row
(Sync to a Channel). External connectors lists existing syncs and keeps
the saved send target as an advanced fallback. The Lark setup guide
shrinks to app, bind, verify, and the Lark, Slack and WeChat guides,
CONTEXT terms and the architecture Messaging section follow ADR-0142.

The Host now inspects implicit entries through the account when a sync
is added, and places later default traffic into synced Channels without
admitting it twice.

Issue: #1113
Agent-Task: claude-code/cloud/session_01WXjBatxGTRyRSxZYeJpqgH
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH
@DoodleBears DoodleBears self-assigned this Oct 7, 2026
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 55 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 71829960-4476-43f0-a708-8a9c448fc762
📥 Commits

Reviewing files that changed from the base of the PR and between 3408994 and 29801ee.

📒 Files selected for processing (51)
  • CHANGELOG.md
  • CHANGELOG.zh.md
  • CONTEXT.md
  • CONTEXT.zh.md
  • apps/docs/public/guides/channel-sidebar/20b-external-connectors-en.webp
  • apps/docs/public/guides/channel-sidebar/20b-external-connectors-zh.webp
  • apps/docs/public/guides/lark/28-setup-guide.en.webp
  • apps/docs/public/guides/lark/28-setup-guide.zh.webp
  • docs/architecture/botharness-architecture.en.md
  • docs/architecture/botharness-architecture.md
  • docs/assets/pr/1113-connectors-relabel/README.md
  • docs/assets/pr/1113-connectors-relabel/conns-en-dark.webp
  • docs/assets/pr/1113-connectors-relabel/conns-en-light.webp
  • docs/assets/pr/1113-connectors-relabel/conns-zh-dark.webp
  • docs/assets/pr/1113-connectors-relabel/conns-zh-light.webp
  • docs/assets/pr/1113-connectors-relabel/guide-v2-en-dark.webp
  • docs/assets/pr/1113-connectors-relabel/guide-v2-en-light.webp
  • docs/assets/pr/1113-connectors-relabel/guide-v2-zh-dark.webp
  • docs/assets/pr/1113-connectors-relabel/guide-v2-zh-light.webp
  • docs/assets/pr/1113-connectors-relabel/rows-v4-en-dark.webp
  • docs/assets/pr/1113-connectors-relabel/rows-v4-en-light.webp
  • docs/assets/pr/1113-connectors-relabel/rows-v4-zh-dark.webp
  • docs/assets/pr/1113-connectors-relabel/rows-v4-zh-light.webp
  • docs/channel-sidebar/external-connectors.md
  • docs/channel-sidebar/external-connectors.zh.md
  • docs/channel-sidebar/external-identities.md
  • docs/channel-sidebar/external-identities.zh.md
  • docs/channel-sidebar/index.md
  • docs/channel-sidebar/index.zh.md
  • docs/lark-connection.md
  • docs/lark-connection.zh.md
  • docs/slack-connection.md
  • docs/slack-connection.zh.md
  • docs/wechat-connection.md
  • docs/wechat-connection.zh.md
  • packages/client/src/client/channel-bridge-list.tsx
  • packages/client/src/client/external-conversations.tsx
  • packages/client/src/client/external-entries.tsx
  • packages/client/src/client/external-identity-list.tsx
  • packages/client/src/client/lark-setup-guide.tsx
  • packages/client/src/client/lark-setup-state.ts
  • packages/client/src/client/lark-setup-styles.ts
  • packages/client/src/client/locale.ts
  • packages/client/src/client/styles.ts
  • packages/client/test/external-conversations.test.ts
  • packages/client/test/external-entries.test.ts
  • packages/client/test/lark-setup-guide.test.ts
  • packages/client/test/lark-setup-state.test.ts
  • packages/core/src/messaging/inbound.ts
  • packages/core/src/messaging/outbound.ts
  • packages/core/test/messaging-default-traffic.test.ts
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

claude added 5 commits October 7, 2026 16:17
Issue: #1113
Agent-Task: claude-code/cloud/session_01WXjBatxGTRyRSxZYeJpqgH
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH
Conversation row actions move from a trailing column onto their own row of
DSH Buttons, so the name and meta keep the full width. The sync hint moves
into an info tooltip beside the "Sync to a Channel" label. The setup guide
puts platform and account side by side, numbers the three steps in one
compact list with each hint behind an info icon, and keeps the test text
under the verify step.

Issue: #1113
Agent-Task: claude-code/cloud/session_01WXjBatxGTRyRSxZYeJpqgH
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH
Per review, the app overview lives where apps are chosen. Bind app now
lists every connected app: apps a Bot already uses are disabled and name
that Bot (or say they are bound to this Bot), disconnected apps say so,
and Manage app credentials opens IM bots settings. The IM apps list in
Bot settings and its messagingApps bridge method are removed; the
snapshot's accounts already carry the owner.

Issue: #1110
Agent-Task: claude-code/cloud/session_01WXjBatxGTRyRSxZYeJpqgH
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH
Brings in the Bind app change from #1110. The edit-identity modal's
generic list indent no longer applies to card lists, so conversation
cards line up like External connectors.

Issue: #1113
Agent-Task: claude-code/cloud/session_01WXjBatxGTRyRSxZYeJpqgH
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH
Per review, syncing hangs off a bound app's conversation the wrong way
round and will be redesigned around External connectors (any connected
app, bound or not). The row Sync and its panel are removed while the Host
fixes stay; rows still show where an existing sync goes, and External
connectors lists and edits existing syncs. Row actions use outline DSH
Buttons, each with a tooltip explaining it (Mute vs Block in particular).
Guides, CONTEXT, architecture and changelog drop the row Sync steps.

Issue: #1113
Agent-Task: claude-code/cloud/session_01WXjBatxGTRyRSxZYeJpqgH
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WXjBatxGTRyRSxZYeJpqgH
@DoodleBears DoodleBears changed the title feat(messaging): sync from the conversation row and relabel External connectors (#1113) feat(messaging): compact conversation rows and relabel External connectors (#1113) Oct 7, 2026
claude added 3 commits October 7, 2026 17:11
# Conflicts:
#	CHANGELOG.md
#	CHANGELOG.zh.md
#	packages/client/src/client/external-entries.tsx
#	packages/client/src/client/external-identity-list.tsx
#	packages/client/src/client/locale.ts
#	packages/client/test/external-identity-list.test.ts
#	packages/core/src/database/schema-plan.ts
…s-relabel

# Conflicts:
#	packages/client/src/client/external-entries.tsx
#	packages/client/src/client/external-identity-list.tsx
@DoodleBears
DoodleBears changed the base branch from claude/1110-several-apps to main October 7, 2026 17:16
@DoodleBears
DoodleBears merged commit 13ca500 into main Oct 7, 2026
2 checks passed
@DoodleBears
DoodleBears deleted the claude/1113-connectors-relabel branch October 28, 2026 04:24
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.

External connectors relabel and the connection guides

2 participants