## summary
sorts the Discord adapter type imports so main lint passes again
## test plan
- `pnpm exec ultracite check packages/adapter-discord/src/index.ts`
- `git diff --check`
## Summary
Plan’s task list API always marked existing in-progress steps as
complete whenever a new step was added. That made sense for simple
sequential bots, but it blocked parallel work — even though the docs
already showed a parallel pattern and per-task updates by ID were added
earlier.
This PR adds an optional flag on task creation so callers can keep
multiple steps in progress at once, while leaving the old sequential
behavior as the default.
**Opt-out flag, default on**. We considered removing auto-completion
entirely. That would’ve been cleaner for parallel use but would’ve
broken existing sequential bots that rely on implicit “move to next
step” behavior. Defaulting to the current behavior keeps upgrades safe;
parallel callers pass the flag off.
**No broader API redesign**. Task completion stays explicit via status
updates and the existing “complete plan” flow. The change is scoped to
when a new task is appended.
closes#630
## summary
resolves#515
adds Discord slash-command interaction response flags so selected
commands can defer as ephemeral
Discord locks ephemerality on the initial
`DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE` response, so the adapter now
exposes `interactionFlags` on `createDiscordAdapter` for that initial
acknowledgement
```ts
import {
createDiscordAdapter,
DiscordInteractionResponseFlag,
} from "@chat-adapter/discord";
const discord = createDiscordAdapter({
interactionFlags: ({ command }) => {
if (command === "/admin") {
return DiscordInteractionResponseFlag.Ephemeral;
}
},
});
```
handlers still use the normal `event.channel.post(...)` flow, and
`event.channel.postEphemeral(...)` keeps the normal Chat SDK fallback
behavior outside Discord's slash-command interaction response path
Co-authored-by: dancer <josh@afterima.ge>
## summary
fixes#613
detects bot mentions across queued and burst skipped messages before
routing handlers
this makes `onNewMention` fire when an earlier skipped message mentions
the bot and the latest collapsed message does not, while preserving
`message.isMention` on the latest message
adds regression coverage for both `queue` and `burst`
## Summary
Send Telegram typing actions immediately for private incoming message
and slash command updates before handing the message to Chat SDK
processing. This lets Telegram clients show the native `...` indicator
during early processing instead of waiting for downstream handler code
to call `thread.startTyping()`.
The change is scoped to private, non-bot Telegram messages and adds
regression coverage for normal messages and slash commands plus a patch
changeset.
Closes#611
## Test plan
- [x] `pnpm validate`
- [x] `pnpm --filter @chat-adapter/telegram test`
- [x] `pnpm --filter @chat-adapter/telegram typecheck`
- [x] `pnpm --filter @chat-adapter/telegram build`
## Checklist
- [x] All commits are signed and verified
- [x] `pnpm validate` passes
- [x] Changeset added (or N/A — see
[CONTRIBUTING.md](./CONTRIBUTING.md))
- [x] Documentation updated (or N/A)
---------
Signed-off-by: dancer <josh@afterima.ge>
Co-authored-by: dancer <josh@afterima.ge>
- Remove raw GitHub webhook body previews from adapter debug/error logs
- Prevents webhook payload content from being copied into application
logs when debug logging is enabled
- No webhook routing or response behavior change; only log fields change
## Context
The GitHub adapter logged a preview of incoming webhook request bodies
while handling webhooks.
Raw webhook payloads can contain repository metadata, user-authored
issue or pull request text, URLs, installation details, and other
provider-controlled content. Even at debug level, SDK logging should
avoid copying raw provider payloads into application logs by default.
## Problem
Debug logging should provide useful operational context without changing
the privacy boundary of webhook data.
The previous log emitted a raw body preview before signature
verification. That meant an application with debug logging enabled could
record payload content from both valid GitHub webhook events and invalid
requests that were later rejected.
This is unnecessary for normal webhook troubleshooting. Derived request
metadata is enough to understand routing and parsing failures without
retaining payload text.
## Changes
The GitHub adapter no longer logs raw webhook bodies or body previews.
Webhook logs now use bounded request-shape metadata:
- `bodyBytes`
- `contentType`
- `eventType`
- `signaturePresent`
- `jsonParseStatus` for invalid JSON
The change preserves signature verification, ping handling, JSON
parsing, and event routing behavior.
Regression tests cover invalid signature, invalid JSON, and valid
webhook paths with token-shaped and customer-slug sentinel strings in
the payload. The tests assert those sentinels, the full raw body, the
old raw-body log message, and `bodyPreview` do not appear in logger
calls.
A patch changeset is included for `@chat-adapter/github`.
## Verification
- `pnpm turbo build --filter @chat-adapter/github`
- `pnpm --filter @chat-adapter/github test`
- `pnpm --filter @chat-adapter/github typecheck`
- `pnpm check`
- `git diff --check`
## Summary
Discord only renders masked links `[text](url)` inside embeds. In a
normal message, a bare URL converted to `[url](url)` shows up as literal
text rather than a clickable link.
In nodeToDiscordMarkdown's link branch, return the bare URL when the
link's label equals its target (the bare-URL / autolink case); labeled
links are unchanged. Adds regression tests for both bare URLs and
<autolinks>.
Fixes#565.
## Bug
The Discord adapter converts `@mentions` with `/@(\w+)/g` in two places
— `DiscordFormatConverter.convertMentionsToDiscord` (plain/`raw`
messages) and the text-node branch of `nodeToDiscordMarkdown`
(markdown/AST messages):
```ts
text.replace(/@(\w+)/g, "<@$1>");
```
That pattern matches `@word` even when the `@` is preceded by a word
character, so it rewrites **email addresses** and `word@word` handles
into broken mentions:
| input | before | after |
|---|---|---|
| `Contact me at user@example.com` | `Contact me at user<@example>.com`
| `Contact me at user@example.com` |
| `ping support@vercel.com` | `ping support<@vercel>.com` | `ping
support@vercel.com` |
| `hey @alice` | `hey <@alice>` | `hey <@alice>` (unchanged) |
The Slack adapter already guards against exactly this with a
word-boundary check (`replaceBareMentions`); the Discord converter
didn't.
## Fix
Introduce a shared top-level `BARE_MENTION_PATTERN =
/(?<![\w@.])@(\w+)/g` (per AGENTS.md, regex literals live at top level)
with a negative lookbehind, so only an `@` at a word boundary becomes a
mention. Emails/handles are left intact; real bare mentions still
convert. Used in both conversion sites.
## Test
Adds a regression test in `markdown.test.ts` asserting `Contact me at
user@example.com` round-trips through `toAst`/`fromAst` without becoming
a mention. Includes a changeset (`@chat-adapter/discord` patch). Commit
is signed (Verified) and DCO signed-off.
---------
Signed-off-by: Osamaali313 <86572800+Osamaali313@users.noreply.github.com>
Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com>
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
- Replace npm version/download badges with Agent Stack and MIT badges on
the root README and all published package READMEs
- Streamline root `AGENTS.md`: fix title, add an accurate monorepo map,
trim duplicated CONTRIBUTING/Ultracite/env-var content, and link to
package-level `AGENTS.md` files
- Slim the Chat SDK agent skill (`skills/chat/SKILL.md` and published
copies) to defer to bundled docs, chat-sdk.dev, Vercel KB, and
`llms.txt` instead of inlining CLI flags, quick-start code, and API
tables
- Polish root README copy (install examples, adapter/build links, Vercel
Plugin URL, Vercel KB link, “Made by Vercel” badge)
- Minor `CONTRIBUTING.md` fixes: simplify DCO wording, correct
preview-branch proxy file references (`proxy.ts` vs middleware)
---------
Signed-off-by: Ben Sabic <bensabic@users.noreply.github.com>
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
Adds the
[`chat-adapter-weixin`](https://github.com/wong2/weixin-chat-adapter)
community adapter (Weixin / WeChat iLink bot) to the docs.
### What's included
- `apps/docs/content/adapters/community/weixin.mdx` — hand-authored
adapter page following the existing community-adapter structure
(install, quick start, long-polling note, QR login, env vars, config
`TypeTable`, thread-ID format, capabilities/limitations, and
`<FeatureSupport />`).
- `apps/docs/adapters.json` — registry entry (`community: true`, author,
pinned README commit).
- `apps/docs/content/adapters/community/meta.json` — sidebar link under
**Platforms**.
### Notes
The adapter talks to Weixin's iLink bot HTTP JSON APIs directly. It uses
long polling for inbound messages (no webhook) and requires a Chat SDK
`StateAdapter` for cursor / context-token / dedupe / history. It's 1:1
only, so messages route through `onDirectMessage`.
### Verification
`docs-adapters` (322) and `docs-llms` (129) integration tests pass.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
## summary
fixes#631
removes dummy `Message` casts from lightweight thread, action, and
reaction paths when no incoming message context exists
this keeps the existing `currentMessage` guard meaningful and prevents
streaming through `chat.thread(threadId)`, `chat.openDM(...)`, action
threads, and reaction threads from reading fields from an empty object
when Slack lacks the thread or recipient context required by
`chat.startStream`, the adapter now returns `null` before consuming the
stream so Chat SDK can transparently use its post-and-edit fallback
native Slack streaming remains available for webhook-created threads and
DM threads with valid native stream context
---------
Co-authored-by: dancer <josh@afterima.ge>
Replace the explicit per-example entries in the changesets `ignore` list
with an `example-*` name glob (matched by micromatch). All example apps
are
private and never published, so listing them individually only adds
version
and changelog churn to release PRs, and each new example required
editing
this CODEOWNERS-gated file.
Add an integration test that resolves the changesets config against the
workspace and asserts every examples/* package is in the resolved ignore
list and follows the `example-*` naming convention, so an off-convention
example app fails CI instead of silently leaking into releases.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
## Summary
Fixes `@chat-adapter/telegram` silently truncating valid MarkdownV2
messages whose link URLs contain an odd number of entity-marker
characters (`_`, `*`, `~`).
`trimToMarkdownV2SafeBoundary` counted unescaped markers anywhere
outside code spans and treated an odd total as an unterminated entity.
But per the [MarkdownV2
spec](https://core.telegram.org/bots/api#markdownv2-style), only `)` and
`\` are special inside the `(...)` URL part of an inline link — so a
message ending with e.g. `[Read
more](https://example.com/page?utm_campaign=a&utm_source=b&utm_channel=c)`
(3 raw underscores in the URL) was sliced mid-URL, rejected by Telegram
with `can't parse entities: Can't find end of a URL`, and degraded to
plain text by the markdown fallback — links and formatting silently
stripped.
Changes in `findUnescapedPositionsOutsideCode`:
- Tracks a link-URL state alongside the existing `inFence`/`inInline`
tracking: it opens when an unescaped `](` is consumed outside code and
closes at the first unescaped `)`. Markers inside that span are never
recorded.
- A link's `]` only counts toward bracket pairing once its URL closes,
so hard truncation (4096-char limit) that slices mid-URL now leaves the
`[` unmatched and trims back to before the link — previously the cut
left an unterminated `(` that Telegram rejected.
The defensive under-limit safety pass from #446 (streaming chunks) is
intentionally kept; it's now link-aware.
## summary
prevents cached Slack display names inside urls from being resolved as
user mentions before payload formatting
shares url-aware mention handling between cached user lookup and Slack
formatting while preserving real mentions
follow-up to #618, which only protected the final formatting pass
Syncs the bundled Chat SDK KB resources from Edge Config and hardens the
`sync-resources` script that generates them.
- **New guides** (4): Vercel Connect, the Slack Vercel Connect bot, AI
Gateway + AI SDK, and the daily digest bot. Existing guide bodies
refreshed and `templates.json` regenerated.
- **Script hardening** (`scripts/sync-resources.ts`):
- Fetch + validate all guides into memory **before** wiping the
resources dir — a failed fetch now leaves the working tree untouched.
- Validate the `resources-edge-config.json` shape with a clear error
instead of a blind cast.
- Reject duplicate guide slug collisions.
- Retry transient fetches (5xx / network) with exponential backoff; fail
fast on 4xx, bad content-type, and oversized bodies.
- Mirror `skills/chat/SKILL.md` to **all four** committed copies (docs
site `.well-known` + `AGENTS.md`, and the two `create-chat-sdk` scaffold
templates).
- TSDoc on every function.
- **Tests**: new offline consistency test in
`packages/integration-tests` — every guide has a non-empty file with no
orphans, `templates.json` mirrors the config, no duplicate slugs, and
all four `SKILL.md` copies are byte-identical to the source.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
Adds Linq as a vendor-official adapter — iMessage and SMS for Chat SDK.
- `vendor-official/linq.mdx` adapter page (following the Velt /
AgentPhone format)
- catalog entry in `adapters.json`
- `linq` added to the vendor-official `meta.json`
Repo: https://github.com/linq-team/linq-chat-sdk · npm:
`@linqapp/chat-sdk-adapter` (Apache-2.0)
The adapter is built and tested end-to-end against the live Linq API and
the Chat SDK runtime (real iMessage round-trip, webhooks, reactions,
media). Confirmed with Benji that a repo link works and Apache-2.0 is
fine. Happy to adjust the page to match any conventions I missed.
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
## Summary
Adds Novu as a vendor official adapter to Chat SDK allowing
multi-channel notification delivery and quick channel setup for
multi-tenant apps.
Official change log entry:
https://novu.co/changelog/novu-chat-sdk-adapter/
Official social post: https://x.com/novuhq/status/2067870170320679158
## Test plan
Manually tested with our team to ensure compatability with the create
chat sdk and template apps, also created an example repo:
https://github.com/novuhq/novu-chat-sdk-example
## Checklist
- [x] All commits are signed and verified
- [x] `pnpm validate` passes
- [x] Changeset added (or N/A — see
[CONTRIBUTING.md](./CONTRIBUTING.md))
- [x] Documentation updated (or N/A)
---------
Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
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>
## 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>
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>
## 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
## 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>
## 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>
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>
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>
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>
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>
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>
## 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
## 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
## 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
## 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
## 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
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>
## 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.
## 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>
## 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
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>
## 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`
## 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>
## 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
## 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