From 7e713be8896659d56fe2798ff8e7384466a58144 Mon Sep 17 00:00:00 2001 From: Pierre Date: Tue, 7 Jul 2026 11:55:59 +0200 Subject: [PATCH] fix: rename chat connector bridge contracts --- .../panels/SettingsIntegrationsPanel.tsx | 12 ++-- .../src/v2/hooks/use-settings-page-state.ts | 10 +-- .../src/v2/lib/chat-provider-view-models.ts | 22 +++---- dashboard/src/v2/lib/settings-search-index.ts | 2 +- .../architecture/external-chat-providers.md | 20 +++--- docs-web/architecture/index.md | 2 +- .../architecture-external-chat-providers.mdx | 20 +++--- .../content/docs/architecture-overview.mdx | 2 +- docs-web/content/docs/developer-mcp-tools.mdx | 6 +- docs-web/content/docs/registry.ts | 2 +- .../content/docs/user-dashboard-settings.mdx | 10 +-- .../docs/user-providers-and-models.mdx | 12 ++-- docs-web/developer/mcp-tools.md | 6 +- docs-web/user/dashboard/settings.md | 10 +-- docs-web/user/providers-and-models.md | 12 ++-- docs/architecture/external-chat-providers.md | 18 +++--- docs/architecture/repository-map.md | 2 +- docs/mcp/tools-and-contracts.md | 2 +- docs/settings/chat-provider-integrations.md | 26 ++++---- .../subcategories/provider-integration.md | 8 +-- src/contracts/chat-provider-types.ts | 64 +++++++++---------- src/contracts/mcp-tool-definitions.ts | 2 +- src/mcp/management/chat-provider-actions.ts | 2 +- src/services/chat-provider-adapters.ts | 12 ++-- src/services/chat-provider-security.ts | 8 +-- .../management-chat-provider-actions.test.ts | 2 +- .../chat-provider-ingress-routes.test.ts | 12 ++-- .../server/chat-provider-routes.test.ts | 30 ++++----- .../chat-provider-ingress-service.test.ts | 4 +- .../chat-provider-outbound-service.test.ts | 14 ++-- .../lib/chat-provider-view-models.test.ts | 22 +++---- .../lib/settings-search-index.test.ts | 2 +- .../v2/settings-chat-providers-panel.test.tsx | 32 +++++----- 33 files changed, 203 insertions(+), 207 deletions(-) diff --git a/dashboard/src/v2/components/settings/panels/SettingsIntegrationsPanel.tsx b/dashboard/src/v2/components/settings/panels/SettingsIntegrationsPanel.tsx index 35cc155d0a..82ce33b7a7 100644 --- a/dashboard/src/v2/components/settings/panels/SettingsIntegrationsPanel.tsx +++ b/dashboard/src/v2/components/settings/panels/SettingsIntegrationsPanel.tsx @@ -608,7 +608,7 @@ export const SettingsIntegrationsPanel: FunctionComponent<{ state: SettingsPageS }, { id: "chat", - label: "PROVIDERS", + label: "CHAT CONNECTORS", purpose: "Chat bridges, delivery health, and project/channel bindings", items: integrations.filter((integration) => isChatProviderIntegrationId(integration.id)), }, @@ -1090,7 +1090,7 @@ export const SettingsIntegrationsPanel: FunctionComponent<{ state: SettingsPageS updateConnectionDraft(connection, definition, (current) => ({ ...current, enabled: !current.enabled }))} /> - + undefined} disabled mono aria-label={`${connection.displayName} ingress URL`} /> @@ -1200,7 +1200,7 @@ export const SettingsIntegrationsPanel: FunctionComponent<{ state: SettingsPageS Back to Integrations } actions={ @@ -1213,10 +1213,10 @@ export const SettingsIntegrationsPanel: FunctionComponent<{ state: SettingsPageS } > {chatProviders.loading ? ( - Loading provider setup definitions, connections, bindings, and delivery health. + Loading connector setup definitions, connections, bindings, and delivery health. ) : null} {chatProviders.error ? ( - {chatProviders.error} + {chatProviders.error} ) : null} {definition ? ( @@ -1225,7 +1225,7 @@ export const SettingsIntegrationsPanel: FunctionComponent<{ state: SettingsPageS ) : ( - Refresh chat provider settings to load setup fields for this provider. + Refresh chat connector settings to load setup fields for this connector. )} {definition && providerConnections.length > 0 ? (
diff --git a/dashboard/src/v2/hooks/use-settings-page-state.ts b/dashboard/src/v2/hooks/use-settings-page-state.ts index c7583831c5..e0473b6441 100644 --- a/dashboard/src/v2/hooks/use-settings-page-state.ts +++ b/dashboard/src/v2/hooks/use-settings-page-state.ts @@ -144,11 +144,11 @@ const INTEGRATIONS: IntegrationDefinition[] = [ { id: "github", label: "GitHub", description: "Repository, pull request, branch, and CI integration" }, { id: "gitlab", label: "GitLab", description: "GitLab repository, merge request, and CI token integration" }, { id: "jira", label: "Jira", description: "Atlassian Jira issue search, sprint linking, and completion transitions" }, - { id: "whatsapp", label: "WhatsApp", description: "OpenClaw or webhook bridge for WhatsApp groups and business conversations" }, - { id: "imessage", label: "iMessage", description: "OpenClaw or native macOS bridge for iMessage routing" }, - { id: "telegram", label: "Telegram", description: "Telegram bot or OpenClaw bridge for channel ingress and replies" }, - { id: "slack", label: "Slack", description: "Slack Events or OpenClaw bridge with signed webhooks" }, - { id: "microsoft-teams", label: "Microsoft Teams", description: "Teams bot or OpenClaw bridge for tenant channels" }, + { id: "whatsapp", label: "WhatsApp", description: "Managed or webhook bridge for WhatsApp groups and business conversations" }, + { id: "imessage", label: "iMessage", description: "Managed or native macOS bridge for iMessage routing" }, + { id: "telegram", label: "Telegram", description: "Telegram bot or managed bridge for channel ingress and replies" }, + { id: "slack", label: "Slack", description: "Slack Events or managed bridge with signed webhooks" }, + { id: "microsoft-teams", label: "Microsoft Teams", description: "Teams bot or managed bridge for tenant channels" }, { id: "discord", label: "Discord", description: "Discord bot or gateway connection for project chat" }, { id: "notion", label: "Notion", description: "Read-only import from Notion workspace pages and databases" }, { id: "asana", label: "Asana", description: "Read-only import from Asana workspaces, teams, and projects" }, diff --git a/dashboard/src/v2/lib/chat-provider-view-models.ts b/dashboard/src/v2/lib/chat-provider-view-models.ts index ee86a8984e..944b631ac1 100644 --- a/dashboard/src/v2/lib/chat-provider-view-models.ts +++ b/dashboard/src/v2/lib/chat-provider-view-models.ts @@ -22,23 +22,23 @@ export const CHAT_PROVIDER_KINDS: ChatProviderKind[] = [ const SETUP_NOTES: Record = { whatsapp: [ - "Use the OpenClaw WhatsApp plugin for a managed bridge, or paste the generated ingress URL into a Meta webhook gateway.", + "Use a managed WhatsApp bridge, or paste the generated ingress URL into a Meta webhook gateway.", "Bind each WhatsApp group or business conversation by its external channel id before enabling inbound routing.", ], imessage: [ - "Use OpenClaw iMessage on a trusted Apple device, or run the macOS native bridge command from a locked-down local account.", + "Use a managed iMessage bridge on a trusted Apple device, or run the macOS native bridge command from a locked-down local account.", "Native bridge mode accepts an optional bridge token; keep it in the secret field and rotate it if the host changes.", ], telegram: [ - "Connect an OpenClaw Telegram core bridge or configure a Telegram bot webhook with the generated ingress URL.", + "Connect a managed Telegram bridge or configure a Telegram bot webhook with the generated ingress URL.", "Use bot usernames and channel labels only for operator clarity; routing is based on the external channel id and binding hints.", ], slack: [ - "Configure Slack Events API or the OpenClaw Slack plugin to send message events to the connection ingress URL.", + "Configure Slack Events API or a managed Slack bridge to send message events to the connection ingress URL.", "Store Slack signing secrets or bot tokens only in the credential fields; saved values are returned as redacted metadata.", ], "microsoft-teams": [ - "Use the OpenClaw Teams plugin or a Teams bot endpoint that posts normalized activity payloads to the ingress URL.", + "Use a managed Teams bridge or a Teams bot endpoint that posts normalized activity payloads to the ingress URL.", "Tenant and bot identifiers belong in setup fields; bot passwords and signing material belong in secret fields.", ], discord: [ @@ -101,13 +101,13 @@ export const getChatProviderDescription = (providerKind: ChatProviderKind): stri case "whatsapp": return "WhatsApp bridge, webhook setup, and project/channel routing."; case "imessage": - return "iMessage OpenClaw or native macOS bridge with command controls."; + return "iMessage managed or native macOS bridge with command controls."; case "telegram": - return "Telegram bot and OpenClaw channel ingress for project chat."; + return "Telegram bot and managed channel ingress for project chat."; case "slack": - return "Slack Events or OpenClaw bridge with signed inbound routing."; + return "Slack Events or managed bridge with signed inbound routing."; case "microsoft-teams": - return "Teams bot and OpenClaw bridge bindings for project channels."; + return "Teams bot and managed bridge bindings for project channels."; case "discord": return "Discord bot or gateway connection with explicit channel bindings."; } @@ -115,8 +115,8 @@ export const getChatProviderDescription = (providerKind: ChatProviderKind): stri export const getBridgeModeLabel = (bridgeMode: ChatProviderBridgeMode): string => { switch (bridgeMode) { - case "openclaw": - return "OpenClaw"; + case "managed_bridge": + return "Managed bridge"; case "webhook": return "Webhook"; case "native_bridge": diff --git a/dashboard/src/v2/lib/settings-search-index.ts b/dashboard/src/v2/lib/settings-search-index.ts index cd261fea2c..4d1b3ffa69 100644 --- a/dashboard/src/v2/lib/settings-search-index.ts +++ b/dashboard/src/v2/lib/settings-search-index.ts @@ -229,7 +229,7 @@ const BASE_CATEGORY_TERMS: Record = { "microsoft teams", "discord", "imessage", - "openclaw", + "managed_bridge", "webhook", "native bridge", "bridge token", diff --git a/docs-web/architecture/external-chat-providers.md b/docs-web/architecture/external-chat-providers.md index ca0601584d..6da03057da 100644 --- a/docs-web/architecture/external-chat-providers.md +++ b/docs-web/architecture/external-chat-providers.md @@ -1,4 +1,4 @@ -# External chat providers +# External chat connectors Code UX persists external chat provider configuration separately from MCP listener connections and dashboard conversation messages. The runtime stays adapter-neutral: it records provider setup, bridge mode, channel routing, inbound dedupe, outbound delivery state, and bridge attempts without adding provider SDK dependencies. @@ -15,13 +15,13 @@ Supported providers: - `microsoft-teams` - `discord` -Supported bridge modes are `openclaw`, `webhook`, and `native_bridge`. Provider setup schemas describe the executable bridge shape for future runtime adapters: +Supported bridge modes are `managed_bridge`, `webhook`, and `native_bridge`. Provider setup schemas describe the executable bridge shape for future runtime adapters: -- WhatsApp: OpenClaw plugin or webhook. -- iMessage: OpenClaw core or macOS native bridge command. -- Telegram: OpenClaw core or bot webhook. -- Slack: OpenClaw plugin or Events webhook. -- Microsoft Teams: OpenClaw plugin or bot webhook. +- WhatsApp: managed bridge or webhook. +- iMessage: managed bridge or macOS native bridge command. +- Telegram: managed bridge or bot webhook. +- Slack: managed bridge or Events webhook. +- Microsoft Teams: managed bridge or bot webhook. - Discord: bot/webhook gateway. Public records expose redacted credential metadata only. Runtime code that needs secrets must call the explicit internal repository read path. @@ -85,7 +85,7 @@ The outbound runtime builds one delivery payload per persisted reply with: Bridge execution is isolated behind `src/services/chat-provider-adapters.ts`: -- `openclaw`: HTTP `POST` to a configured OpenClaw bridge URL such as `openclawBridgeUrl`, using bridge credentials as transport headers. +- `managed_bridge`: HTTP `POST` to a configured managed bridge URL such as `bridgeUrl`, using bridge credentials as transport headers. - `webhook`: HTTP `POST` to configured generic bridge URLs such as `webhookUrl`, `eventsUrl`, `botEndpointUrl`, or `gatewayUrl`. - `native_bridge`: local command execution for macOS/iMessage-style bridge scripts. The payload is written as JSON on stdin, commands are parsed into executable plus arguments without shell interpretation, and optional bridge tokens are supplied through environment variables. @@ -124,7 +124,7 @@ Dashboard settings use `src/server/chat-provider-routes.ts` to manage chat provi ## Dashboard Settings UI -Settings -> Integrations includes a Providers group for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Each provider detail view reads the setup definitions, redacted connection records, channel bindings, generated ingress URLs, and outbound delivery status from the dashboard API. +Settings -> Integrations includes a Chat Connectors group for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Each provider detail view reads the setup definitions, redacted connection records, channel bindings, generated ingress URLs, and outbound delivery status from the dashboard API. The UI lets operators create and edit provider connections with display names, bridge modes, setup fields, enabled state, connection status, and write-only secret replacement fields. Saved secrets are never rendered back into the form; configured credentials appear only as redacted metadata and empty replacement inputs. @@ -132,7 +132,7 @@ Channel binding controls support multiple projects on the same external channel Provider cards and connection detail views surface enabled state, bridge mode, ingress URL, authentication status, configured channels, bound projects, outbound reply state, pending outbound delivery count, and failed outbound delivery count. Recent failed outbound messages are shown with retryable labels and redacted error text. -The ingress endpoint supports OpenClaw, webhook, and native bridge payloads for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. OpenClaw and native bridges authenticate with bearer tokens from the configured bridge secret. Webhook bridges require a configured signing secret and a valid HMAC signature; they do not accept bearer-only fallback. All ingress requests require a fresh timestamp, and signed requests or requests with explicit nonces are replay-checked before processing. +The ingress endpoint supports Managed, webhook, and native bridge payloads for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Managed and native bridges authenticate with bearer tokens from the configured bridge secret. Webhook bridges require a configured signing secret and a valid HMAC signature; they do not accept bearer-only fallback. All ingress requests require a fresh timestamp, and signed requests or requests with explicit nonces are replay-checked before processing. Inbound messages normalize to provider connection id, provider kind, external channel id/name, external sender id/name, text, external message id, timestamp, and redacted raw metadata. The repository idempotency lookup runs before chat posting; duplicate external messages return the existing delivery record without creating another conversation message. diff --git a/docs-web/architecture/index.md b/docs-web/architecture/index.md index 227790eedb..5341ce1958 100644 --- a/docs-web/architecture/index.md +++ b/docs-web/architecture/index.md @@ -15,7 +15,7 @@ It is for contributors and integrators who need to reason about *how* Code UX ma | 5 | [CI integration](./ci-integration.md) | Feature PR gate, merge protocol, autofix retries, conflict handling | | 6 | [Dashboard architecture](./dashboard-architecture.md) | Preact stack, real-time client, route map, state model | | 7 | [Data model](./data-model.md) | Projects, sprints, tasks, runs, dispatches, memory, conversations | -| 8 | [External chat providers](./external-chat-providers.md) | Provider setup, channel bindings, inbound dedupe, outbound delivery state | +| 8 | [External chat connectors](./external-chat-providers.md) | Provider setup, channel bindings, inbound dedupe, outbound delivery state | | 9 | [Configuration resolution](./configuration-resolution.md) | Cascade order, search paths, settings hierarchy | | 10 | [Security model](./security.md) | Authentication, authorisation, secrets, network surface | diff --git a/docs-web/content/docs/architecture-external-chat-providers.mdx b/docs-web/content/docs/architecture-external-chat-providers.mdx index ca0601584d..6da03057da 100644 --- a/docs-web/content/docs/architecture-external-chat-providers.mdx +++ b/docs-web/content/docs/architecture-external-chat-providers.mdx @@ -1,4 +1,4 @@ -# External chat providers +# External chat connectors Code UX persists external chat provider configuration separately from MCP listener connections and dashboard conversation messages. The runtime stays adapter-neutral: it records provider setup, bridge mode, channel routing, inbound dedupe, outbound delivery state, and bridge attempts without adding provider SDK dependencies. @@ -15,13 +15,13 @@ Supported providers: - `microsoft-teams` - `discord` -Supported bridge modes are `openclaw`, `webhook`, and `native_bridge`. Provider setup schemas describe the executable bridge shape for future runtime adapters: +Supported bridge modes are `managed_bridge`, `webhook`, and `native_bridge`. Provider setup schemas describe the executable bridge shape for future runtime adapters: -- WhatsApp: OpenClaw plugin or webhook. -- iMessage: OpenClaw core or macOS native bridge command. -- Telegram: OpenClaw core or bot webhook. -- Slack: OpenClaw plugin or Events webhook. -- Microsoft Teams: OpenClaw plugin or bot webhook. +- WhatsApp: managed bridge or webhook. +- iMessage: managed bridge or macOS native bridge command. +- Telegram: managed bridge or bot webhook. +- Slack: managed bridge or Events webhook. +- Microsoft Teams: managed bridge or bot webhook. - Discord: bot/webhook gateway. Public records expose redacted credential metadata only. Runtime code that needs secrets must call the explicit internal repository read path. @@ -85,7 +85,7 @@ The outbound runtime builds one delivery payload per persisted reply with: Bridge execution is isolated behind `src/services/chat-provider-adapters.ts`: -- `openclaw`: HTTP `POST` to a configured OpenClaw bridge URL such as `openclawBridgeUrl`, using bridge credentials as transport headers. +- `managed_bridge`: HTTP `POST` to a configured managed bridge URL such as `bridgeUrl`, using bridge credentials as transport headers. - `webhook`: HTTP `POST` to configured generic bridge URLs such as `webhookUrl`, `eventsUrl`, `botEndpointUrl`, or `gatewayUrl`. - `native_bridge`: local command execution for macOS/iMessage-style bridge scripts. The payload is written as JSON on stdin, commands are parsed into executable plus arguments without shell interpretation, and optional bridge tokens are supplied through environment variables. @@ -124,7 +124,7 @@ Dashboard settings use `src/server/chat-provider-routes.ts` to manage chat provi ## Dashboard Settings UI -Settings -> Integrations includes a Providers group for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Each provider detail view reads the setup definitions, redacted connection records, channel bindings, generated ingress URLs, and outbound delivery status from the dashboard API. +Settings -> Integrations includes a Chat Connectors group for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Each provider detail view reads the setup definitions, redacted connection records, channel bindings, generated ingress URLs, and outbound delivery status from the dashboard API. The UI lets operators create and edit provider connections with display names, bridge modes, setup fields, enabled state, connection status, and write-only secret replacement fields. Saved secrets are never rendered back into the form; configured credentials appear only as redacted metadata and empty replacement inputs. @@ -132,7 +132,7 @@ Channel binding controls support multiple projects on the same external channel Provider cards and connection detail views surface enabled state, bridge mode, ingress URL, authentication status, configured channels, bound projects, outbound reply state, pending outbound delivery count, and failed outbound delivery count. Recent failed outbound messages are shown with retryable labels and redacted error text. -The ingress endpoint supports OpenClaw, webhook, and native bridge payloads for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. OpenClaw and native bridges authenticate with bearer tokens from the configured bridge secret. Webhook bridges require a configured signing secret and a valid HMAC signature; they do not accept bearer-only fallback. All ingress requests require a fresh timestamp, and signed requests or requests with explicit nonces are replay-checked before processing. +The ingress endpoint supports Managed, webhook, and native bridge payloads for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Managed and native bridges authenticate with bearer tokens from the configured bridge secret. Webhook bridges require a configured signing secret and a valid HMAC signature; they do not accept bearer-only fallback. All ingress requests require a fresh timestamp, and signed requests or requests with explicit nonces are replay-checked before processing. Inbound messages normalize to provider connection id, provider kind, external channel id/name, external sender id/name, text, external message id, timestamp, and redacted raw metadata. The repository idempotency lookup runs before chat posting; duplicate external messages return the existing delivery record without creating another conversation message. diff --git a/docs-web/content/docs/architecture-overview.mdx b/docs-web/content/docs/architecture-overview.mdx index 16ec4eca94..5b28caa78c 100644 --- a/docs-web/content/docs/architecture-overview.mdx +++ b/docs-web/content/docs/architecture-overview.mdx @@ -15,7 +15,7 @@ It is for contributors and integrators who need to reason about *how* Code UX ma | 5 | [CI integration](/docs/architecture-ci-integration) | Feature PR gate, merge protocol, autofix retries, conflict handling | | 6 | [Dashboard architecture](/docs/architecture-dashboard-architecture) | Preact stack, real-time client, route map, state model | | 7 | [Data model](/docs/architecture-data-model) | Projects, sprints, tasks, runs, dispatches, memory, conversations | -| 8 | [External chat providers](/docs/architecture-external-chat-providers) | Provider setup, channel bindings, inbound dedupe, outbound delivery state | +| 8 | [External chat connectors](/docs/architecture-external-chat-providers) | Provider setup, channel bindings, inbound dedupe, outbound delivery state | | 9 | [Configuration resolution](/docs/architecture-configuration-resolution) | Cascade order, search paths, settings hierarchy | | 10 | [Security model](/docs/architecture-security) | Authentication, authorisation, secrets, network surface | diff --git a/docs-web/content/docs/developer-mcp-tools.mdx b/docs-web/content/docs/developer-mcp-tools.mdx index fa8b7f37a3..6816c55cce 100644 --- a/docs-web/content/docs/developer-mcp-tools.mdx +++ b/docs-web/content/docs/developer-mcp-tools.mdx @@ -2,7 +2,7 @@ Code UX is also an MCP server. When connected, it advertises a set of **management tools** that an MCP client (or another agent) can call to drive projects, sprints, tasks, agents, memory, persistent -skills, settings, previews, chat providers, and telemetry. This page is the exact contract: the tool list, each +skills, settings, previews, chat connectors, and telemetry. This page is the exact contract: the tool list, each tool's `action` enum, input shape, approval rules, and the error model. > **Server identity:** the server identifies as `code-ux`, with the version matching the installed @@ -157,8 +157,8 @@ channel bindings, and outbound delivery inspection. It does not process inbound outbound sends; those are runtime services behind authenticated ingress and delivery adapters. Supported provider kinds are `whatsapp`, `imessage`, `telegram`, `slack`, `microsoft-teams`, and -`discord`. Supported bridge modes are `openclaw`, `webhook`, and `native_bridge`. Code UX does not -call those providers' official APIs directly; it talks to the configured OpenClaw bridge, webhook +`discord`. Supported bridge modes are `managed_bridge`, `webhook`, and `native_bridge`. Code UX does not +call those providers' official APIs directly; it talks to the configured managed bridge, webhook gateway, or native bridge command. Common actions: diff --git a/docs-web/content/docs/registry.ts b/docs-web/content/docs/registry.ts index 43f98d407d..d6e34229db 100644 --- a/docs-web/content/docs/registry.ts +++ b/docs-web/content/docs/registry.ts @@ -364,7 +364,7 @@ export const docsRegistry: Record = { id: 'architecture-external-chat-providers', path: '/docs/architecture-external-chat-providers', section: 'Architecture', - title: "External chat providers", + title: "External chat connectors", description: "Code UX persists external chat provider configuration separately from MCP listener connections and dashboard conversation messages. The runtime stays adapter-neutral: it records provider setup, bridge mode, channel ro...", }, 'architecture-configuration-resolution': { diff --git a/docs-web/content/docs/user-dashboard-settings.mdx b/docs-web/content/docs/user-dashboard-settings.mdx index 0c69849918..7c6bbde23f 100644 --- a/docs-web/content/docs/user-dashboard-settings.mdx +++ b/docs-web/content/docs/user-dashboard-settings.mdx @@ -713,18 +713,18 @@ Related docs: -Explains that AI provider credentials are system-owned while project scopes still control routing and auth-copy behavior. External chat provider connections also appear under Settings -> Providers, but they use a separate chat-provider runtime path for ingress, channel binding, and outbound reply delivery. +Explains that AI provider credentials are system-owned while project scopes still control routing and auth-copy behavior. External chat connector connections appear under Settings -> Integrations -> Chat Connectors, but they use a separate chat-provider runtime path for ingress, channel binding, and outbound reply delivery. -**What it controls:** The notices clarify where AI provider instances live, which settings remain project-scoped, and why chat provider connections are configured beside provider credentials without participating in AI model routing. +**What it controls:** The notices clarify where AI provider instances live, which settings remain project-scoped, and why chat connector connections are configured beside provider credentials without participating in AI model routing. -**Recommended defaults:** Switch to system scope to add AI provider credentials, then route them from AI Models. Configure chat provider connections from the provider integration cards only when an external chat bridge is ready to send authenticated ingress. +**Recommended defaults:** Switch to system scope to add AI provider credentials, then route them from AI Models. Configure chat connector connections from the provider integration cards only when an external chat bridge is ready to send authenticated ingress. -**Risks and gotchas:** Expecting project scope to create AI provider credentials can leave routes without provider instances. Expecting chat provider credentials to affect AI routing can also be misleading: chat provider connections bind external channels to projects, while AI provider credentials decide which model runs Code UX work. +**Risks and gotchas:** Expecting project scope to create AI provider credentials can leave routes without provider instances. Expecting chat provider credentials to affect AI routing can also be misleading: chat connector connections bind external channels to projects, while AI provider credentials decide which model runs Code UX work. Related docs: - [Provider Routing](/docs/user-providers-and-models) -- [External chat providers](/docs/architecture-external-chat-providers) +- [External chat connectors](/docs/architecture-external-chat-providers) - [Configuration and Storage](/docs/developer-settings-reference) ### Provider Credentials diff --git a/docs-web/content/docs/user-providers-and-models.mdx b/docs-web/content/docs/user-providers-and-models.mdx index 2773764b9b..bccd6a6631 100644 --- a/docs-web/content/docs/user-providers-and-models.mdx +++ b/docs-web/content/docs/user-providers-and-models.mdx @@ -16,21 +16,21 @@ Code UX dispatches work across **seven providers**, each accepting one or more * All non-Jules providers are *virtual workers* — Code UX shells out to the provider's CLI, optionally inside a Docker container. Authentication is provided by the host CLI's normal login flow; Code UX merely detects and references it. -## External chat providers +## External chat connectors -Settings -> Providers also includes external chat provider connections for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord channels. These are not AI model providers and they do not affect invocation routing. They bind authenticated external chat bridges to Code UX projects so inbound messages can enter project chat threads and assistant replies can be delivered back through the same bridge. +Settings -> Integrations -> Chat Connectors includes external chat connector connections for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord channels. These are not AI model providers and they do not affect invocation routing. They bind authenticated external chat bridges to Code UX projects so inbound messages can enter project chat threads and assistant replies can be delivered back through the same bridge. Supported bridge modes are: -- `openclaw` — HTTP delivery to a configured OpenClaw bridge URL. +- `managed_bridge` — HTTP delivery to a configured managed bridge URL. - `webhook` — HTTP delivery to a configured generic bridge or bot gateway URL. - `native_bridge` — shell-free local command execution for native bridge scripts, with JSON on stdin and optional bridge token environment variables. -Code UX does not call the official WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, or Discord APIs directly. Provider-specific API interaction belongs to the OpenClaw integration, webhook gateway, or native bridge you connect. +Code UX does not call the official WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, or Discord APIs directly. Provider-specific API interaction belongs to the managed bridge, webhook gateway, or native bridge you connect. -Chat provider setup stores connection records, write-only secrets, channel bindings, routing hints, and outbound delivery state separately from AI provider credentials. Webhook ingress requires HMAC signatures when a signing secret is configured; OpenClaw and native bridge ingress use bearer-style bridge tokens. Shared external channels can route to multiple projects only when a selector or routing hint chooses exactly one binding. +Chat provider setup stores connection records, write-only secrets, channel bindings, routing hints, and outbound delivery state separately from AI provider credentials. Webhook ingress requires HMAC signatures when a signing secret is configured; Managed and native bridge ingress use bearer-style bridge tokens. Shared external channels can route to multiple projects only when a selector or routing hint chooses exactly one binding. -For the full setup and routing contract in the published docs, see [External chat providers](/docs/architecture-external-chat-providers). +For the full setup and routing contract in the published docs, see [External chat connectors](/docs/architecture-external-chat-providers). ## The models diff --git a/docs-web/developer/mcp-tools.md b/docs-web/developer/mcp-tools.md index cedea62471..987f7e4907 100644 --- a/docs-web/developer/mcp-tools.md +++ b/docs-web/developer/mcp-tools.md @@ -2,7 +2,7 @@ Code UX is also an MCP server. When connected, it advertises a set of **management tools** that an MCP client (or another agent) can call to drive projects, sprints, tasks, agents, memory, persistent -skills, settings, previews, chat providers, and telemetry. This page is the exact contract: the tool list, each +skills, settings, previews, chat connectors, and telemetry. This page is the exact contract: the tool list, each tool's `action` enum, input shape, approval rules, and the error model. > **Server identity:** the server identifies as `code-ux`, with the version matching the installed @@ -139,8 +139,8 @@ channel bindings, and outbound delivery inspection. It does not process inbound outbound sends; those are runtime services behind authenticated ingress and delivery adapters. Supported provider kinds are `whatsapp`, `imessage`, `telegram`, `slack`, `microsoft-teams`, and -`discord`. Supported bridge modes are `openclaw`, `webhook`, and `native_bridge`. Code UX does not -call those providers' official APIs directly; it talks to the configured OpenClaw bridge, webhook +`discord`. Supported bridge modes are `managed_bridge`, `webhook`, and `native_bridge`. Code UX does not +call those providers' official APIs directly; it talks to the configured managed bridge, webhook gateway, or native bridge command. Common actions: diff --git a/docs-web/user/dashboard/settings.md b/docs-web/user/dashboard/settings.md index 06c8b65fa7..674b65fac9 100644 --- a/docs-web/user/dashboard/settings.md +++ b/docs-web/user/dashboard/settings.md @@ -696,18 +696,18 @@ Related docs: -Explains that AI provider credentials are system-owned while project scopes still control routing and auth-copy behavior. External chat provider connections also appear under Settings -> Providers, but they use a separate chat-provider runtime path for ingress, channel binding, and outbound reply delivery. +Explains that AI provider credentials are system-owned while project scopes still control routing and auth-copy behavior. External chat connector connections appear under Settings -> Integrations -> Chat Connectors, but they use a separate chat-provider runtime path for ingress, channel binding, and outbound reply delivery. -**What it controls:** The notices clarify where AI provider instances live, which settings remain project-scoped, and why chat provider connections are configured beside provider credentials without participating in AI model routing. +**What it controls:** The notices clarify where AI provider instances live, which settings remain project-scoped, and why chat connector connections are configured beside provider credentials without participating in AI model routing. -**Recommended defaults:** Switch to system scope to add AI provider credentials, then route them from AI Models. Configure chat provider connections from the provider integration cards only when an external chat bridge is ready to send authenticated ingress. +**Recommended defaults:** Switch to system scope to add AI provider credentials, then route them from AI Models. Configure chat connector connections from the provider integration cards only when an external chat bridge is ready to send authenticated ingress. -**Risks and gotchas:** Expecting project scope to create AI provider credentials can leave routes without provider instances. Expecting chat provider credentials to affect AI routing can also be misleading: chat provider connections bind external channels to projects, while AI provider credentials decide which model runs Code UX work. +**Risks and gotchas:** Expecting project scope to create AI provider credentials can leave routes without provider instances. Expecting chat provider credentials to affect AI routing can also be misleading: chat connector connections bind external channels to projects, while AI provider credentials decide which model runs Code UX work. Related docs: - [Provider Routing](../providers-and-models.md) -- [External chat providers](../../architecture/external-chat-providers.md) +- [External chat connectors](../../architecture/external-chat-providers.md) - [Configuration and Storage](../../developer/settings-reference.md) ### Provider Credentials diff --git a/docs-web/user/providers-and-models.md b/docs-web/user/providers-and-models.md index 1ec86de9db..d26526099a 100644 --- a/docs-web/user/providers-and-models.md +++ b/docs-web/user/providers-and-models.md @@ -16,21 +16,21 @@ Code UX dispatches work across **seven providers**, each accepting one or more * All non-Jules providers are *virtual workers* — Code UX shells out to the provider's CLI, optionally inside a Docker container. Authentication is provided by the host CLI's normal login flow; Code UX merely detects and references it. -## External chat providers +## External chat connectors -Settings -> Providers also includes external chat provider connections for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord channels. These are not AI model providers and they do not affect invocation routing. They bind authenticated external chat bridges to Code UX projects so inbound messages can enter project chat threads and assistant replies can be delivered back through the same bridge. +Settings -> Integrations -> Chat Connectors includes external chat connector connections for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord channels. These are not AI model providers and they do not affect invocation routing. They bind authenticated external chat bridges to Code UX projects so inbound messages can enter project chat threads and assistant replies can be delivered back through the same bridge. Supported bridge modes are: -- `openclaw` — HTTP delivery to a configured OpenClaw bridge URL. +- `managed_bridge` — HTTP delivery to a configured managed bridge URL. - `webhook` — HTTP delivery to a configured generic bridge or bot gateway URL. - `native_bridge` — shell-free local command execution for native bridge scripts, with JSON on stdin and optional bridge token environment variables. -Code UX does not call the official WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, or Discord APIs directly. Provider-specific API interaction belongs to the OpenClaw integration, webhook gateway, or native bridge you connect. +Code UX does not call the official WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, or Discord APIs directly. Provider-specific API interaction belongs to the managed bridge, webhook gateway, or native bridge you connect. -Chat provider setup stores connection records, write-only secrets, channel bindings, routing hints, and outbound delivery state separately from AI provider credentials. Webhook ingress requires HMAC signatures when a signing secret is configured; OpenClaw and native bridge ingress use bearer-style bridge tokens. Shared external channels can route to multiple projects only when a selector or routing hint chooses exactly one binding. +Chat provider setup stores connection records, write-only secrets, channel bindings, routing hints, and outbound delivery state separately from AI provider credentials. Webhook ingress requires HMAC signatures when a signing secret is configured; Managed and native bridge ingress use bearer-style bridge tokens. Shared external channels can route to multiple projects only when a selector or routing hint chooses exactly one binding. -For the full setup and routing contract in the published docs, see [External chat providers](../architecture/external-chat-providers.md). +For the full setup and routing contract in the published docs, see [External chat connectors](../architecture/external-chat-providers.md). ## The models diff --git a/docs/architecture/external-chat-providers.md b/docs/architecture/external-chat-providers.md index 3581379349..d88552119a 100644 --- a/docs/architecture/external-chat-providers.md +++ b/docs/architecture/external-chat-providers.md @@ -15,13 +15,13 @@ Supported providers: - `microsoft-teams` - `discord` -Supported bridge modes are `openclaw`, `webhook`, and `native_bridge`. Provider setup schemas describe the executable bridge shape for future runtime adapters: +Supported bridge modes are `managed_bridge`, `webhook`, and `native_bridge`. Provider setup schemas describe the executable bridge shape for future runtime adapters: -- WhatsApp: OpenClaw plugin or webhook. -- iMessage: OpenClaw core or macOS native bridge command. -- Telegram: OpenClaw core or bot webhook. -- Slack: OpenClaw plugin or Events webhook. -- Microsoft Teams: OpenClaw plugin or bot webhook. +- WhatsApp: managed bridge or webhook. +- iMessage: managed bridge or macOS native bridge command. +- Telegram: managed bridge or bot webhook. +- Slack: managed bridge or Events webhook. +- Microsoft Teams: managed bridge or bot webhook. - Discord: bot/webhook gateway. Public records expose redacted credential metadata only. Runtime code that needs secrets must call the explicit internal repository read path. @@ -85,7 +85,7 @@ The outbound runtime builds one delivery payload per persisted reply with: Bridge execution is isolated behind `src/services/chat-provider-adapters.ts`: -- `openclaw`: HTTP `POST` to a configured OpenClaw bridge URL such as `openclawBridgeUrl`, using bridge credentials as transport headers. +- `managed_bridge`: HTTP `POST` to a configured managed bridge URL such as `bridgeUrl`, using bridge credentials as transport headers. - `webhook`: HTTP `POST` to configured generic bridge URLs such as `webhookUrl`, `eventsUrl`, `botEndpointUrl`, or `gatewayUrl`. - `native_bridge`: local command execution for macOS/iMessage-style bridge scripts. The payload is written as JSON on stdin, commands are parsed into executable plus arguments without shell interpretation, and optional bridge tokens are supplied through environment variables. @@ -124,7 +124,7 @@ Dashboard settings use `src/server/chat-provider-routes.ts` to manage chat provi ## Dashboard Settings UI -Settings -> Integrations includes a Providers group for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Each provider detail view reads the setup definitions, redacted connection records, channel bindings, generated ingress URLs, and outbound delivery status from the dashboard API. +Settings -> Integrations includes a Chat Connectors group for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Each provider detail view reads the setup definitions, redacted connection records, channel bindings, generated ingress URLs, and outbound delivery status from the dashboard API. The UI lets operators create and edit provider connections with display names, bridge modes, setup fields, enabled state, connection status, and write-only secret replacement fields. Saved secrets are never rendered back into the form; configured credentials appear only as redacted metadata and empty replacement inputs. @@ -132,7 +132,7 @@ Channel binding controls support multiple projects on the same external channel Provider cards and connection detail views surface enabled state, bridge mode, ingress URL, authentication status, configured channels, bound projects, outbound reply state, pending outbound delivery count, and failed outbound delivery count. Recent failed outbound messages are shown with retryable labels and redacted error text. -The ingress endpoint supports OpenClaw, webhook, and native bridge payloads for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. OpenClaw and native bridges authenticate with bearer tokens from the configured bridge secret. Webhook bridges require a configured signing secret and a valid HMAC signature; they do not accept bearer-only fallback. All ingress requests require a fresh timestamp, and signed requests or requests with explicit nonces are replay-checked before processing. +The ingress endpoint supports Managed, webhook, and native bridge payloads for WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, and Discord. Managed and native bridges authenticate with bearer tokens from the configured bridge secret. Webhook bridges require a configured signing secret and a valid HMAC signature; they do not accept bearer-only fallback. All ingress requests require a fresh timestamp, and signed requests or requests with explicit nonces are replay-checked before processing. Inbound messages normalize to provider connection id, provider kind, external channel id/name, external sender id/name, text, external message id, timestamp, and redacted raw metadata. The repository idempotency lookup runs before chat posting; duplicate external messages return the existing delivery record without creating another conversation message. diff --git a/docs/architecture/repository-map.md b/docs/architecture/repository-map.md index 48c2d9082f..a93d6dc9b3 100644 --- a/docs/architecture/repository-map.md +++ b/docs/architecture/repository-map.md @@ -64,7 +64,7 @@ backup files appear there. - `project-runtime/run-event-writes.ts` - Focused write module for legacy runtime status-sync task runs and task-run events, including candidate run matching, status-sync event signatures, denormalized `task_run_events.project_id`, and source event key deduplication. - `chat-provider-repository.ts` - - External chat provider connections, channel bindings, inbound message idempotency, and outbound delivery state. + - External chat connector connections, channel bindings, inbound message idempotency, and outbound delivery state. - `settings-repository.ts` - `settings-defaults.ts` - `settings-sanitizer.ts` diff --git a/docs/mcp/tools-and-contracts.md b/docs/mcp/tools-and-contracts.md index 0dce469a90..b2291d790f 100644 --- a/docs/mcp/tools-and-contracts.md +++ b/docs/mcp/tools-and-contracts.md @@ -756,7 +756,7 @@ For preview calls: For external chat provider calls: - `manage_chat_providers` supports `list_provider_definitions`, `list_connections`, `get_connection`, `create_connection`, `update_connection`, `delete_connection`, `list_channel_bindings`, `create_channel_binding`, `update_channel_binding`, `delete_channel_binding`, and `list_outbound_deliveries`. -- Supported provider kinds are `whatsapp`, `imessage`, `telegram`, `slack`, `microsoft-teams`, and `discord`, delivered through the implemented `openclaw`, `webhook`, or `native_bridge` bridge contracts. The tool does not claim direct official API integration with those providers. +- Supported provider kinds are `whatsapp`, `imessage`, `telegram`, `slack`, `microsoft-teams`, and `discord`, delivered through the implemented `managed_bridge`, `webhook`, or `native_bridge` bridge contracts. The tool does not claim direct official API integration with those providers. - Connection responses return redacted credential metadata and generated ingress URL guidance; raw `secrets` are not exposed in success responses, validation errors, or approval envelopes. - `delete_connection` and `delete_channel_binding` require approval confirmation. - `update_connection` requires a one-use approval handshake before replacing a non-empty `secrets` payload. The preflight response is bound to a redacted payload plus secret hash and does not echo secret values. diff --git a/docs/settings/chat-provider-integrations.md b/docs/settings/chat-provider-integrations.md index a5d3760faa..431e8203df 100644 --- a/docs/settings/chat-provider-integrations.md +++ b/docs/settings/chat-provider-integrations.md @@ -1,6 +1,6 @@ # Chat Provider Integrations -External chat provider integrations let Code UX accept messages from chat channels, route them into project chat threads, and deliver assistant replies back through the same bridge. These integrations are configured under Settings -> Providers, but they are separate from AI provider credentials and model routing. +External chat connector integrations let Code UX accept messages from chat channels, route them into project chat threads, and deliver assistant replies back through the same bridge. These integrations are configured under Settings -> Integrations -> Chat Connectors, but they are separate from AI provider credentials and model routing. ## Supported Providers And Bridge Modes @@ -8,27 +8,27 @@ Code UX supports external chat channels through the bridge contracts implemented | Provider kind | Supported bridge modes | | --- | --- | -| `whatsapp` | OpenClaw plugin, webhook | -| `imessage` | OpenClaw core, native bridge command | -| `telegram` | OpenClaw core, bot webhook | -| `slack` | OpenClaw plugin, Events webhook | -| `microsoft-teams` | OpenClaw plugin, bot webhook | +| `whatsapp` | managed bridge, webhook | +| `imessage` | managed bridge, native bridge command | +| `telegram` | managed bridge, bot webhook | +| `slack` | managed bridge, Events webhook | +| `microsoft-teams` | managed bridge, bot webhook | | `discord` | bot/webhook gateway | -These provider labels describe the normalized payloads Code UX can accept and the bridge setup schemas it exposes. Code UX does not call WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, or Discord APIs directly. A bridge, webhook gateway, OpenClaw integration, or native command owns provider-specific API interaction. +These connector labels describe the normalized payloads Code UX can accept and the bridge setup schemas it exposes. Code UX does not call WhatsApp, iMessage, Telegram, Slack, Microsoft Teams, or Discord APIs directly. A managed bridge, webhook gateway, or native command owns provider-specific API interaction. Bridge modes: -- `openclaw`: HTTP delivery to a configured OpenClaw bridge URL, with OpenClaw credentials used as bridge transport credentials. +- `managed_bridge`: HTTP delivery to a configured managed bridge URL, with bridge credentials used as transport credentials. - `webhook`: HTTP delivery to a configured generic gateway URL such as `webhookUrl`, `eventsUrl`, `botEndpointUrl`, or `gatewayUrl`. - `native_bridge`: local command execution for native bridge scripts. Code UX writes JSON to stdin, parses the configured command into executable and arguments without shell interpretation, and passes an optional bridge token through the environment. ## Setup Model -Settings -> Providers contains two related but separate configuration families: +Settings -> Integrations contains related but separate configuration families: - AI provider credentials and model routing configure CLI or hosted providers that do Code UX work, such as Codex, Gemini, Claude Code, Qwen Code, OpenCode, Antigravity, and Jules. -- Chat provider connections configure external chat ingress, project/channel binding, and outbound reply delivery. +- Chat connector connections configure external chat ingress, project/channel binding, and outbound reply delivery. Chat provider connections are stored in the Code UX SQLite database. Each connection records provider kind, bridge mode, display name, enabled state, status, non-secret setup fields, and secret fields. Public dashboard and MCP reads return redacted credential metadata only; runtime services that need raw secrets use an explicit internal repository path. @@ -38,9 +38,9 @@ Saved secret fields are write-only in the dashboard. To rotate a secret, enter a Inbound chat provider requests are accepted on the dashboard server and must authenticate before routing: -- OpenClaw and native bridge modes use bearer-style bridge credentials. The request can use an `Authorization: Bearer ...` header, `x-code-ux-bridge-token`, or `x-openclaw-token`. +- Managed and native bridge modes use bearer-style bridge credentials. The request can use an `Authorization: Bearer ...` header or `x-code-ux-bridge-token`. - Webhook mode requires a configured HMAC signing secret and a valid signature. Webhook mode does not fall back to bearer-only authentication. -- Every inbound request needs a fresh timestamp header such as `x-code-ux-timestamp`, `x-openclaw-timestamp`, `x-provider-timestamp`, or `x-slack-request-timestamp`. +- Every inbound request needs a fresh timestamp header such as `x-code-ux-timestamp`, `x-provider-timestamp`, or `x-slack-request-timestamp`. - Signed requests and bearer requests with explicit nonce/request-id headers are replay-checked during the timestamp window. The primary ingress endpoint is: @@ -103,7 +103,7 @@ Outbound states: - `retryable_failure`: a network, HTTP, or native bridge failure will be retried after `delivery.nextAttemptAt`. - `failed`: delivery is terminal because routing is disabled, bridge setup is missing, the bridge returned a non-retryable error, or retry attempts were exhausted. -The dashboard lifecycle starts the retry loop. Failed and retryable deliveries are visible through Settings -> Providers delivery status views and through MCP `manage_chat_providers` inspection. Error text and payload metadata are redacted before being returned through dashboard or MCP reads. +The dashboard lifecycle starts the retry loop. Failed and retryable deliveries are visible through Settings -> Integrations -> Chat Connectors delivery status views and through MCP `manage_chat_providers` inspection. Error text and payload metadata are redacted before being returned through dashboard or MCP reads. ## Rich Widget Suppression diff --git a/docs/settings/subcategories/provider-integration.md b/docs/settings/subcategories/provider-integration.md index 2db30780db..54fc40cb33 100644 --- a/docs/settings/subcategories/provider-integration.md +++ b/docs/settings/subcategories/provider-integration.md @@ -1,18 +1,18 @@ # Provider Integration -Explains that AI provider credentials are system-owned while project scopes still control routing and auth-copy behavior. External chat provider connections also appear under Settings -> Providers, but they use a separate chat-provider runtime path for ingress, channel binding, and outbound reply delivery. +Explains that AI provider credentials are system-owned while project scopes still control routing and auth-copy behavior. External chat connector connections appear under Settings -> Integrations -> Chat Connectors, but they use a separate chat-provider runtime path for ingress, channel binding, and outbound reply delivery. ## What It Controls -The notices clarify where AI provider instances live, which settings remain project-scoped, and why chat provider connections are configured beside provider credentials without participating in AI model routing. +The notices clarify where AI provider instances live, which settings remain project-scoped, and why chat connector connections are configured beside provider credentials without participating in AI model routing. ## Recommended Defaults -Switch to system scope to add AI provider credentials, then route them from AI Models. Configure chat provider connections from the provider integration cards only when an external chat bridge is ready to send authenticated ingress. +Switch to system scope to add AI provider credentials, then route them from AI Models. Configure chat connector connections from the provider integration cards only when an external chat bridge is ready to send authenticated ingress. ## Risks And Gotchas -Expecting project scope to create AI provider credentials can leave routes without provider instances. Expecting chat provider credentials to affect AI routing can also be misleading: chat provider connections bind external channels to projects, while AI provider credentials decide which model runs Code UX work. +Expecting project scope to create AI provider credentials can leave routes without provider instances. Expecting chat provider credentials to affect AI routing can also be misleading: chat connector connections bind external channels to projects, while AI provider credentials decide which model runs Code UX work. ## Dashboard Link diff --git a/src/contracts/chat-provider-types.ts b/src/contracts/chat-provider-types.ts index acf51b9743..093245abf7 100644 --- a/src/contracts/chat-provider-types.ts +++ b/src/contracts/chat-provider-types.ts @@ -6,7 +6,7 @@ export type ChatProviderKind = | "microsoft-teams" | "discord"; -export type ChatProviderBridgeMode = "openclaw" | "webhook" | "native_bridge"; +export type ChatProviderBridgeMode = "managed_bridge" | "webhook" | "native_bridge"; export type ChatProviderConnectionStatus = | "draft" @@ -34,8 +34,8 @@ export type ChatProviderSetupFieldType = | "select"; export type ChatProviderBridgeIntegration = - | "openclaw_core" - | "openclaw_plugin" + | "managed_core" + | "managed_plugin" | "webhook" | "native_bridge" | "bot_gateway"; @@ -218,18 +218,18 @@ export const CHAT_PROVIDER_SETUP_SCHEMAS: readonly ChatProviderSetupSchema[] = [ { kind: "whatsapp", label: "WhatsApp", - defaultBridgeMode: "openclaw", + defaultBridgeMode: "managed_bridge", bridgeModes: [ { - mode: "openclaw", - label: "OpenClaw WhatsApp plugin", - integration: "openclaw_plugin", + mode: "managed_bridge", + label: "Managed WhatsApp bridge", + integration: "managed_plugin", setupFields: [ { key: "pluginName", label: "Plugin name", type: "string", required: true, defaultValue: "whatsapp" }, - { key: "workspaceId", label: "OpenClaw workspace", type: "string", required: false }, + { key: "workspaceId", label: "Connector workspace", type: "string", required: false }, ], secretFields: [ - { key: "openclawApiKey", label: "OpenClaw API key", required: true }, + { key: "bridgeApiKey", label: "Bridge API key", required: true }, ], }, { @@ -250,18 +250,18 @@ export const CHAT_PROVIDER_SETUP_SCHEMAS: readonly ChatProviderSetupSchema[] = [ { kind: "imessage", label: "iMessage", - defaultBridgeMode: "openclaw", + defaultBridgeMode: "managed_bridge", bridgeModes: [ { - mode: "openclaw", - label: "OpenClaw iMessage core", - integration: "openclaw_core", + mode: "managed_bridge", + label: "Managed iMessage bridge", + integration: "managed_core", setupFields: [ - { key: "workspaceId", label: "OpenClaw workspace", type: "string", required: false }, + { key: "workspaceId", label: "Connector workspace", type: "string", required: false }, { key: "deviceLabel", label: "Device label", type: "string", required: false }, ], secretFields: [ - { key: "openclawApiKey", label: "OpenClaw API key", required: true }, + { key: "bridgeApiKey", label: "Bridge API key", required: true }, ], }, { @@ -281,18 +281,18 @@ export const CHAT_PROVIDER_SETUP_SCHEMAS: readonly ChatProviderSetupSchema[] = [ { kind: "telegram", label: "Telegram", - defaultBridgeMode: "openclaw", + defaultBridgeMode: "managed_bridge", bridgeModes: [ { - mode: "openclaw", - label: "OpenClaw Telegram core", - integration: "openclaw_core", + mode: "managed_bridge", + label: "Managed Telegram bridge", + integration: "managed_core", setupFields: [ - { key: "workspaceId", label: "OpenClaw workspace", type: "string", required: false }, + { key: "workspaceId", label: "Connector workspace", type: "string", required: false }, { key: "botUsername", label: "Bot username", type: "string", required: false }, ], secretFields: [ - { key: "openclawApiKey", label: "OpenClaw API key", required: true }, + { key: "bridgeApiKey", label: "Bridge API key", required: true }, ], }, { @@ -313,18 +313,18 @@ export const CHAT_PROVIDER_SETUP_SCHEMAS: readonly ChatProviderSetupSchema[] = [ { kind: "slack", label: "Slack", - defaultBridgeMode: "openclaw", + defaultBridgeMode: "managed_bridge", bridgeModes: [ { - mode: "openclaw", - label: "OpenClaw Slack plugin", - integration: "openclaw_plugin", + mode: "managed_bridge", + label: "Managed Slack bridge", + integration: "managed_plugin", setupFields: [ { key: "pluginName", label: "Plugin name", type: "string", required: true, defaultValue: "slack" }, - { key: "workspaceId", label: "OpenClaw workspace", type: "string", required: false }, + { key: "workspaceId", label: "Connector workspace", type: "string", required: false }, ], secretFields: [ - { key: "openclawApiKey", label: "OpenClaw API key", required: true }, + { key: "bridgeApiKey", label: "Bridge API key", required: true }, ], }, { @@ -345,18 +345,18 @@ export const CHAT_PROVIDER_SETUP_SCHEMAS: readonly ChatProviderSetupSchema[] = [ { kind: "microsoft-teams", label: "Microsoft Teams", - defaultBridgeMode: "openclaw", + defaultBridgeMode: "managed_bridge", bridgeModes: [ { - mode: "openclaw", - label: "OpenClaw Teams plugin", - integration: "openclaw_plugin", + mode: "managed_bridge", + label: "Managed Teams bridge", + integration: "managed_plugin", setupFields: [ { key: "pluginName", label: "Plugin name", type: "string", required: true, defaultValue: "microsoft-teams" }, { key: "tenantId", label: "Tenant ID", type: "string", required: false }, ], secretFields: [ - { key: "openclawApiKey", label: "OpenClaw API key", required: true }, + { key: "bridgeApiKey", label: "Bridge API key", required: true }, ], }, { diff --git a/src/contracts/mcp-tool-definitions.ts b/src/contracts/mcp-tool-definitions.ts index aad858630a..4627853496 100644 --- a/src/contracts/mcp-tool-definitions.ts +++ b/src/contracts/mcp-tool-definitions.ts @@ -481,7 +481,7 @@ export const TOOL_DEFINITIONS = [ providerConnectionId: { type: "string", description: "Provider connection id. Required for get_connection, update_connection, delete_connection, and binding creation." }, connectionId: { type: "string", description: "Alias for providerConnectionId." }, displayName: { type: "string", description: "Connection display name. Required for create_connection and optional for update_connection." }, - bridgeMode: { type: "string", enum: ["openclaw", "webhook", "native_bridge"], description: "Optional provider bridge mode." }, + bridgeMode: { type: "string", enum: ["managed_bridge", "webhook", "native_bridge"], description: "Optional provider bridge mode." }, status: { type: "string", enum: ["draft", "active", "disabled", "error"], description: "Optional provider connection status for create_connection and update_connection." }, enabled: { type: "boolean", description: "Optional enabled flag for connection or binding mutations." }, enabledOnly: { type: "boolean", description: "Optional list filter that returns only enabled connections or bindings." }, diff --git a/src/mcp/management/chat-provider-actions.ts b/src/mcp/management/chat-provider-actions.ts index 28bcfb79f4..a1cf1fc564 100644 --- a/src/mcp/management/chat-provider-actions.ts +++ b/src/mcp/management/chat-provider-actions.ts @@ -45,7 +45,7 @@ const PROVIDER_KINDS: readonly ChatProviderKind[] = [ "discord", ]; -const BRIDGE_MODES: readonly ChatProviderBridgeMode[] = ["openclaw", "webhook", "native_bridge"]; +const BRIDGE_MODES: readonly ChatProviderBridgeMode[] = ["managed_bridge", "webhook", "native_bridge"]; const CONNECTION_STATUSES: readonly ChatProviderConnectionStatus[] = ["draft", "active", "disabled", "error"]; const DELIVERY_STATUSES: readonly ChatProviderDeliveryStatus[] = [ "pending", diff --git a/src/services/chat-provider-adapters.ts b/src/services/chat-provider-adapters.ts index 497328889c..b743736376 100644 --- a/src/services/chat-provider-adapters.ts +++ b/src/services/chat-provider-adapters.ts @@ -60,8 +60,8 @@ export function createDefaultChatProviderOutboundAdapter(): ChatProviderOutbound export class ConfiguredChatProviderOutboundAdapter implements ChatProviderOutboundAdapter { async send(context: ChatProviderOutboundAdapterContext): Promise { switch (context.connection.bridgeMode) { - case "openclaw": - return this.sendHttp(context, resolveOpenClawUrl(context.connection.setup), "openclaw"); + case "managed_bridge": + return this.sendHttp(context, resolveManagedUrl(context.connection.setup), "managed_bridge"); case "webhook": return this.sendHttp(context, resolveWebhookUrl(context.connection.setup), "webhook"); case "native_bridge": @@ -74,7 +74,7 @@ export class ConfiguredChatProviderOutboundAdapter implements ChatProviderOutbou private async sendHttp( context: ChatProviderOutboundAdapterContext, url: string, - mode: "openclaw" | "webhook", + mode: "managed_bridge" | "webhook", ): Promise { const normalizedUrl = requireHttpUrl(url, `${mode} bridge URL`); const headers: Record = { @@ -84,7 +84,7 @@ export class ConfiguredChatProviderOutboundAdapter implements ChatProviderOutbou "x-codeux-bridge-mode": context.connection.bridgeMode, }; const bearer = getFirstSecret(context.connection.secrets, [ - "openclawApiKey", + "bridgeApiKey", "bridgeToken", "botToken", "webhookSecret", @@ -148,10 +148,8 @@ export class ConfiguredChatProviderOutboundAdapter implements ChatProviderOutbou } } -function resolveOpenClawUrl(setup: Record): string { +function resolveManagedUrl(setup: Record): string { return getString( - setup.openclawBridgeUrl, - setup.openclawUrl, setup.bridgeUrl, setup.outboundUrl, setup.endpointUrl, diff --git a/src/services/chat-provider-security.ts b/src/services/chat-provider-security.ts index c06a11580c..47ef20fe65 100644 --- a/src/services/chat-provider-security.ts +++ b/src/services/chat-provider-security.ts @@ -44,7 +44,6 @@ export class ChatProviderIngressSecurity { const timestamp = this.requireFreshTimestamp(request.headers, nowMs); const signature = firstHeader(request.headers, [ "x-code-ux-signature", - "x-openclaw-signature", "x-hub-signature-256", "x-slack-signature", "x-signature", @@ -71,7 +70,7 @@ export class ChatProviderIngressSecurity { const expectedBearer = firstConfiguredSecret( connection.secrets, - connection.bridgeMode === "native_bridge" ? ["bridgeToken"] : ["openclawApiKey"], + connection.bridgeMode === "native_bridge" ? ["bridgeToken"] : ["bridgeApiKey"], ); if (!expectedBearer) { throw new ChatProviderIngressSecurityError("missing_bridge_secret", "Chat provider bridge secret is not configured.", 403); @@ -82,7 +81,7 @@ export class ChatProviderIngressSecurity { throw new ChatProviderIngressSecurityError("invalid_bearer_token", "Invalid chat provider bridge token.", 401); } - const nonce = firstHeader(request.headers, ["x-code-ux-nonce", "x-openclaw-nonce", "x-request-id"]); + const nonce = firstHeader(request.headers, ["x-code-ux-nonce", "x-request-id"]); if (nonce) { this.preventReplay({ connectionId: connection.id, @@ -96,7 +95,6 @@ export class ChatProviderIngressSecurity { private requireFreshTimestamp(headers: Record, nowMs: number): { raw: string; value: number } { const rawTimestamp = firstHeader(headers, [ "x-code-ux-timestamp", - "x-openclaw-timestamp", "x-provider-timestamp", "x-slack-request-timestamp", ]); @@ -176,7 +174,7 @@ export class ChatProviderIngressSecurity { function parseBearerToken(headers: Record): string | null { const authorization = firstHeader(headers, ["authorization"]); const match = authorization?.match(/^Bearer\s+(.+)$/i); - return match?.[1]?.trim() || firstHeader(headers, ["x-code-ux-bridge-token", "x-openclaw-token"]) || null; + return match?.[1]?.trim() || firstHeader(headers, ["x-code-ux-bridge-token"]) || null; } function firstConfiguredSecret(secrets: ChatProviderSecretConfig | null, keys: string[]): string | null { diff --git a/tests/backend/mcp/management-chat-provider-actions.test.ts b/tests/backend/mcp/management-chat-provider-actions.test.ts index b1b2cdc4fd..7e73c2df59 100644 --- a/tests/backend/mcp/management-chat-provider-actions.test.ts +++ b/tests/backend/mcp/management-chat-provider-actions.test.ts @@ -67,7 +67,7 @@ describe("ChatProviderActions", () => { expect(definitions).toHaveLength(1); expect(definitions[0]).toMatchObject({ kind: "slack", - defaultBridgeMode: "openclaw", + defaultBridgeMode: "managed_bridge", setupGuidance: { providerKind: "slack", ingressUrlTemplate: "https://codeux.example.test/api/chat-providers/{providerConnectionId}/channels/{externalChannelId}/ingress", diff --git a/tests/backend/server/chat-provider-ingress-routes.test.ts b/tests/backend/server/chat-provider-ingress-routes.test.ts index b5122ac8d8..14976436f4 100644 --- a/tests/backend/server/chat-provider-ingress-routes.test.ts +++ b/tests/backend/server/chat-provider-ingress-routes.test.ts @@ -46,9 +46,9 @@ describe("chat provider ingress routes", () => { const connection = context.chatProviderRepository.createConnection({ providerKind: "slack", displayName: "Slack bridge", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", status: "active", - secrets: { openclawApiKey: "bridge-token" }, + secrets: { bridgeApiKey: "bridge-token" }, }); context.chatProviderRepository.createChannelBinding({ providerConnectionId: connection.id, @@ -148,9 +148,9 @@ describe("chat provider ingress routes", () => { const connection = context.chatProviderRepository.createConnection({ providerKind: "slack", displayName: "Slack bridge", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", status: "active", - secrets: { openclawApiKey: "bridge-token" }, + secrets: { bridgeApiKey: "bridge-token" }, }); context.chatProviderRepository.createChannelBinding({ providerConnectionId: connection.id, @@ -183,9 +183,9 @@ describe("chat provider ingress routes", () => { const connection = context.chatProviderRepository.createConnection({ providerKind: "telegram", displayName: "Telegram gateway", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", status: "active", - secrets: { openclawApiKey: "telegram-token" }, + secrets: { bridgeApiKey: "telegram-token" }, }); for (const project of [projectA, projectB]) { context.chatProviderRepository.createChannelBinding({ diff --git a/tests/backend/server/chat-provider-routes.test.ts b/tests/backend/server/chat-provider-routes.test.ts index 7281d6eaac..27353ffe63 100644 --- a/tests/backend/server/chat-provider-routes.test.ts +++ b/tests/backend/server/chat-provider-routes.test.ts @@ -54,9 +54,9 @@ describe("chat provider dashboard routes", () => { ])); const slack = body.providers.find((provider: any) => provider.kind === "slack"); expect(slack.bridgeModes[0].setupHints).toMatchObject({ - integration: "openclaw_plugin", + integration: "managed_plugin", requiredSetupFields: ["pluginName"], - requiredSecretFields: ["openclawApiKey"], + requiredSecretFields: ["bridgeApiKey"], }); }); @@ -69,9 +69,9 @@ describe("chat provider dashboard routes", () => { body: JSON.stringify({ providerKind: "slack", displayName: "Operations Slack", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", setup: { pluginName: "slack" }, - secrets: { openclawApiKey: "raw-secret-token" }, + secrets: { bridgeApiKey: "raw-secret-token" }, }), }); @@ -81,17 +81,17 @@ describe("chat provider dashboard routes", () => { expect(created).toMatchObject({ providerKind: "slack", displayName: "Operations Slack", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", ingressUrl: `${context.baseUrl}/api/chat-providers/ingress/${created.id}`, credentials: [ expect.objectContaining({ - key: "openclawApiKey", + key: "bridgeApiKey", configured: true, redactedValue: "********", }), ], setupHints: expect.objectContaining({ - requiredSecretFields: ["openclawApiKey"], + requiredSecretFields: ["bridgeApiKey"], }), }); @@ -111,7 +111,7 @@ describe("chat provider dashboard routes", () => { body: JSON.stringify({ displayName: "Support Slack", enabled: false, - secrets: { openclawApiKey: "new-raw-secret" }, + secrets: { bridgeApiKey: "new-raw-secret" }, }), }); expect(updateResponse.status).toBe(200); @@ -141,21 +141,21 @@ describe("chat provider dashboard routes", () => { await expectValidationFailure(context, { providerKind: "discord", displayName: "Bad bridge", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", }, "unsupported_bridge_mode"); await expectValidationFailure(context, { providerKind: "slack", displayName: "Bad setup", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", setup: { unsupported: "value" }, }, "unsupported_setup_field"); await expectValidationFailure(context, { providerKind: "slack", displayName: "Bad secret", - bridgeMode: "openclaw", - secrets: { openclawApiKey: 123 }, + bridgeMode: "managed_bridge", + secrets: { bridgeApiKey: 123 }, }, "invalid_secret"); }); @@ -164,7 +164,7 @@ describe("chat provider dashboard routes", () => { const connection = context.chatProviderRepository.createConnection({ providerKind: "slack", displayName: "Team Slack", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", setup: { pluginName: "slack" }, }); const projectA = createProject(context, "project-a"); @@ -231,7 +231,7 @@ describe("chat provider dashboard routes", () => { const connection = context.chatProviderRepository.createConnection({ providerKind: "slack", displayName: "Team Slack", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", }); const missingProject = await createBinding(context, { @@ -276,7 +276,7 @@ describe("chat provider dashboard routes", () => { const connection = context.chatProviderRepository.createConnection({ providerKind: "slack", displayName: "Delivery Slack", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", }); const binding = context.chatProviderRepository.createChannelBinding({ providerConnectionId: connection.id, diff --git a/tests/backend/services/chat-provider-ingress-service.test.ts b/tests/backend/services/chat-provider-ingress-service.test.ts index 37273be11c..f07a6ad2e2 100644 --- a/tests/backend/services/chat-provider-ingress-service.test.ts +++ b/tests/backend/services/chat-provider-ingress-service.test.ts @@ -37,9 +37,9 @@ describe("ChatProviderIngressService", () => { const connection = context.providerRepository.createConnection({ providerKind: "slack", displayName: "Slack ingress", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", status: "active", - secrets: { openclawApiKey: "bridge-token" }, + secrets: { bridgeApiKey: "bridge-token" }, }); const bindingA = context.providerRepository.createChannelBinding({ providerConnectionId: connection.id, diff --git a/tests/backend/services/chat-provider-outbound-service.test.ts b/tests/backend/services/chat-provider-outbound-service.test.ts index 6b6332c85f..ff59991257 100644 --- a/tests/backend/services/chat-provider-outbound-service.test.ts +++ b/tests/backend/services/chat-provider-outbound-service.test.ts @@ -122,17 +122,17 @@ describe("ChatProviderOutboundService", () => { expect(JSON.stringify(delivery?.payload)).not.toContain("response-secret-token"); }); - it("uses OpenClaw bridge URLs without provider SDK dependencies", async () => { + it("uses Managed bridge URLs without provider SDK dependencies", async () => { const context = await createContext(); const bridge = await startJsonBridge((_req, res) => { res.writeHead(200, { "content-type": "application/json" }); - res.end(JSON.stringify({ messageId: "telegram-openclaw-1" })); + res.end(JSON.stringify({ messageId: "telegram-managed_bridge-1" })); }); const fixture = await createOutboundFixture(context, { - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", providerKind: "telegram", - setup: { openclawBridgeUrl: bridge.url }, - secrets: { openclawApiKey: "openclaw-secret" }, + setup: { bridgeUrl: bridge.url }, + secrets: { bridgeApiKey: "managed_bridge-secret" }, }); const service = new ChatProviderOutboundService({ chatProviderRepository: context.providerRepository }); @@ -140,7 +140,7 @@ describe("ChatProviderOutboundService", () => { expect(delivery).toMatchObject({ status: "delivered", - externalMessageId: "telegram-openclaw-1", + externalMessageId: "telegram-managed_bridge-1", }); }); @@ -289,7 +289,7 @@ async function createContext(): Promise<{ async function createOutboundFixture( context: Awaited>, options: { - bridgeMode: "openclaw" | "webhook" | "native_bridge"; + bridgeMode: "managed_bridge" | "webhook" | "native_bridge"; providerKind: "telegram" | "discord" | "imessage"; setup: Record; secrets: Record; diff --git a/tests/dashboard/lib/chat-provider-view-models.test.ts b/tests/dashboard/lib/chat-provider-view-models.test.ts index 4b02792c25..2a8bede533 100644 --- a/tests/dashboard/lib/chat-provider-view-models.test.ts +++ b/tests/dashboard/lib/chat-provider-view-models.test.ts @@ -16,19 +16,19 @@ import { const definition: DashboardChatProviderSetupDefinition = { kind: "slack", label: "Slack", - defaultBridgeMode: "openclaw", + defaultBridgeMode: "managed_bridge", ingressUrlTemplate: "http://localhost/api/chat-providers/ingress/{connectionId}", bridgeModes: [ { - mode: "openclaw", - label: "OpenClaw Slack plugin", - integration: "openclaw_plugin", + mode: "managed_bridge", + label: "Managed Slack bridge", + integration: "managed_plugin", setupFields: [ { key: "pluginName", label: "Plugin name", type: "string", required: true, defaultValue: "slack" }, { key: "workspaceId", label: "Workspace", type: "string", required: false }, ], secretFields: [ - { key: "openclawApiKey", label: "OpenClaw API key", required: true }, + { key: "bridgeApiKey", label: "Bridge API key", required: true }, ], }, ], @@ -38,19 +38,19 @@ const connection: DashboardChatProviderConnectionRecord = { id: "conn-1", providerKind: "slack", displayName: "Slack Bridge", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", status: "active", enabled: true, setup: { pluginName: "slack" }, credentials: [ - { key: "openclawApiKey", label: "OpenClaw API key", configured: true, redactedValue: "••••••••" }, + { key: "bridgeApiKey", label: "Bridge API key", configured: true, redactedValue: "••••••••" }, ], ingressUrl: "http://localhost/api/chat-providers/ingress/conn-1", setupHints: { - bridgeModeLabel: "OpenClaw Slack plugin", - integration: "openclaw_plugin", + bridgeModeLabel: "Managed Slack bridge", + integration: "managed_plugin", requiredSetupFields: ["pluginName"], - requiredSecretFields: ["openclawApiKey"], + requiredSecretFields: ["bridgeApiKey"], }, createdAt: "2026-01-01T00:00:00.000Z", updatedAt: "2026-01-01T00:00:00.000Z", @@ -124,7 +124,7 @@ describe("chat provider view models", () => { }); it("creates default setup and redacts common credential patterns", () => { - expect(createDefaultSetupForBridge(definition, "openclaw")).toEqual({ pluginName: "slack" }); + expect(createDefaultSetupForBridge(definition, "managed_bridge")).toEqual({ pluginName: "slack" }); expect(redactChatProviderError("token=abc123 secret: super-secret password=hunter2")).toBe("token=[redacted] secret: [redacted] password=[redacted]"); }); }); diff --git a/tests/dashboard/lib/settings-search-index.test.ts b/tests/dashboard/lib/settings-search-index.test.ts index 4c75b2c871..b6d296624b 100644 --- a/tests/dashboard/lib/settings-search-index.test.ts +++ b/tests/dashboard/lib/settings-search-index.test.ts @@ -76,7 +76,7 @@ describe("settings search index", () => { ["imessage", ["integrations"]], ["chat provider", ["integrations"]], ["channel binding", ["integrations"]], - ["openclaw", ["integrations"]], + ["managed_bridge", ["integrations"]], ["webhook", ["integrations"]], ["native bridge", ["integrations"]], ["model", ["models"]], diff --git a/tests/dashboard/v2/settings-chat-providers-panel.test.tsx b/tests/dashboard/v2/settings-chat-providers-panel.test.tsx index 505cee9001..3c73103178 100644 --- a/tests/dashboard/v2/settings-chat-providers-panel.test.tsx +++ b/tests/dashboard/v2/settings-chat-providers-panel.test.tsx @@ -56,18 +56,18 @@ const providerDefinitions: DashboardChatProviderSetupDefinition[] = [ ].map((kind) => ({ kind: kind as ChatProviderKind, label: kind === "microsoft-teams" ? "Microsoft Teams" : kind === "imessage" ? "iMessage" : kind.charAt(0).toUpperCase() + kind.slice(1), - defaultBridgeMode: kind === "discord" ? "webhook" : "openclaw", + defaultBridgeMode: kind === "discord" ? "webhook" : "managed_bridge", ingressUrlTemplate: "http://localhost/api/chat-providers/ingress/{connectionId}", bridgeModes: [ { - mode: "openclaw", - label: "OpenClaw bridge", - integration: "openclaw_core", + mode: "managed_bridge", + label: "Managed bridge", + integration: "managed_core", setupFields: [ - { key: "workspaceId", label: "OpenClaw workspace", type: "string", required: false }, + { key: "workspaceId", label: "Connector workspace", type: "string", required: false }, ], secretFields: [ - { key: "openclawApiKey", label: "OpenClaw API key", required: true }, + { key: "bridgeApiKey", label: "Bridge API key", required: true }, ], }, { @@ -88,19 +88,19 @@ const slackConnection: DashboardChatProviderConnectionRecord = { id: "conn-slack", providerKind: "slack", displayName: "Slack Bridge", - bridgeMode: "openclaw", + bridgeMode: "managed_bridge", status: "active", enabled: true, setup: { workspaceId: "workspace-1" }, credentials: [ - { key: "openclawApiKey", label: "OpenClaw API key", configured: true, redactedValue: "••••••••" }, + { key: "bridgeApiKey", label: "Bridge API key", configured: true, redactedValue: "••••••••" }, ], ingressUrl: "http://localhost/api/chat-providers/ingress/conn-slack", setupHints: { - bridgeModeLabel: "OpenClaw bridge", - integration: "openclaw_core", + bridgeModeLabel: "Managed bridge", + integration: "managed_core", requiredSetupFields: [], - requiredSecretFields: ["openclawApiKey"], + requiredSecretFields: ["bridgeApiKey"], }, createdAt: "2026-01-01T00:00:00.000Z", updatedAt: "2026-01-01T00:00:00.000Z", @@ -209,16 +209,16 @@ const createState = (selectedIntegration: string | null) => ({ }, }); -describe("SettingsIntegrationsPanel chat providers", () => { +describe("SettingsIntegrationsPanel chat connectors", () => { afterEach(() => { cleanup(); }); - it("surfaces all chat providers in the Providers integration group", async () => { + it("surfaces all chat connectors in the Chat Connectors integration group", async () => { const state = createState(null); render(); - await waitFor(() => expect(screen.getByText("PROVIDERS")).not.toBeNull()); + await waitFor(() => expect(screen.getByText("CHAT CONNECTORS")).not.toBeNull()); for (const label of ["WhatsApp", "iMessage", "Telegram", "Slack", "Microsoft Teams", "Discord"]) { expect(screen.getByText(label)).not.toBeNull(); } @@ -231,12 +231,12 @@ describe("SettingsIntegrationsPanel chat providers", () => { const state = createState("slack"); render(); - await waitFor(() => expect(screen.getByText("Slack Provider")).not.toBeNull()); + await waitFor(() => expect(screen.getByText("Slack Connector")).not.toBeNull()); expect(screen.getByText("Slack setup guidance")).not.toBeNull(); expect((screen.getByLabelText("Slack Bridge display name") as HTMLInputElement).value).toBe("Slack Bridge"); expect(screen.getByRole("radiogroup", { name: "Slack Bridge bridge mode" })).not.toBeNull(); expect((screen.getByLabelText("Slack Bridge ingress URL") as HTMLInputElement).value).toBe("http://localhost/api/chat-providers/ingress/conn-slack"); - expect((screen.getByLabelText("Slack Bridge OpenClaw API key") as HTMLInputElement).value).toBe(""); + expect((screen.getByLabelText("Slack Bridge Bridge API key") as HTMLInputElement).value).toBe(""); expect(screen.getByText(/configured\. Enter a replacement only when rotating it\./i)).not.toBeNull(); expect(screen.getByText("Shared-channel routing")).not.toBeNull();