mirror of
https://github.com/vercel/chat.git
synced 2026-09-14 18:32:29 +08:00
@chat-adapter/messenger@4.31.0
432 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2a553aa948 |
chore(release): version packages (#600)
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @chat-adapter/slack@4.31.0 ### Minor Changes - |
||
|
|
8c7141174a |
feat(teams): add low-level primitives (#593)
Add Teams subpath exports for custom runtimes, including Bot Connector API helpers, Graph reads, parse-only webhooks, format helpers, Adaptive Cards, and Task Module primitives. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
a8bf99ab19 |
fix(adapter-slack): don't rewrite @handles inside URL paths as mentions (#618)
## Problem `linkBareMentionNames` (in `markdown.ts`) rewrites any bare `@word` into a `<@word>` Slack mention. Its lookbehind `(?<![<\w])@(\w+)` excludes `<` and word characters, but **not `/`** — so an `@handle` inside a URL path gets rewritten, corrupting the link: ``` See https://hackmd.io/@jkyang/B1W69XA-fe → See https://hackmd.io/<@jkyang>/B1W69XA-fe ❌ (Slack renders a broken mention; link dead) ``` This affects common `@handle` URLs (HackMD `/@user`, Mastodon `/@user`, Medium `/@user`, …). It reproduces on `main` via `toSlackPayload` for both the plain `text` and the native `markdown_text` paths, because `finalize()` runs the regex over the whole string. (The `renderPostable({ markdown })` AST path is unaffected — bare URLs become link nodes there — which is likely why it's gone unnoticed.) This is the same class of bug as the email fix in #394, which tuned this same regex; URL paths are the sibling case it didn't cover. ## Fix Add `/` to the negative lookbehind so a handle preceded by a path separator is left intact: ```diff -const BARE_MENTION_PATTERN = /(?<![<\w])@(\w+)/g; +const BARE_MENTION_PATTERN = /(?<![<\w/])@(\w+)/g; ``` Whitespace-/punctuation-led mentions (`(cc @george)`), emails (`user@example.com`), and `<mailto:…>` links are unaffected. ## Tests Two cases added to the `mentions` suite (plain string + markdown). Verified against current `main`: - **Without the fix:** both new tests fail (e.g. `…/@user` → `…/<@user>`). - **With the fix:** full `markdown.test.ts` suite passes (28/28). Changeset included (`patch`). --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
8f3af76565 |
feat: add create-chat-sdk CLI (#603)
Adds `create-chat-sdk`, a CLI that scaffolds a Next.js Chat SDK bot project: ```bash npm create chat-sdk@latest my-bot # non-interactive npm create chat-sdk@latest -- my-bot --adapter slack redis -y ``` The user picks platform and state adapters interactively or via `--adapter`, and the CLI generates a webhook-only project with `src/lib/bot.ts`, `.env.example`, `next.config.ts`, `package.json`, and a README, then optionally runs `git init` and installs dependencies. There are no pages or client UI in the template. Adapter choices come straight from the `chat/adapters` catalog, so the CLI has no adapter registry of its own. When a coding agent such as Cursor or Claude Code runs the CLI, it uses non-interactive defaults and requires an explicit platform adapter. `--interactive` forces prompts. ## also in this pr - `google-chat` is renamed to `gchat` everywhere, including docs pages, the OG image, and adapter catalog. Old URLs redirect permanently, including language-prefixed and `/og` paths - a new docs page is available at `chat-sdk.dev/docs/create-chat-sdk`, and the CLI is promoted on the homepage, package READMEs, and agent skill - `create-chat-sdk` releases independently with a minor changeset for its initial `0.1.0` release --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
4662309fe3 |
feat(telegram): support native rich messages (#616)
## summary adds native rich message support for Telegram Bot API 10.1 explicit markdown and AST messages now use `sendRichMessage`, edits use rich message payloads, and private chat streams use `sendRichMessageDraft` before persisting the completed response preserves existing behavior for plain strings, raw messages, cards, media captions, and older or custom Bot API servers through automatic fallback adds typed inbound rich message parsing, rich message limits, regression coverage, and updated adapter documentation |
||
|
|
8336a3e818 |
feat(slack): expose webClientOptions to configure the underlying WebClient (#602)
## summary adds `webClientOptions` to `SlackAdapterConfig` so users can configure the underlying Slack `WebClient` instances the options apply to both the default client and per-token clients used for multi-workspace requests, including settings such as `retryConfig`, per-request `timeout`, custom headers, and `rejectRateLimitedCalls` `slackApiUrl` is intentionally excluded from `webClientOptions` because the existing `apiUrl` option remains the single configuration path for overriding the Slack Web API base URL custom headers are cloned for each client because the Slack SDK adds authorization to the provided headers object, preventing credentials from leaking between token-bound clients --------- Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
9c936f8796 |
feat(telegram): support slash commands (#586)
## Summary Adds Telegram bot command support for Chat SDK slash command handlers. - Routes Telegram `/command` and `/command@botusername` messages to `bot.onSlashCommand` - Ignores commands addressed to another bot - Keeps non-command messages on the existing normal message path ## Test plan - `pnpm validate` - Tested locally against a real Telegram bot ## Checklist - [x] All commits are signed and verified - [x] `pnpm validate` passes - [x] Changeset added - [x] Documentation updated --------- Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
b14114a714 |
test(slack): expand emulator coverage for emulate.dev 0.6.0 APIs (#591)
Upgrade @emulators/* to 0.6.0 and add integration tests for DMs, reactions, fetch history, modals, scheduled messages, file uploads, member joins, and bookmarks against the in-process Slack emulator. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
778ae69abc |
add zero-dependency chat/adapters for adapters catalog (#599)
Adapter Catalog: - Adds a zero-dependency `chat/adapters` subpath for official and vendor-official adapter metadata. - Includes typed catalog entries, env specs, peer dependency metadata, and helper APIs for setup and onboarding flows. - Wires the subpath into the `chat` package export map and build config. Code Coverage: - Adds unit coverage for catalog integrity, registry sync, helper behavior, official env declarations, and peer dependency derivation. - Extends docs integration coverage for `chat/adapters` imports and vendor-official package install metadata. Documentation: - Documents the new catalog on the adapter overview page. - Splits platform-specific adapter guidance into a new `/docs/platform-adapters` page. - Renames `/docs/state` to `/docs/state-adapters` and adds a redirect for the old slug. Agent Guidance: - Updates repo-local and public agent guidance so agents know when and how to use `chat/adapters`. - Adds focused `AGENTS.md` guidance inside `packages/chat/src/adapters` for future catalog maintenance. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
171657a019 |
[chat] adding stable id to link button action handlers (#598)
Enabling overriding the `link:<url>` action ID for `LinkButton` events. |
||
|
|
7ecb9730e3 |
chore(docs): add missing Twilio logo and add official platform adapter OG images (#589)
Adds official platform adapter branding across the docs site, npm
READMEs, and social previews.
- **Homepage**: add Twilio to the supported-platforms logo grid
- **OG images**: add custom artwork for all 11 official platform
adapters under content/adapters/official/og/; serve static-first from
the existing /adapters/official/{slug}/og route with dynamic fallback
for state adapters
- **READMEs**: add linked hero banners to every official platform
adapter package README, using the live OG URL as the single image source
- **Tests**: integration-test guardrails for OG image coverage, README
banner discoverability, and knip-clean helpers
- **Changeset**: empty changeset for CI
<img width="2400" height="1256" alt="Chat SDK - Slack"
src="https://github.com/user-attachments/assets/4d186a1c-5651-44b8-8698-091ee23b44da"
/>
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
|
||
|
|
9921dcd1c4 |
docs(seo): improve npm metadata, README discoverability, and structured data (#587)
Improves Chat SDK discoverability across npm, READMEs, and the docs site for search engines and AI coding agents. - **npm metadata**: point every published package `homepage` at chat-sdk.dev deep links; expand `chat` keywords/description; fix `repository.directory` (`packages/chat-sdk` → `packages/chat`); align state adapter keywords - **READMEs**: add npm callouts, Documentation/Guides links, and AI Coding Agents sections (skill install, optional Vercel Plugin, `llms.txt` / `llms-full.txt`) across all published packages and the repo root - **docs JSON-LD**: `HowTo` / `TechArticle` on getting-started, streaming, and cards; `CollectionPage` + official-only `ItemList` on `/adapters` (with split human vs JSON-LD descriptions) - **UTMs**: add `chat-sdk_site` / `chat-sdk_repo` tracking params to Resources links in selected MDX pages and adapter READMEs (discord, github, slack, liveblocks, getting-started, ai index) - **contract tests**: integration-tests guardrails for npm metadata and README discoverability so future package additions don't drift --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
c290464634 |
docs(adapters): promote Sendblue to vendor-official adapter (#584)
Moves the Sendblue adapter from community to vendor-official in the docs site now that Sendblue maintains `chat-adapter-sendblue`. - package: `chat-adapter-sendblue` - repo: https://github.com/sendblue-api/chat-adapter-sendblue - docs: https://docs.sendblue.com/guides/chat-sdk-adapter/ Updates the adapter registry and hand-authored detail page (iMessage, SMS, RCS, `sb-signing-secret` webhook verification, official Sendblue guide links). Reorders vendor-official adapters so Liveblocks, Resend, Sendblue, and Zernio appear first. Adds a permanent redirect from `/adapters/community/sendblue`. Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
2fb8ad29cf |
docs(adapters): add Kapso WhatsApp adapter (#577)
## Summary Adds [Kapso WhatsApp](https://docs.kapso.ai/) as a vendor-official adapter in `adapters.json`. Kapso is a WhatsApp adapter for Chat SDK that receives signed Kapso webhooks, replies through Chat SDK threads, and supports WhatsApp-native messaging features: - **Text messages** — send and receive WhatsApp messages via Kapso - **Buttons/cards** — Chat SDK card buttons render as WhatsApp reply buttons - **Media** — send and receive images, video, audio, documents, and stickers - **Reactions** — add/remove reactions and handle inbound reaction events - **History** — fetch Kapso-backed message, contact, and conversation metadata - **Webhook verification** — validates Kapso `X-Webhook-Signature` deliveries | Feature | Support | | --- | --- | | Send/receive text | Yes | | Reply buttons | Yes, up to 3 | | CTA URL buttons | Yes | | Media attachments | Yes | | Reactions | Yes | | Message history | Yes | - **Docs**: [docs.kapso.ai](https://docs.kapso.ai/) - **npm**: [`@kapso/chat-adapter`](https://www.npmjs.com/package/@kapso/chat-adapter) - **GitHub**: [`gokapso/chat-sdk-adapter`](https://github.com/gokapso/chat-sdk-adapter) - **Blog**: https://kapso.ai/blog/chat-sdk-adapter |
||
|
|
f40c4d4840 |
docs(chat): clarify isMe semantics for adapter authors (#582)
## summary clarifies that `author.isMe` means the message was sent by the current bot runtime and should be filtered from handler dispatch documents that adapters backed by user-owned accounts should not map platform fields like `fromMe` directly to `isMe` recommends tracking message ids returned by `postMessage` so webhook echoes can be identified without filtering legitimate user-authored messages |
||
|
|
9b99ee2d2d |
fix(docs): allow Velt adapter examples (#575)
## summary fixes the release-blocking docs validation failures from the Velt vendor-official adapter page this updates the docs integration-test allowlists so `velt` is an expected vendor-official adapter slug and `@veltdev/chat-sdk-adapter` is accepted in docs code examples no changeset needed because this only updates test expectations for existing docs content |
||
|
|
a5b118f1dc |
chore(release): version packages (#546)
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @chat-adapter/slack@4.30.0 ### Minor Changes - |
||
|
|
b63c042ca1 |
fix(slack): resolve reaction user display names (#523)
## Summary Fixes Slack reaction events so `event.user.userName` and `event.user.fullName` are resolved from Slack user profile data instead of always being the raw Slack user ID. This reuses the Slack adapter's existing cached `lookupUser()` path and falls back to the user ID when lookup fails. Fixes #521 |
||
|
|
073ff920a1 |
fix(slack): return uploaded file ids from postMessage (#574)
## summary fixes #564 preserves Slack `files.uploadV2` confirmation IDs on `postMessage` results when a message includes uploaded files file-only Slack posts now keep the existing synthetic raw payload and add `uploadedFileIds`, while text/card posts with files augment the normal `chat.postMessage` raw response with the same IDs this lets callers confirm which files Slack accepted without replacing existing `raw` data |
||
|
|
999d268de1 |
fix(slack): pass token through native stream stop (#573)
## summary fixes #570 fixes Slack native streaming when the stream reaches `stop()` before a token-bearing append has flushed `SlackAdapter.stream()` now passes the resolved bot token on every `streamer.append()` and on `streamer.stop()`, matching Slack's auth requirements and avoiding `not_authed` responses from `chat.startStream` / `chat.stopStream` adds regression coverage for buffered markdown streams and repeated structured chunk appends |
||
|
|
5a72259fbc |
feat(docs): improve LLM/search discoverability of docs (#566)
SEO/AEO improvements for the docs site: - Append `| Chat SDK` to every page's `<title>` and `og:title` (home stays `Chat SDK`). - Expose a plain-markdown version of every docs and adapter page via an `sr-only` AI/LLM hint link and a `text/markdown` alternate; adapter pages get a new `/adapters/<group>/<slug>.md` endpoint. - Turn `llms.txt` into a sitemap-style index linking to each page's markdown, and move the full-text concatenation to `llms-full.txt`. A `<link rel="llms-txt">` is added to every page. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
6750dda955 |
docs: use stable Teams CLI package (#568)
## Summary - Updates Teams setup docs to install `@microsoft/teams.cli` instead of the old `@preview` tag. ## Why - Teams CLI is stable now, so the docs should point folks at the stable package. Nice and tidy. ## Interesting bits - This touches both the public docs page and the adapter README so they don't disagree. ## Test plan - Not run; docs-only change. |
||
|
|
ffc43fcf1f |
feat(whatsapp-adapter): Add typing indicator support (#320)
## Summary Adds typing indicator support for WhatsApp and also bumps the API version to the latest v25.0. > Good to know: There is a limitation with typing indicator API: it has a 25-second cooldown and rqeuires a recent incoming message. This means if you try to display the typing indicator before the cooldown period has passed, it won’t show up, but the message will still be marked with a red check mark. ## Test plan Verified end-to-end on a real WhatsApp Business profile --------- Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
293356525d |
feat: docs: add Lark / Feishu adapter (#517)
## Summary Adds [`@larksuite/vercel-chat-adapter`](https://www.npmjs.com/package/@larksuite/vercel-chat-adapter), the Lark / Feishu adapter for Chat SDK, as a **vendor-official community adapter**. - **Package**: `@larksuite/vercel-chat-adapter` — published on npm under the official `larksuite` scope - **Built on**: [`@larksuiteoapi/node-sdk`](https://www.npmjs.com/package/@larksuiteoapi/node-sdk)'s `LarkChannel`, the official Lark Node SDK - **Docs source**: external README referenced by `adapters.json` lives in [`larksuite/node-sdk`](https://github.com/larksuite/node-sdk/tree/cbc4adf13cbcb93b389db01faf428e3b3cef053c/docs/vercel-chat-adapter) (the official Lark vendor-owned GitHub org, pinned at commit `cbc4adf1`); the in-tree MDX in this PR is the rendered detail page (`mdxBody: true`) - **Capabilities**: native cardkit typewriter streaming, interactive cards, reactions, edit / delete, message history (via SDK `normalize()`), DM detection, mention handling, and scan-to-create app onboarding through `registerLarkApp` ## Changes | File | Change | |---|---| | `apps/docs/adapters.json` | Add Lark / Feishu entry (`community: true`, `vendorOfficial: true`) | | `apps/docs/content/adapters/vendor-official/lark.mdx` | New hand-authored MDX detail page (frontmatter with full features matrix, install / quick start / configuration / transport / streaming / ID encoding / history / safety / limitations / FeatureSupport) | | `apps/docs/content/adapters/vendor-official/meta.json` | Append `"lark"` to the sidebar `pages` array | | `packages/integration-tests/src/docs-adapters.test.ts` | Append `"lark"` to the hardcoded vendor-official slug list asserted by `Vendor-Official adapter MDX › contains exactly the expected adapters` | No icon registered in `adapters.json` / `iconMap` / `adapterLogos` — matches the existing pattern for vendor-official adapters (Beeper, Resend, Liveblocks, Zernio, Photon). ## Vendor Official tier Per `docs/contributing/building.mdx` (Qualifications for vendor official tier): - ✅ **Commitment for continued maintenance** — owned by the Lark / Feishu team - ✅ **GitHub hosting in official vendor-owned org** — adapter README lives in [`larksuite/node-sdk`](https://github.com/larksuite/node-sdk), the official Lark org - ✅ **Documentation in primary vendor docs** — will be cross-linked from the official Lark Open Platform developer documentation - ✅ **Announcement** — will be announced through Lark developer changelog / channels ## A note on source visibility The adapter source is not currently open-sourced due to internal release-process requirements. What is public: - The npm package itself (consumable by any user) - The README, hosted in `larksuite/node-sdk` (official Lark org) - The underlying [`@larksuiteoapi/node-sdk`](https://github.com/larksuite/node-sdk) on which it is built — this *is* fully open-source ## Test plan - [x] `pnpm --filter docs build` — docs app builds cleanly; `/en/adapters/vendor-official/lark` and `/en/adapters/vendor-official/lark/og` routes are generated - [x] `pnpm typecheck` — passes (33 tasks) - [x] `pnpm check` (Ultracite / Biome) — 438 files, no fixes - [x] `pnpm --filter @chat-adapter/integration-tests test docs-adapters` — 232 tests pass (frontmatter, vendor-official roster, adapters.json ↔ MDX sync) - [x] Manual: `/adapters` lists the Lark / Feishu card in the **Vendor Official** section; `/adapters/vendor-official/lark` renders the MDX detail page with the FeatureSupport matrix |
||
|
|
bd38498b60 |
docs(adapters): add AgentPhone as vendor-official adapter (#562)
## Summary Adds [AgentPhone](https://agentphone.to) as a vendor-official adapter in `adapters.json`. AgentPhone is the first Chat SDK adapter with unified support for **SMS, MMS, iMessage, and voice calls** in a single package: - **SMS/MMS** — send and receive via `agent.message` webhooks - **iMessage** — full support including tapback reactions (love, like, laugh, etc.) and expressive send styles - **Voice** — inbound/outbound call transcripts and summaries via `agent.call_ended` webhooks - **HMAC-SHA256** webhook verification with replay protection | | SMS | MMS | iMessage | Voice | |---|---|---|---|---| | Send messages | ✓ | ✓ | ✓ | — | | Receive messages | ✓ | ✓ | ✓ | — | | Media attachments | — | ✓ | ✓ | — | | Reactions | — | — | ✓ | — | | Call transcripts | — | — | — | ✓ | - **npm**: [`@agentphone/chat-sdk-adapter`](https://www.npmjs.com/package/@agentphone/chat-sdk-adapter) - **GitHub**: [`AgentPhone-AI/chat-sdk-adapter`](https://github.com/AgentPhone-AI/chat-sdk-adapter) - **Docs**: [docs.agentphone.ai](https://docs.agentphone.ai) |
||
|
|
9b8d8c4518 |
Discoverability lift: link KB guides, broaden npm keywords, mirror to AGENTS.md (#560)
Broad SEO/AEO pass across the docs site, adapter READMEs and AGENTS.md files, and npm package metadata so Chat SDK content shows up better in search engines, in LLM-driven package recommendations, and in IDE/coding-agent context. **Docs site** - Adds a `## Resources` section to the Getting Started and AI overview pages and to the Slack, Discord, GitHub, Liveblocks, and Sendblue adapter pages, each linking to applicable guides/templates with descriptions sourced from `resources-edge-config.json` and a cross-link back to the central `/resources` hub. **Adapter packages** - Mirrors the same Resources sections into the Slack, Discord, and GitHub READMEs (so they surface on npm) and into their AGENTS.md files (so coding agents see them alongside the API notes). - Expands `keywords` on every published adapter and state package — adds `chat-sdk`, `chatbot`, `ai-agent`, `ai-sdk`, `vercel`, plus platform-specific terms like `slack-bot`, `block-kit`, `slash-commands`, `github-app`, `whatsapp-business`, `state-adapter`. **Resources registry** - Registers four new entries in `resources-edge-config.json` (Human-in-the-Loop guide, Liveblocks AI agent guide, Slack + Vercel Blob guide, Durable iMessage Agent template) and runs `pnpm sync-resources` so the bundled `chat` package guides, `templates.json`, and `skills/chat/SKILL.md` all pick them up. - Fixes the synced Slack AI agent guide to import `toAiMessages` from `chat/ai` instead of the deprecated `chat` re-export path (the upstream KB source has also been updated, so future syncs will preserve this). **Drive-by fixes** - Resend adapter doc quick start: corrects `MemoryStateAdapter` class import to the `createMemoryState()` factory (matching every other adapter doc). - Zalo adapter doc: drops the "community adapter" callout that duplicated frontmatter. **Tooling / CI** - Adds `tsx` as a root devDependency so `pnpm sync-resources` works out of the box (it previously relied on `npx tsx`, which hung when not pre-cached). - Loosens the CI changeset gate to also skip `packages/chat/resources/` (generated data), matching the existing `*.md` carve-out. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
5461ea982b |
feat(telegram): add native DM draft streaming with segmented stream results (#340)
## Summary Add native Telegram DM streaming via `sendMessageDraft` while preserving Chat SDK's existing post+edit fallback for non-DM threads. This PR: - adds native private-chat draft streaming to the Telegram adapter - splits long streamed markdown into Telegram-safe persisted segments - retries without `parse_mode` when Telegram rejects markdown entity parsing - exposes segmented native stream results in the chat core - updates docs and feature matrices to reflect Telegram DM draft streaming --------- Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
6ed4a43897 |
feat(slack): add low-level interaction helpers (#559)
## summary adds lower-level Slack helpers for custom runtimes that already own routing, state, sessions, or workflow execution this expands the existing Slack subpaths with typed inbound files, richer interaction payload fields, thread reply fetching, modal opening, and generic input request Block Kit helpers it keeps the helpers on the existing `@chat-adapter/slack` package and preserves the runtime-light import boundary for `webhook`, `api`, and `blocks` |
||
|
|
177735a60f |
fix(gchat): collapse redundant autolink formatting for email links (#553)
## Description Fix redundant autolink rendering for email addresses in the Google Chat adapter. Previously, autolinked email addresses were rendered as `<mailto:...|...>` even when the visible text already matched the email address. This resulted in unnecessary verbose output. This change collapses such cases to plain text for cleaner and more consistent rendering. While testing, it was observed that `tel:` links are not currently generated from plain phone number inputs in the existing parsing pipeline. However, support for `tel:` handling has still been added in the implementation for future compatibility as referenced in the issue. <img width="757" height="107" alt="image" src="https://github.com/user-attachments/assets/a8ccfd6c-6669-4535-b733-5f2c185d9e2f" /> Additionally, new test cases have been added to cover email autolinks, labeled mailto links, and general markdown link behavior. ## Type of Change - [x] Bug fix (non-breaking change which fixes an issue) ## Related Issues Fixes #516 ## Changes Made - Collapsed redundant `mailto:` autolinks when visible text matches the email address - Added support for `tel:` scheme handling for future compatibility - Updated link rendering logic in Google Chat adapter markdown converter - Added and updated unit tests for email and link conversion cases ## Testing - [x] All existing tests pass - [x] Added new tests for the changes - [x] Manually tested the changes ### Test Coverage - Email autolink collapsing verified - Custom labeled mailto links verified - HTTP link formatting verified - Edge cases for link conversion verified via unit tests ## Screenshots/Demos N/A ## Checklist - [x] My code follows the project's code style - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings or errors - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [x] I have created a changeset (`pnpm changeset`) ## Changeset - [x] I have created a changeset for these changes ## Additional Notes During testing, `tel:` links were not observed in the current markdown parsing pipeline for plain phone numbers. However, support for `tel:` has been included to align with the issue description and for future-proofing the adapter behavior. --------- Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
25ebc3b925 |
feat(twilio): add sms, mms, and voice helpers (#558)
## summary adds a first-class Twilio adapter for SMS and MMS bots, plus low-level voice helpers for custom Twilio voice routes this includes webhook parsing and signature verification, outbound Messages API helpers, phone-number and Messaging Service sending, inbound MMS attachments with authenticated `fetchData`, plain text card fallback rendering, markdown conversion, and runtime-light `api`, `webhook`, `voice`, and `format` subpaths the adapter intentionally avoids the `twilio` npm runtime dependency so apps can use the low-level helpers without pulling in the full SDK |
||
|
|
0488a6613c |
docs(slack): document low-level api subpaths (#557)
## summary documents the low-level Slack subpaths for custom runtimes that own routing, state, sessions, or workflow execution covers `@chat-adapter/slack/webhook`, `@chat-adapter/slack/format`, `@chat-adapter/slack/api`, and `@chat-adapter/slack/blocks`, including when to use them instead of the full `createSlackAdapter` runtime also links the new guide from the Slack adapter page |
||
|
|
1294490755 |
refactor(slack): share provider helpers (#556)
## summary reuses the low-level Slack formatting helpers inside the high-level Slack adapter without changing adapter behavior this removes duplicated mrkdwn-to-markdown and markdown-bold conversion logic by sharing `slackMrkdwnToMarkdown`, `linkBareSlackMentions`, and `markdownBoldToSlackMrkdwn` across the format converter, card converter, and blocks subpath the low-level mention helper remains ID-based to match Slack docs, while the high-level adapter keeps its existing bare-name mention compatibility privately |
||
|
|
dbd8dc5b7c |
feat(slack): expose block kit helpers (#555)
## summary exposes a runtime-free `@chat-adapter/slack/blocks` subpath for converting Chat SDK-style card objects into Slack Block Kit blocks the new subpath includes typed card input shapes, fallback text helpers, Slack emoji placeholder conversion, and docs-backed Slack limits for headers, images, actions, select options, fields, and tables this keeps lower-level Slack rendering reusable without importing the full Slack adapter, `chat`, `@chat-adapter/shared`, or Slack SDK runtime packages |
||
|
|
aba6aa94fe |
feat(slack): add api primitives subpath (#548)
## summary adds `@chat-adapter/slack/api` for lightweight Slack Web API helpers the new subpath exposes fetch-based primitives for calling Slack Web API methods, posting and updating messages, sending response URL payloads, uploading files through Slack's external upload flow, and fetching private Slack file URLs with bearer auth it stays independent of the full Slack adapter runtime, Chat SDK runtime, Slack WebClient, Socket Mode, and shared adapter package, so lower-level runtimes can reuse Slack API correctness without adopting `createSlackAdapter` |
||
|
|
4c46c26c75 |
feat(slack): add format primitives subpath (#547)
## summary adds `@chat-adapter/slack/format` for lightweight Slack formatting helpers the new subpath exposes runtime-free primitives for Slack text objects, mrkdwn escaping, mentions, links, dates, and basic mrkdwn normalization without importing the full Slack adapter, Chat SDK runtime, Slack SDK, Socket Mode, or shared adapter package this keeps the normal `@chat-adapter/slack` adapter path unchanged while giving lower-level runtimes a small typed API for Slack formatting correctness |
||
|
|
b332a03d59 |
feat(slack): add webhook primitives subpath (#538)
## summary adds a lightweight `@chat-adapter/slack/webhook` subpath for lower-level Slack webhook handling without pulling in the full Slack adapter runtime this exposes primitives for verifying Slack requests, reading signed webhook bodies, parsing Events API callbacks, slash commands, and interactive payloads, and returning provider-native continuation data for message-like payloads this gives framework and infrastructure integrations a small Slack-owned surface they can use directly while keeping `chat`, Slack SDK clients, adapter state, dedupe, locks, and subscriptions out of the primitive path |
||
|
|
6581d31507 |
chore(release): version packages (#469)
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @chat-adapter/discord@4.29.0 ### Minor Changes - |
||
|
|
9d7891b2f5 |
fix(release): prevent accidental major bumps (#520)
## summary fixes the release plan so peer-dependent packages only trigger major bumps when the next dependency version falls outside their supported range this keeps the current release on `4.29.0` instead of accidentally bumping the fixed `chat` and `@chat-adapter/*` group to `5.0.0` also changes `@chat-adapter/tests` to use a real `chat` peer range while keeping `workspace:*` for local development |
||
|
|
9f7bbc8482 |
fix(web): exclude framework wrappers from coverage (#512)
## summary excludes the Web adapter React, Vue, and Svelte wrapper entry points from coverage collection these files are thin framework-specific `useChat` wrappers that are already validated by build and typecheck, and excluding them avoids Vitest coverage trying to parse the Svelte wrapper as plain TypeScript |
||
|
|
b93ffa78a1 |
build(deps-dev): bump svelte from 5.55.5 to 5.55.7 (#511)
Bumps [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) from 5.55.5 to 5.55.7. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/sveltejs/svelte/releases">svelte's releases</a>.</em></p> <blockquote> <h2>svelte@5.55.7</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: prevent XSS on <code>hydratable</code> from user contents (<a href="https://github.com/sveltejs/svelte/commit/a16ebc67bbcf8f708360195687e1b2719463e1a4"><code>a16ebc67bbcf8f708360195687e1b2719463e1a4</code></a>)</p> </li> <li> <p>chore: bump devalue (<a href="https://redirect.github.com/sveltejs/svelte/pull/18219">#18219</a>)</p> </li> <li> <p>fix: disallow empty attribute names during SSR (<a href="https://github.com/sveltejs/svelte/commit/547853e2406a2147ad7fb5ffeba95b01bd9642da"><code>547853e2406a2147ad7fb5ffeba95b01bd9642da</code></a>)</p> </li> <li> <p>fix: harden regex (<a href="https://github.com/sveltejs/svelte/commit/d2375e2ebcab5c88feb5652f1a9d621b8f06b259"><code>d2375e2ebcab5c88feb5652f1a9d621b8f06b259</code></a>)</p> </li> <li> <p>fix: move Svelte runtime properties to symbols (<a href="https://github.com/sveltejs/svelte/commit/e1cbbd96441e82c9eb8a23a2903c0d06d3cda991"><code>e1cbbd96441e82c9eb8a23a2903c0d06d3cda991</code></a>)</p> </li> </ul> <h2>svelte@5.55.6</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: leave stale promises to wait for a later resolution, instead of rejecting (<a href="https://redirect.github.com/sveltejs/svelte/pull/18180">#18180</a>)</p> </li> <li> <p>fix: keep dependencies of <code>$state.eager/pending</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/18218">#18218</a>)</p> </li> <li> <p>fix: reapply context after transforming error during SSR (<a href="https://redirect.github.com/sveltejs/svelte/pull/18099">#18099</a>)</p> </li> <li> <p>fix: don't rebase just-created batches (<a href="https://redirect.github.com/sveltejs/svelte/pull/18117">#18117</a>)</p> </li> <li> <p>chore: allow <code>null</code> for <code>pending</code> in typings (<a href="https://redirect.github.com/sveltejs/svelte/pull/18201">#18201</a>)</p> </li> <li> <p>fix: flush eager effects in production (<a href="https://redirect.github.com/sveltejs/svelte/pull/18107">#18107</a>)</p> </li> <li> <p>fix: rethrow error of failed iterable after calling <code>return()</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/18169">#18169</a>)</p> </li> <li> <p>fix: account for proxified instance when updating <code>bind:this</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/18147">#18147</a>)</p> </li> <li> <p>fix: ensure scheduled batch is flushed if not obsolete (<a href="https://redirect.github.com/sveltejs/svelte/pull/18131">#18131</a>)</p> </li> <li> <p>fix: resolve stale deriveds with latest value (<a href="https://redirect.github.com/sveltejs/svelte/pull/18167">#18167</a>)</p> </li> <li> <p>chore: remove unnecessary <code>increment_pending</code> calls (<a href="https://redirect.github.com/sveltejs/svelte/pull/18183">#18183</a>)</p> </li> <li> <p>fix: correctly compile component member expressions for SSR (<a href="https://redirect.github.com/sveltejs/svelte/pull/18192">#18192</a>)</p> </li> <li> <p>fix: reset <code>source.updated</code> stack traces after <code>flush</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/18196">#18196</a>)</p> </li> <li> <p>fix: replacing async 'blocking' strategy with 'merging' (<a href="https://redirect.github.com/sveltejs/svelte/pull/18205">#18205</a>)</p> </li> <li> <p>fix: allow <code>@debug</code> tags to reference awaited variables (<a href="https://redirect.github.com/sveltejs/svelte/pull/18138">#18138</a>)</p> </li> <li> <p>fix: re-run fallback props if dependencies update (<a href="https://redirect.github.com/sveltejs/svelte/pull/18146">#18146</a>)</p> </li> <li> <p>fix: abort running obsolete async branches (<a href="https://redirect.github.com/sveltejs/svelte/pull/18118">#18118</a>)</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md">svelte's changelog</a>.</em></p> <blockquote> <h2>5.55.7</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: prevent XSS on <code>hydratable</code> from user contents (<a href="https://github.com/sveltejs/svelte/commit/a16ebc67bbcf8f708360195687e1b2719463e1a4"><code>a16ebc67bbcf8f708360195687e1b2719463e1a4</code></a>)</p> </li> <li> <p>chore: bump devalue (<a href="https://redirect.github.com/sveltejs/svelte/pull/18219">#18219</a>)</p> </li> <li> <p>fix: disallow empty attribute names during SSR (<a href="https://github.com/sveltejs/svelte/commit/547853e2406a2147ad7fb5ffeba95b01bd9642da"><code>547853e2406a2147ad7fb5ffeba95b01bd9642da</code></a>)</p> </li> <li> <p>fix: harden regex (<a href="https://github.com/sveltejs/svelte/commit/d2375e2ebcab5c88feb5652f1a9d621b8f06b259"><code>d2375e2ebcab5c88feb5652f1a9d621b8f06b259</code></a>)</p> </li> <li> <p>fix: move Svelte runtime properties to symbols (<a href="https://github.com/sveltejs/svelte/commit/e1cbbd96441e82c9eb8a23a2903c0d06d3cda991"><code>e1cbbd96441e82c9eb8a23a2903c0d06d3cda991</code></a>)</p> </li> </ul> <h2>5.55.6</h2> <h3>Patch Changes</h3> <ul> <li> <p>fix: leave stale promises to wait for a later resolution, instead of rejecting (<a href="https://redirect.github.com/sveltejs/svelte/pull/18180">#18180</a>)</p> </li> <li> <p>fix: keep dependencies of <code>$state.eager/pending</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/18218">#18218</a>)</p> </li> <li> <p>fix: reapply context after transforming error during SSR (<a href="https://redirect.github.com/sveltejs/svelte/pull/18099">#18099</a>)</p> </li> <li> <p>fix: don't rebase just-created batches (<a href="https://redirect.github.com/sveltejs/svelte/pull/18117">#18117</a>)</p> </li> <li> <p>chore: allow <code>null</code> for <code>pending</code> in typings (<a href="https://redirect.github.com/sveltejs/svelte/pull/18201">#18201</a>)</p> </li> <li> <p>fix: flush eager effects in production (<a href="https://redirect.github.com/sveltejs/svelte/pull/18107">#18107</a>)</p> </li> <li> <p>fix: rethrow error of failed iterable after calling <code>return()</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/18169">#18169</a>)</p> </li> <li> <p>fix: account for proxified instance when updating <code>bind:this</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/18147">#18147</a>)</p> </li> <li> <p>fix: ensure scheduled batch is flushed if not obsolete (<a href="https://redirect.github.com/sveltejs/svelte/pull/18131">#18131</a>)</p> </li> <li> <p>fix: resolve stale deriveds with latest value (<a href="https://redirect.github.com/sveltejs/svelte/pull/18167">#18167</a>)</p> </li> <li> <p>chore: remove unnecessary <code>increment_pending</code> calls (<a href="https://redirect.github.com/sveltejs/svelte/pull/18183">#18183</a>)</p> </li> <li> <p>fix: correctly compile component member expressions for SSR (<a href="https://redirect.github.com/sveltejs/svelte/pull/18192">#18192</a>)</p> </li> <li> <p>fix: reset <code>source.updated</code> stack traces after <code>flush</code> (<a href="https://redirect.github.com/sveltejs/svelte/pull/18196">#18196</a>)</p> </li> <li> <p>fix: replacing async 'blocking' strategy with 'merging' (<a href="https://redirect.github.com/sveltejs/svelte/pull/18205">#18205</a>)</p> </li> <li> <p>fix: allow <code>@debug</code> tags to reference awaited variables (<a href="https://redirect.github.com/sveltejs/svelte/pull/18138">#18138</a>)</p> </li> <li> <p>fix: re-run fallback props if dependencies update (<a href="https://redirect.github.com/sveltejs/svelte/pull/18146">#18146</a>)</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/sveltejs/svelte/commit/4d8f99a2709e3c02e48d8bc6c77458f4ba49d0e3"><code>4d8f99a</code></a> Version Packages (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/18220">#18220</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/05523088173e10af0753877af6936088de924833"><code>0552308</code></a> chore: bump devalue (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/18219">#18219</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/e1cbbd96441e82c9eb8a23a2903c0d06d3cda991"><code>e1cbbd9</code></a> Merge commit from fork</li> <li><a href="https://github.com/sveltejs/svelte/commit/a16ebc67bbcf8f708360195687e1b2719463e1a4"><code>a16ebc6</code></a> Merge commit from fork</li> <li><a href="https://github.com/sveltejs/svelte/commit/d2375e2ebcab5c88feb5652f1a9d621b8f06b259"><code>d2375e2</code></a> Merge commit from fork</li> <li><a href="https://github.com/sveltejs/svelte/commit/547853e2406a2147ad7fb5ffeba95b01bd9642da"><code>547853e</code></a> Merge commit from fork</li> <li><a href="https://github.com/sveltejs/svelte/commit/55f9c85c09d625c3dd80c71ce7542f57386fafb4"><code>55f9c85</code></a> Version Packages (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/18158">#18158</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/a10e8e47a5946623a60a1e36b9023c23926eae87"><code>a10e8e4</code></a> fix: keep dependencies of <code>$state.eager</code>/<code>pending</code> (alternative approach) (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/1">#1</a>...</li> <li><a href="https://github.com/sveltejs/svelte/commit/ef4b97dfabfd7a23b27933e18f7393587c343d66"><code>ef4b97d</code></a> fix: duplicated "of" in events.js comment (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/18217">#18217</a>)</li> <li><a href="https://github.com/sveltejs/svelte/commit/5122936edb3c14e9a602e579727479b49cbd3239"><code>5122936</code></a> fix: treat batches as a linked list (<a href="https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte/issues/18205">#18205</a>)</li> <li>Additional commits viewable in <a href="https://github.com/sveltejs/svelte/commits/svelte@5.55.7/packages/svelte">compare view</a></li> </ul> </details> <br /> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
ac8a20779c |
feat(chat): add chat/ai subpath for AI SDK utilities (#492)
## Summary
Introduces a dedicated `chat/ai` subpath as the home for every Vercel AI
SDK helper that ships with Chat SDK. Importing from this subpath keeps
the optional `ai` and `zod` peer dependencies out of bundles that don't
use them.
### What's new
- **`createChatTools`** — exposes Chat SDK operations as ready-to-use AI
SDK tools so an agent can read, post, react, edit, delete, and manage
thread subscriptions across every adapter the supplied `Chat` instance
has registered.
- Write operations require user approval by default (`requireApproval:
true`); toggle globally or per-tool.
- Three presets — `reader`, `messenger`, `moderator` — scope the
toolset.
- Individual tools can also be cherry-picked (`import { postMessage,
addReaction } from "chat/ai"`).
- **`toAiMessages`** (and the `Ai*` / `ToAiMessagesOptions` types) now
live alongside the tools at `chat/ai`. The previous `chat` re-exports
continue to work, but are flagged `@deprecated` with an editor hint
pointing to the new home — migration is a one-line import change.
- **Docs** — new `/docs/ai` section between Usage and Adapters in the
sidebar:
- `/docs/ai` — Overview
- `/docs/ai/ai-sdk-tools` — `createChatTools` guide
- `/docs/ai/to-ai-messages` — `toAiMessages` reference
- `/docs/ai/types` — Reference for every type exported from `chat/ai`
- **Example app** — `examples/nextjs-chat` now demos the new surface via
a "Run Agent Demo" button on the welcome card and a free-form `/agent
<prompt>` slash command (streaming, with a placeholder so users get
immediate feedback in channel contexts where Slack's typing-status API
is a no-op).
### Future plans
`createChatTools` currently exposes the cross-adapter Chat SDK surface
only. A natural follow-up is to also support **platform-specific tools**
— e.g. expose Slack-only `pin`/`unpin`, Discord-only thread archiving,
GitHub-only issue commenting, etc., so users can further extend what
their agent can do without dropping back to raw adapter calls. The shape
would likely be additional opt-in factories under `chat/ai` (or
per-adapter subpaths like `@chat-adapter/slack/ai`) that return tools
layered on top of the platform-specific adapter clients, while keeping
the cross-platform `createChatTools` API as the lowest common
denominator.
### Coverage
- `createChatTools` orchestrator: 100% statements / 94.7% branches.
- Every tool factory's `execute()` is exercised end-to-end (29 tests in
`index.test.ts`).
- `toAiMessages` keeps its existing 35-test suite covering role mapping,
attachment handling, links, transforms, and unsupported-attachment
fallbacks.
- Tools folder overall: 99.0% statements / 86.1% branches / 97.4%
functions / 98.9% lines.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
Co-authored-by: dancer <josh@afterima.ge>
|
||
|
|
b75eedbb5f |
feat(chat): add queue-debounce concurrency strategy (#495)
## summary adds an opt-in `burst` concurrency strategy for #414 when a thread is idle, the first message waits for `debounceMs`, messages that arrive during that window are queued, and the handler runs once with the latest message plus earlier burst messages in `context.skipped` after the handler finishes, messages that arrived while it was running are drained like `queue`, so the latest queued message is processed with earlier queued messages in `context.skipped` keeps existing `drop`, `queue`, `debounce`, and `concurrent` behavior unchanged updates docs to cover `burst`, explain when to choose it over `debounce`, and document the related `MessageContext` behavior |
||
|
|
716e934aa2 |
feat(web-adapter): first class support for Vue and Svelte (#498)
## Summary <!-- What does this PR do? --> ## Test plan <!-- How did you verify the changes? --> ## Checklist - [ ] All commits are signed and verified - [ ] `pnpm validate` passes - [ ] Changeset added (or N/A — see [CONTRIBUTING.md](./CONTRIBUTING.md)) - [ ] Documentation updated (or N/A) --------- Co-authored-by: dancer <josh@afterima.ge> |
||
|
|
2f108bd4b3 |
feat: rename adapter.client to adapter.octokit / adapter.linearClient / adapter.webClient (#478)
## Summary
Rename the public native client getter on the GitHub, Linear, and Slack
adapters so it matches the underlying SDK class instead of the generic
`.client`. The previous `.client` getter is preserved as a `@deprecated`
alias on all three adapters, so existing code keeps working without
changes.
- `bot.getAdapter("github").client` is now
`bot.getAdapter("github").octokit` (returns `Octokit`)
- `bot.getAdapter("linear").client` is now
`bot.getAdapter("linear").linearClient` (returns `LinearClient` from
`@linear/sdk`)
- `bot.getAdapter("slack").client` is now
`bot.getAdapter("slack").webClient` (returns `WebClient` from
`@slack/web-api`)
Each new getter has TSDoc covering single- vs multi-tenant resolution
rules and when calling outside a webhook handler throws. Focused unit
tests assert that the new getter returns the underlying SDK instance,
that single-tenant calls return the same instance, that the deprecated
`.client` alias points at the new getter, that multi-tenant mode without
webhook context throws on both getters, and that inside a webhook
context the getter resolves to the per-tenant client.
Commits are split for review:
1. `feat(adapter-github): rename adapter.client to adapter.octokit`
2. `feat(adapter-linear): rename adapter.client to adapter.linearClient`
3. `docs: use .octokit / .linearClient in chat-sdk.dev examples`
4. `chore: changeset for adapter native client getter rename`
5. `fix: hoist regex literals in new client-getter tests to module
scope`
6. `feat(adapter-slack): rename adapter.client to adapter.webClient`
7. `docs: include slack .webClient in chat-sdk.dev examples`
8. `chore: include adapter-slack in native client getter rename
changeset`
9. `test(adapter-github,adapter-linear): cover with-context resolution
on the new client getters`
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
|
||
|
|
cd7b6af1c8 |
test(integration-tests): add Emulate.dev-backed tests for the GitHub adapter (#479)
## Summary Add an Emulate.dev-backed integration-test suite for the GitHub adapter, mirroring the structure of the Slack work in #477. Tests drive the adapter against an in-process [`@emulators/github`](https://emulate.dev/docs/github) server and assert on its stateful store (comments, reviews) rather than `mock.calls`, catching wire-format and contract issues that pure Octokit mocks miss. - New private devDeps in `packages/integration-tests`: `@emulators/github`, `@emulators/core`, `@hono/node-server`, plus a workspace dep on `@chat-adapter/github`. (`@emulators/core` and `@hono/node-server` are also declared by #477; this PR is independent of merge order.) - New harness `packages/integration-tests/src/github-emulator-utils.ts` boots the emulator on an ephemeral `127.0.0.1` port, seeds a deterministic user / repo / issue / PR / starter review comment, and exposes a near-passthrough HTTP forwarder. **No re-signing needed** here. `@emulators/core`'s `WebhookDispatcher` already signs deliveries with `X-Hub-Signature-256: sha256=<hex>` exactly as the GitHub adapter expects. The harness also adds a small URL rewriter for Octokit's `pulls.createReplyForReviewComment` shortcut endpoint, translating it into the canonical review-comment POST that the emulator implements. - Four new test files (12 tests), wired to the adapter via its existing `apiUrl` + `webhookSecret` config **zero source changes** to `packages/adapter-github`: - `emulator-github-auth.test.ts` (2) `GET /user` populates `botUserId` during `initialize()`. - `emulator-github-comments.test.ts` (4) `thread.post` / `edit` / `delete` on issue and PR-conversation threads. - `emulator-github-reviews.test.ts` (3) review-comment replies routed through `pulls.createReplyForReviewComment` with the right \`in_reply_to_id\`, plus edit / delete. - `emulator-github-events.test.ts` (3) full inbound `issue_comment` / `pull_request_review_comment` round-trip, including bot self-message filtering. ```mermaid flowchart LR subgraph Test["Vitest test process"] SDK[GitHubAdapter + Chat] Forwarder["HTTP forwarder<br/>passthrough"] Emu["@emulators/github<br/>(in-process Hono)"] end SDK -->|"issues.createComment / pulls.* / GET /user<br/>(apiUrl override)"| Emu Emu -->|"X-Hub-Signature-256 + x-github-event"| Forwarder Forwarder -->|"chat.webhooks.github(request)"| SDK ``` ### Out of scope (deliberate) - **Reactions** `@emulators/github` does not implement the `/reactions` endpoints used by the adapter. Reaction logic is still covered by the existing mock-based tests in `packages/adapter-github/src/index.test.ts`. - **GitHub App auth** (JWT \u2192 installation token via `POST /app/installations/:id/access_tokens`) the adapter and emulator both support it, but PAT-mode was the agreed scope here. - **Multi-tenant install flows** via `installation` webhook events. - Branches/refs, releases, search, actions, checks not used by the adapter. ## Test plan - [x] `pnpm --filter @chat-adapter/integration-tests test` 407 tests pass across 34 files (including the 12 new emulator-github tests, ~480 ms total). - [x] `pnpm check` and `pnpm knip` clean. - [x] CI safety verified: ephemeral ports (`port: 0`), loopback-only binds (`127.0.0.1`), deterministic teardown via `httpServer.close()`, no env vars, no external network egress. ## Checklist - [x] All commits are signed and verified - [x] \`pnpm validate\` passes - [x] Changeset added (or N/A see [CONTRIBUTING.md](./CONTRIBUTING.md)) N/A: \`@chat-adapter/integration-tests\` is \`private: true\` and the change is test-only. - [x] Documentation updated (or N/A) \`packages/integration-tests/README.md\` describes the new emulator-github test category. --------- Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com> |
||
|
|
79227ae991 |
docs: refresh adapter pages with hand-authored MDX (#474)
## Summary
Refreshes the adapter docs end-to-end so every adapter — official,
vendor-official, and community — now ships hand-authored MDX, lives
under a clean URL structure, and renders on a polished
sidebar/right-rail layout dedicated to `/adapters` (the shared `/docs`
chrome is untouched).
```mermaid
flowchart LR
subgraph Before
direction TB
OB[official] --> CB[community<br/>incl. 5 vendor pages]
end
subgraph After
direction TB
OA[official] --> VA[vendor-official<br/>5 pages] --> CA[community]
end
Before -.-> After
```
### Content & routing
- **New `/adapters/vendor-official/<slug>` route** for vendor-maintained
adapters (Beeper Matrix, Photon iMessage, Liveblocks, Resend, Zernio).
Sidebar gets a third labelled group ("Vendor-Official Adapters") between
Official and Community, with a top divider matching the existing
Community treatment.
- **All 13 vendor-official + community adapters migrated** from runtime
README fetching to hand-authored MDX with rich `features:` matrices and
full body content (install, quick start, configuration, auth,
gateway/streaming, troubleshooting). README fetch stays as a fallback
for any future community adapter that hasn't been migrated yet, gated by
a new `mdxBody: true` frontmatter flag.
- **Messenger filter pages removed** (`/adapters/for/<messenger>` + the
"Browse by messenger" chip row on `/adapters`). Existing URLs
308-redirect to `/adapters`.
- **Permanent redirects** from
`/adapters/community/{matrix,imessage,resend,zernio,liveblocks}` to
their new `/adapters/vendor-official/...` paths.
- **Fixed** `/docs/adapters` and `/docs/state` so the bare pages are
accessible again — the previous catch-all redirect (`:slug*`) was
swallowing them. Switched to `:slug+` so subpath URLs still 308 while
the bare pages render.
### Visual polish
- **Adapter-only sidebar variant** (`AdaptersDocsLayout` +
`AdaptersSidebar`) with uppercase eyebrow separators, tighter rows, and
a thin themed scrollbar utility class. The shared `/docs` sidebar is
untouched.
- **Restyled `AdapterHero`**: drops the badges row + packageName, sits
the title inline with the logo, larger 17 px tagline, horizontal divider
beneath the block.
- **Restyled `PackageInstall`** as a tabbed dark single-line snippet
with a `$` prompt prefix and a copy button — replaces the previous
multi-line `CodeBlock` layout.
- **New "Deploy your chat app on Vercel" upsell card** (`<Upsell />`)
replaces the old `EditSource / ScrollTop / Feedback / CopyPage` footer
cluster on every adapter detail page.
- **Listing & messenger pages**: align the H1 to a tighter `text-4xl
sm:text-[44px]`, and the section headers to `text-base font-medium
tracking-tight` with a one-line muted lede.
### Tooling & tests
- Added `mdxBody: true` opt-in to the adapter frontmatter schema
(`source.config.ts`), and updated both detail-page handlers
(`community/[slug]` and the new `vendor-official/[slug]`) to render the
MDX body when present, falling back to README fetch otherwise.
- Refactored both detail-page handlers to flatten the body-render
branches into a `renderBody()` helper, removing the nested ternaries
that were tripping `lint/style/noNestedTernary`.
- New test file
[`packages/integration-tests/src/docs-adapters.test.ts`](https://github.com/vercel/chat/blob/docs/refresh-adapters/packages/integration-tests/src/docs-adapters.test.ts)
— **220 new assertions** covering:
- Adapter MDX frontmatter completeness, slug ↔ filename consistency, and
`type ∈ {platform, state}`.
- Vendor-official invariants: exactly the expected slugs,
`vendorOfficial: true`, `community: true`, `author`, `mdxBody: true`,
`<FeatureSupport />` rendered.
- Community invariants: `community: true` (never vendor-official),
`mdxBody: true`, `<FeatureSupport />`.
- Official invariants: never flagged, `packageName` always under
`@chat-adapter/*`.
- `adapters.json` ↔ MDX sync on `packageName` / `type` / `community` /
`vendorOfficial`.
- Extended `VALID_DOC_PACKAGES` so `docs-content.test.ts` accepts the
new vendor-official + community packages, plus `@chat-adapter/web`,
`@chat-adapter/web/react`, and `@chat-adapter/messenger`.
### Per-package AGENTS.md
- Added `AGENTS.md` to every official adapter and state adapter (14
packages), each tailored to that adapter's surface — overview, directory
layout, build/test commands, public exports, thread ID format, webhook
flow, authentication, format conversion, cards/streaming, platform
quirks, testing approach, coding conventions, and release rules.
- Added a one-line `CLAUDE.md` (`@AGENTS.md`) beside each so Claude Code
picks up the same instructions through its built-in resolver — same
convention as the root.
### Web adapter copy
- Cleaned up the Web adapter tagline (removed inline backticks) and
dropped the now-redundant "v1 scope" section from the body.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
|
||
|
|
b9b17cd37d |
fix(discord): handle interactions in gateway-only mode (#490)
## summary fixes #343 fix Discord gateway-only mode so `InteractionCreate` events are handled directly when no interactions endpoint is configured slash commands now defer the gateway interaction and route through the existing slash command handler path, and button interactions defer updates before routing through the existing action handler path also clarifies in the Discord README that Discord sends interactions through either the Gateway or an Interactions Endpoint URL, not both |
||
|
|
67c1794a54 |
docs(chat): clarify direct message routing precedence (#491)
## summary clarifies that registered `onDirectMessage` handlers take precedence for incoming DM messages before subscribed-message, mention, and pattern routing updates the direct messages, event handling, thread subscription, and API docs so they match the current runtime behavior adds `onDirectMessage` to the Chat API docs fixes #432 |
||
|
|
add27309fb | feat(telegram): support typed attachment uploads (#485) | ||
|
|
fdebde7988 |
Reapply "feat(slack): expose direct WebClient access via adapter.client" (#472) (#476)
This reverts commit
|