diff --git a/packages/plugins-ui/src/index.ts b/packages/plugins-ui/src/index.ts index 3c0781b36..04c7a9fc2 100644 --- a/packages/plugins-ui/src/index.ts +++ b/packages/plugins-ui/src/index.ts @@ -9,6 +9,8 @@ export { PluginConnectPanel } from "./plugin-connect-panel"; export { McpServersSection } from "./mcp-servers-section"; export { McpPresetCardsSection } from "./mcp-preset-cards"; +export { PLUGINS_STRINGS } from "./strings"; + export { McpServersApiError, listMcpServers, diff --git a/packages/plugins-ui/src/mcp-preset-cards.tsx b/packages/plugins-ui/src/mcp-preset-cards.tsx index 676de13dd..80e47b84f 100644 --- a/packages/plugins-ui/src/mcp-preset-cards.tsx +++ b/packages/plugins-ui/src/mcp-preset-cards.tsx @@ -15,6 +15,7 @@ import { type McpPreset, } from "./mcp-servers-api"; import { PluginLogo } from "./plugin-logo"; +import { PLUGINS_STRINGS } from "./strings"; function messageOf(cause: unknown): string { return cause instanceof Error ? cause.message : String(cause); @@ -27,8 +28,7 @@ const MCP_OAUTH_ERROR_COPY: Readonly> = { state_expired: "The connection took too long or was already used. Try connecting again.", state_mismatch: "The connection was interrupted. Try connecting again.", - exchange_failed: - "That app didn't hand back a token. Try connecting again.", + exchange_failed: "That app didn't hand back a token. Try connecting again.", connect_failed: "Couldn't finish connecting. Try connecting again.", setup_failed: "The sign-in worked, but storing the connection failed. Try connecting again.", @@ -101,7 +101,7 @@ function McpPresetCard({ toast(`${preset.displayName} disconnected.`); onChanged(); }) - .catch(() => setError("Couldn't disconnect — try again.")) + .catch(() => setError(PLUGINS_STRINGS.disconnectError)) .finally(() => setBusy(false)); } diff --git a/packages/plugins-ui/src/mcp-servers-section.tsx b/packages/plugins-ui/src/mcp-servers-section.tsx index d6f6827c2..f1f385e9a 100644 --- a/packages/plugins-ui/src/mcp-servers-section.tsx +++ b/packages/plugins-ui/src/mcp-servers-section.tsx @@ -18,6 +18,7 @@ import { listMcpServers, type McpServer, } from "./mcp-servers-api"; +import { PLUGINS_STRINGS } from "./strings"; function messageOf(cause: unknown): string { return cause instanceof Error ? cause.message : String(cause); @@ -43,7 +44,7 @@ function ConnectedMcpServerRow({ toast(`${server.name} disconnected.`); onChanged(); }) - .catch(() => setError("Couldn't disconnect — try again.")) + .catch(() => setError(PLUGINS_STRINGS.disconnectError)) .finally(() => setBusy(false)); } diff --git a/packages/plugins-ui/src/plugin-connect-panel.tsx b/packages/plugins-ui/src/plugin-connect-panel.tsx index 68320ab20..13b112b4d 100644 --- a/packages/plugins-ui/src/plugin-connect-panel.tsx +++ b/packages/plugins-ui/src/plugin-connect-panel.tsx @@ -37,6 +37,7 @@ import type { ResolvedPlugin } from "@workbench/connections/plugins"; import { useEffect, useState } from "react"; import { pluginOutcome } from "./plugin-meta"; +import { PLUGINS_STRINGS } from "./strings"; const PLUGINS_RETURN_PATH = "/plugins"; @@ -142,7 +143,7 @@ function ConnectedSummary({ toast(`${plugin.descriptor.displayName} disconnected.`); onChanged(); }) - .catch(() => setError("Couldn't disconnect — try again.")) + .catch(() => setError(PLUGINS_STRINGS.disconnectError)) .finally(() => setBusy(false)); } diff --git a/packages/plugins-ui/src/strings.ts b/packages/plugins-ui/src/strings.ts new file mode 100644 index 000000000..d5bef00ea --- /dev/null +++ b/packages/plugins-ui/src/strings.ts @@ -0,0 +1,6 @@ +// Every user-facing word the plugins surface prints, in one place. Nothing +// in the plugins-ui/* components inlines its own copy; it imports from here. + +export const PLUGINS_STRINGS = { + disconnectError: "Couldn't disconnect — try again.", +} as const; diff --git a/packages/plugins-ui/test/mcp-preset-cards.test.tsx b/packages/plugins-ui/test/mcp-preset-cards.test.tsx index 6ceee5ac4..52f78222f 100644 --- a/packages/plugins-ui/test/mcp-preset-cards.test.tsx +++ b/packages/plugins-ui/test/mcp-preset-cards.test.tsx @@ -132,7 +132,10 @@ describe("McpPresetCardsSection", () => { Object.defineProperty(window.location, "href", { configurable: true, get() { - return hrefDescriptor?.get?.call(window.location) ?? "https://workbench.test/"; + return ( + hrefDescriptor?.get?.call(window.location) ?? + "https://workbench.test/" + ); }, set(value: string) { assigned.push(value); diff --git a/packages/plugins-ui/test/plugin-connect-panel.test.tsx b/packages/plugins-ui/test/plugin-connect-panel.test.tsx index 2f866faca..993541c3c 100644 --- a/packages/plugins-ui/test/plugin-connect-panel.test.tsx +++ b/packages/plugins-ui/test/plugin-connect-panel.test.tsx @@ -13,6 +13,7 @@ import type { ConnectorDescriptor } from "@workbench/connections/registry"; import type { ResolvedPlugin } from "@workbench/connections/plugins"; import { PluginConnectPanel } from "../src/plugin-connect-panel"; +import { PLUGINS_STRINGS } from "../src/strings"; const realFetch = globalThis.fetch; let mountedRoots: Root[] = []; @@ -169,7 +170,7 @@ describe("PluginConnectPanel", () => { }); await settle(); - expect(container.textContent).toContain("Couldn't disconnect"); + expect(container.textContent).toContain(PLUGINS_STRINGS.disconnectError); }); function githubDescriptor(): ConnectorDescriptor {