diff --git a/apps/docs/adapters.json b/apps/docs/adapters.json index 5743e97e0..0eb6caf10 100644 --- a/apps/docs/adapters.json +++ b/apps/docs/adapters.json @@ -105,7 +105,7 @@ "type": "platform", "description": "Hold encrypted 1:1 and group conversations on XChat with all cryptography handled inside the adapter.", "packageName": "@chat-adapter/x", - "icon": "x", + "icon": "xchat", "beta": true, "readme": "https://github.com/vercel/chat/tree/main/packages/adapter-x" }, diff --git a/apps/docs/app/[lang]/adapters/components/adapter-card.tsx b/apps/docs/app/[lang]/adapters/components/adapter-card.tsx index 96eede96e..c47075b8f 100644 --- a/apps/docs/app/[lang]/adapters/components/adapter-card.tsx +++ b/apps/docs/app/[lang]/adapters/components/adapter-card.tsx @@ -25,6 +25,7 @@ import { web, whatsapp, x, + xchat, } from "@/lib/logos"; const iconMap: Record< @@ -47,6 +48,7 @@ const iconMap: Record< twilio, messenger, x, + xchat, }; interface AdapterCardProps { diff --git a/apps/docs/components/geistdocs/adapter-hero.tsx b/apps/docs/components/geistdocs/adapter-hero.tsx index ae6b9277d..4e8707416 100644 --- a/apps/docs/components/geistdocs/adapter-hero.tsx +++ b/apps/docs/components/geistdocs/adapter-hero.tsx @@ -15,6 +15,7 @@ import { web, whatsapp, x, + xchat, } from "@/lib/logos"; const ICON_MAP: Record< @@ -37,6 +38,7 @@ const ICON_MAP: Record< twilio, messenger, x, + xchat, }; interface AdapterHeroProps { diff --git a/apps/docs/content/adapters/official/og/xchat.png b/apps/docs/content/adapters/official/og/xchat.png index ec5b054f1..b3509a88f 100644 Binary files a/apps/docs/content/adapters/official/og/xchat.png and b/apps/docs/content/adapters/official/og/xchat.png differ diff --git a/apps/docs/content/adapters/official/x.mdx b/apps/docs/content/adapters/official/x.mdx index 5b58897aa..bbb1be1e9 100644 --- a/apps/docs/content/adapters/official/x.mdx +++ b/apps/docs/content/adapters/official/x.mdx @@ -101,6 +101,25 @@ export async function POST(request: Request) { } ``` +## X Adapter vs XChat Adapter + +Both adapters ship from [`@chat-adapter/x`](https://www.npmjs.com/package/@chat-adapter/x), but they target different X surfaces and use different factories. + +Use this **X** adapter (`createXAdapter` from `@chat-adapter/x`) when you want: + +- Public timeline mentions and replies (`post.mention.create`) +- Classic (unencrypted) direct messages +- Posting from the bot account to the public timeline (`x:public`) +- Likes as reactions + +Use the [**XChat** adapter](/adapters/official/xchat) (`createXchatAdapter` from `@chat-adapter/x/chat`) when you want: + +- Encrypted XChat 1:1 and group conversations +- Typing indicators, read receipts, and emoji reactions +- Crypto handled inside the adapter (Juicebox PIN, key exchange, signed messages) + +You can register both adapters on the same `Chat` instance if your bot needs public posts/DMs and encrypted XChat. + ## Configuration ) => ( ); + +export const xchat = (props: ComponentProps<"svg">) => ( + + + +); diff --git a/packages/adapter-x/README.md b/packages/adapter-x/README.md index 639b78f5e..9c86bd0b8 100644 --- a/packages/adapter-x/README.md +++ b/packages/adapter-x/README.md @@ -248,7 +248,7 @@ export async function POST(request: Request) { When using `createXchatAdapter()` without arguments, credentials are auto-detected from environment variables. The bot's @handle is resolved from `GET /2/users/me` at startup, so mention detection works without any hardcoding. -### X Chat setup +### XChat setup ### 1. Register encryption keys @@ -369,7 +369,7 @@ X_VERIFY_SIGNATURES=true # Optional; set false to accept unverifiable | Post cards | Yes (first `x.com/.../status/...` URL in outgoing text auto-attaches) | | Media out | Yes (files encrypt-streamed and uploaded via the 3-step media upload flow) | | Media in | Yes (attachments exposed with lazy download + decrypt via `fetchData()`) | -| Cards / buttons / modals | No (X Chat has no interactive message surface) | +| Cards / buttons / modals | No (XChat has no interactive message surface) | | Tables | ASCII code blocks | ### Conversations diff --git a/packages/adapter-x/src/chat/index.ts b/packages/adapter-x/src/chat/index.ts index 44cdb6679..414a08777 100644 --- a/packages/adapter-x/src/chat/index.ts +++ b/packages/adapter-x/src/chat/index.ts @@ -1955,7 +1955,7 @@ export class XchatAdapter implements Adapter { ); } - // Resolve to a unicode emoji (X Chat reactions are unicode). The shared + // Resolve to a unicode emoji (XChat reactions are unicode). The shared // resolver's Google Chat profile is its plain-unicode output, so it is // the right conversion here despite the name. const unicodeEmoji = defaultEmojiResolver.toGChat(emoji); @@ -2146,7 +2146,7 @@ export class XchatAdapter implements Adapter { /** * Send a typing indicator and keep re-sending it every few seconds until - * the next postMessage in this conversation (or a safety timeout). X Chat + * the next postMessage in this conversation (or a safety timeout). XChat * typing pills expire quickly, so a single POST is invisible during a * longer generation. */