Files
vercel__chat/.github/CONTRIBUTING.md
Ben Sabic 1bdbc31039 chore: integrate commitlint to enforce Conventional Commits
- Add @commitlint/cli and @commitlint/config-conventional (pinned to 21.0.0)
  and husky as root devDependencies.
- commitlint.config.js extends config-conventional, allows free-form scopes,
  and ignores auto-generated Merge / Revert commits.
- .husky/commit-msg runs commitlint on every local commit; husky installs
  automatically via the `prepare` script on `pnpm install`.
- New `commitlint` CI job in .github/workflows/ci.yml lints PR commits
  (--from base.sha --to head.sha) and the most recent commit on direct
  pushes to main (--last). SHAs are passed via `env:` rather than direct
  `${{ … }}` interpolation to avoid the script-injection class of bug.
- CI uses `pnpm install --frozen-lockfile`, so the commitlint binary that
  runs is exactly the version pinned in pnpm-lock.yaml.
- .github/CONTRIBUTING.md documents the local hook + CI enforcement.
2026-05-12 21:56:44 +10:00

6.8 KiB

Contributing

Reporting issues

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.

Building your own adapter

Want to add Chat SDK support for a platform that isn't covered by the official adapters? See Building a community adapter for a walkthrough of the Adapter interface, testing, packaging, and getting your adapter listed on chat-sdk.dev.

Package conventions

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.ts with a sibling src/types.ts
  • Import the Adapter type from chat
  • Export a ${Name}Adapter class that implements Adapter
  • Export a create${Name}Adapter factory function whose parameter is typed ${Name}AdapterConfig
  • Export the ${Name}AdapterConfig type from ./types

State packages (packages/state-*) must:

  • Import the StateAdapter type from chat
  • Export a ${Name}StateAdapter class that implements StateAdapter
  • Export a create${Name}State factory function whose parameter is typed ${Name}StateAdapterOptions
  • Export the ${Name}StateAdapterOptions type

${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).

Signed Commits

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.

Commit messages

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.

Commit messages are enforced by commitlint via @commitlint/config-conventional:

  • Locally: a Husky commit-msg hook runs commitlint on every commit. It is installed automatically by the prepare script when you run pnpm install.
  • In CI: the commitlint job in .github/workflows/ci.yml lints every commit in a pull request.

Scopes are free-form, but prefer package suffixes (slack, teams, gchat, discord, …) or domain areas (docs, release, ci) when relevant. To lint a message manually:

echo "feat(slack): add new event handler" | pnpm commitlint

Development

Testing

Run all unit tests across every package in a single Vitest Workspace run:

pnpm test:workspace

This produces one combined report covering all 11 unit-test packages. Integration tests (@chat-adapter/integration-tests) are excluded since they require platform credentials.

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 test

Other commands

pnpm 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)

Changesets

This project uses Changesets for version management. Every PR that changes a package's behavior must include a changeset.

Adding a Changeset

When you make a change that should be released (bug fix, new feature, breaking change), run:

pnpm changeset

This interactive CLI will ask:

  1. Which packages changed? — Select affected packages (space to select, enter to confirm)
  2. Bump type? — major (breaking), minor (feature), or patch (fix)
  3. Summary — A brief description for the changelog

This creates a markdown file in .changeset/ describing your change. Commit this file with your PR.

When to Add a Changeset

  • 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

Changeset Types

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.

Updating documentation

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 dev

Preview Branch Testing

The example app includes a middleware that can proxy webhook requests to a preview branch deployment. This allows testing preview branches with real webhook traffic from Slack/Teams/GChat.

Setup

  1. Deploy a preview branch to Vercel (e.g., https://chat-sdk-git-feature-branch.vercel.app)
  2. Go to /settings on the production deployment
  3. Enter the preview branch URL and save

To disable

Clear the URL on the settings page.

Files

  • examples/nextjs-chat/src/middleware.ts - The proxy middleware
  • examples/nextjs-chat/src/app/settings/page.tsx - Settings UI
  • examples/nextjs-chat/src/app/api/settings/preview-branch/route.ts - API to get/set the URL