For bugs, feature requests, documentation issues, or new adapter requests, pick an issue template. Each one asks for the information we need to triage the report.
For questions and getting help, see SUPPORT.md. Security vulnerabilities should be reported privately — see SECURITY.md. Do not file a public issue for security issues.
Want to add Chat SDK support for a platform that isn't covered by the official adapters? See Building an adapter for a walkthrough of the Adapter interface, testing, and packaging. List as community or vendor-official.
When opening a listing PR from a clone of this repo, use the add-adapter skill (Cursor / Claude Code) so the registry, docs page, catalog, and tests stay in sync.
The repo uses konsistent (configured in .github/konsistent.json, run via pnpm konsistent) to enforce a consistent public surface across adapter and state packages.
Adapter packages (packages/adapter-*) must:
- Live in
src/index.tswith a siblingsrc/types.ts - Import the
Adaptertype fromchat - Export a
${Name}Adapterclass that implementsAdapter - Export a
create${Name}Adapterfactory function whose parameter is typed${Name}AdapterConfig - Export the
${Name}AdapterConfigtype from./types
State packages (packages/state-*) must:
- Import the
StateAdaptertype fromchat - Export a
${Name}StateAdapterclass that implementsStateAdapter - Export a
create${Name}Statefactory function whose parameter is typed${Name}StateAdapterOptions - Export the
${Name}StateAdapterOptionstype
${Name} is the kebab-case package suffix in PascalCase — most cases are mechanical (discord → Discord), but a few overrides live in kebabToPascalMap in the config (e.g. gchat → GoogleChat, whatsapp → WhatsApp).
Example apps (examples/*) must:
- Be marked
"private": true(they are never published) - Name their
package.jsonnamefieldexample-*(e.g.example-nextjs-chat)
The example-* name lets the ignore glob in .changeset/config.json exclude every example from versioning and publishing automatically, so adding a new example needs no changeset and no edit to the changesets config. A test in packages/integration-tests asserts every examples/* package follows this convention and is in the resolved changesets ignore list.
All commits to this repository must be signed and verified. Pull requests with unsigned commits will not be merged.
GitHub has a guide on setting this up: Signing commits. The easiest path is usually signing with SSH using a key you've already added to GitHub.
Verify your setup by checking that new commits show a "Verified" badge on github.com.
In addition to signing, every commit must be signed off to certify that you wrote the patch (or otherwise have the right to submit it under the project's license), per the Developer Certificate of Origin.
Sign off by adding the -s flag when you commit:
git commit -s -m "feat: add a thing"This appends a trailer to your commit message:
Signed-off-by: Your Name <your.email@example.com>
The name and email must match the author of the commit. To set them once:
git config user.name "Your Name"
git config user.email "your.email@example.com"If the DCO check fails on existing commits, the simplest fixes are to amend (git commit --amend -s) or rebase (git rebase --signoff main) and force-push. The DCO app also accepts a single remediation commit if you'd rather not rewrite history — follow the instructions in the failed check's details.
We follow Conventional Commits — feat:, fix:, docs:, chore:, etc., optionally with a scope (e.g., fix(slack): ...).
The release workflow's auto-generated version PRs also use this convention (chore(release): version packages), so keeping new commits consistent makes changelogs and release PRs predictable.
Run all unit tests across every package in a single Vitest Workspace run:
pnpm test:workspaceThis produces one combined report covering the unit-test packages and example tests. The integration-test package and PostgreSQL's real-database suite are excluded; run those through their package test commands.
You can also run tests per-package via Turborepo:
# All packages (including integration tests)
pnpm test
# Single package
pnpm --filter chat test
pnpm --filter @chat-adapter/slack testpnpm check # Check all packages (linting and formatting)
pnpm typecheck # Type-check all packages
pnpm knip # Check for unused exports/dependencies
pnpm konsistent # Enforce adapter/state-package shape conventions
pnpm validate # Run everything (knip, lint, typecheck, test, build)This project uses Changesets for version management. Every PR that changes a package's behavior must include a changeset.
When you make a change that should be released (bug fix, new feature, breaking change), run:
pnpm changesetThis interactive CLI will ask:
- Which packages changed? — Select affected packages (space to select, enter to confirm)
- Bump type? —
major(breaking),minor(feature), orpatch(fix) - Summary — A brief description for the changelog
This creates a markdown file in .changeset/ describing your change. Commit this file with your PR.
- Do add for: bug fixes, new features, breaking changes, dependency updates affecting behavior
- Don't add for: documentation changes, internal refactors, test changes, CI updates, or changes to example apps (
examples/*are private and ignored by changesets)
| Type | When to Use | Version Bump |
|---|---|---|
patch |
Bug fixes, minor improvements | 4.0.0 → 4.0.1 |
minor |
New features (backward compatible) | 4.0.0 → 4.1.0 |
major |
Breaking changes | 4.0.0 → 5.0.0 |
All packages in this monorepo use fixed versioning — they always share the same version number, and any release bumps every package together.
User-facing docs live in apps/docs/content/docs/ and render at chat-sdk.dev/docs. When a PR changes behavior, public APIs, or environment variables, update the relevant page(s) in the same PR.
To preview docs locally:
pnpm --filter docs devIf an AI coding agent writes any of your contribution's prose, it must use the technical-writer skill. That covers docs pages, READMEs, changesets, commit messages, PR descriptions, and issues. The skill sets the voice and editorial standards for this repo and checks technical claims against the source. Agents that read this repo's AGENTS.md pick up the requirement automatically.
The example app includes a proxy that can forward webhook requests to a preview branch deployment. This allows testing preview branches with real webhook traffic from Slack/Teams/GChat.
- Deploy a preview branch to Vercel (e.g.,
https://chat-sdk-git-feature-branch.vercel.app) - Go to
/settingson the production deployment - Enter the preview branch URL and save
Clear the URL on the settings page.
examples/nextjs-chat/src/proxy.ts- The proxy logicexamples/nextjs-chat/src/app/settings/page.tsx- Settings UIexamples/nextjs-chat/src/app/api/settings/preview-branch/route.ts- API to get/set the URL