Files
vercel__chat/AGENTS.md
T
Ben Sabic 90cd8f181a chore: refresh release workflow, community health files, and agent docs (#431)
* ci(release): pin changesets/action and enable npm provenance

Pin changesets/action to the v1.7.0 commit SHA, switch to GitHub-API
commit mode (signed commits via the API), set the version PR commit
and title to a conventional "chore(release): version packages", and
enable npm provenance attestations on publish via NPM_CONFIG_PROVENANCE.

* chore: add CODEOWNERS

Default ownership goes to @vercel/chat-sdk; release-plumbing paths
(release workflow, changeset config, CODEOWNERS itself) stay locked
to @cramforce since the publish workflow is bound to npm Trusted
Publisher by filename.

* docs: add SUPPORT.md and tidy issue contact links

Add a SUPPORT.md pointing users to docs, the issue chooser, and the
security advisory flow. Also update .github/config.yml: point the
Documentation contact link at chat-sdk.dev/docs (was a github.com
README anchor) and remove the GitHub Discussions entry, which 404s
because Discussions isn't enabled on the repo.

* chore: add docs issue and adapter request templates

Two new issue templates so reports come in pre-shaped:
- Documentation Issue — page/section, type (typo, outdated, missing,
  broken link, etc.), description, suggested fix.
- Adapter Request — platform name, adapter type (platform/state), API
  docs link, use case, existing community work, willingness to help
  maintain.

* docs(contributing): point contributors at issue templates and SUPPORT.md

Add a "Reporting issues" section at the top of CONTRIBUTING.md that
links to the issue chooser (now covering bugs, features, docs issues,
and adapter requests) and to SUPPORT.md for general questions, with
the SECURITY.md private-disclosure path called out separately.

* chore: add pre-merge checklist to PR template

Adds four self-attestation boxes contributors can tick before
requesting review, surfacing requirements that already live in
CONTRIBUTING.md so they're not forgotten:

- Signed and verified commits (CONTRIBUTING explicitly bounces PRs
  with unsigned commits).
- `pnpm validate` passes (lint, typecheck, tests, build in one go).
- Changeset added when a package's behavior changes.
- Docs updated for user-facing changes.

The "or N/A" wording on the last two avoids forcing a yes for
internal-only or docs-only PRs.

* chore: add Telegram and WhatsApp to bug report platform dropdown

The bug report platform dropdown was missing Telegram and WhatsApp,
which both have official adapters (@chat-adapter/telegram and
@chat-adapter/whatsapp). Reporters had to fall back to "Other" for
bugs in those adapters, losing the platform signal.

* docs(readme): fix CONTRIBUTING link path and add Support section

The Contributing section linked to ./CONTRIBUTING.md, but the file
actually lives at .github/CONTRIBUTING.md, so the link 404'd on
github.com. Repoint it.

Also add a Support section linking SUPPORT.md (general help) and
SECURITY.md (private vulnerability reporting) so those community
health files are reachable from the repo entry point instead of
only via GitHub's auto-surfacing.

* docs(contributing): add adapter authoring, commit conventions, and docs sections

Three additions to CONTRIBUTING.md to round out the file alongside
the recently added issue templates and PR checklist:

- "Building your own adapter" — points contributors who hit the
  Adapter Request template at the existing community-adapter guide
  on chat-sdk.dev rather than leaving them to discover it.
- "Commit messages" — codifies the Conventional Commits style the
  repo already uses; the release workflow now relies on the
  "chore(release): version packages" convention for its auto-PR,
  so consistency in new commits keeps changelogs predictable.
- "Updating documentation" — names the apps/docs/content/docs/
  source path, links the live site, and shows the local preview
  command so the PR-template "Documentation updated" checkbox is
  actionable.

* docs: trim agent docs, rename CLAUDE.md to AGENTS.md, add CLAUDE.md pointer

Move the agent guidance to AGENTS.md (the cross-tool convention) and
leave CLAUDE.md as a one-line "@AGENTS.md" pointer so Claude Code
keeps auto-loading the same content.

While renaming, trim and update the file:

- "packages/chat-sdk" was wrong — directory is "packages/chat", npm
  name is "chat".
- Updated the package list to include adapter-{discord,telegram,
  github,linear,zoom,shared}, state-{ioredis,pg}, integration-tests,
  and the apps/docs and examples/nextjs-chat trees.
- Replaced the verbose recording-and-replay jq walkthrough with a
  one-line pointer to the integration-tests README.
- Dropped the duplicated Changesets walkthrough — full guidance now
  lives in CONTRIBUTING.md.
- Condensed ~120 lines of generic Ultracite/Biome rules to a short
  list of non-obvious gotchas (Biome enforces the rest automatically).
- Added Conventional Commits (load-bearing for the release workflow's
  auto-PR), the apps/docs/content/docs/ docs path with the "pnpm
  --filter docs dev" preview command, a pointer to the community
  health files, and POSTGRES_URL/DATABASE_URL for the new state-pg
  adapter.

Net: 344 → ~125 lines.

* docs(nav): rename "Source" link to "GitHub"

---------

Co-authored-by: Ben Sabic <bensabic@users.noreply.github.com>
2026-04-27 05:22:35 -07:00

6.4 KiB

CLAUDE.md

Guidance for Claude Code (claude.ai/code) when working in this repository.

Build commands

pnpm install
pnpm build           # Build all packages (Turborepo)
pnpm typecheck       # Type-check all packages
pnpm check           # Lint and format check (ultracite/biome)
pnpm fix             # Auto-fix lint/format issues
pnpm knip            # Check for unused exports/dependencies
pnpm test            # Run all tests
pnpm validate        # knip + check + typecheck + test + build. ALWAYS run before declaring a task done.
pnpm dev             # Watch mode

# Per-package
pnpm --filter chat test
pnpm --filter @chat-adapter/slack build
pnpm --filter docs dev    # Preview the docs site (chat-sdk.dev) locally

Code style

  • Install dependencies with pnpm add, not by editing package.json by hand.
  • sample-messages.md files in adapter packages contain real-world webhook logs — useful when writing parsers or fixtures.
  • Commits must be signed and verified — see .github/CONTRIBUTING.md.
  • We follow Conventional Commits (feat:, fix:, docs:, chore:, optionally scoped). The release workflow's auto-PR uses chore(release): version packages — don't reuse that exact subject for unrelated commits.
  • See the Ultracite section at the bottom for the in-code style rules Biome doesn't catch automatically.

Architecture

pnpm monorepo, Turborepo orchestrated. All packages are ESM ("type": "module"), TypeScript, bundled with tsup.

Packages

  • packages/chat — core SDK (chat npm package): Chat class, types, mdast-based markdown utilities
  • packages/adapter-{slack,teams,gchat,discord,telegram,whatsapp,github,linear,zoom} — platform adapters
  • packages/adapter-shared — utilities shared across adapters
  • packages/state-{memory,redis,ioredis,pg} — state adapters
  • packages/integration-tests — integration tests against real platform APIs
  • apps/docs — fumadocs-based docs site (chat-sdk.dev)
  • examples/nextjs-chat — example Next.js app

Core concepts

  1. Chat (packages/chat/src/chat.ts) — main entry point; coordinates adapters and handlers.
  2. Adapter — platform-specific implementation: webhook verification + parsing, normalized format conversion, FormatConverter for markdown ↔ platform AST.
  3. StateAdapter — persistence for subscriptions, distributed locks, key/value cache, lists, and queues.
  4. Thread — conversation thread with post(), subscribe(), startTyping(), setState(), etc.
  5. Message — normalized message: text, formatted (mdast AST), raw (platform-specific).

Thread ID format

{adapter}:{channel}:{thread} — e.g. slack:C123ABC:1234567890.123456. Some adapters base64-encode IDs that contain delimiters (Teams, Google Chat).

Webhook flow

  1. Platform → /api/webhooks/{platform}
  2. Adapter verifies, parses, calls chat.handleIncomingMessage()
  3. Chat acquires a thread lock, then routes to onSubscribedMessage, onNewMention, or onNewMessage handlers depending on context.
  4. Handler receives Thread and Message.

Formatting

Messages use mdast as the canonical format. Each adapter's FormatConverter provides:

  • toAst(platformText) — platform → mdast
  • fromAst(ast) — mdast → platform
  • renderPostable(message) — PostableMessage → platform string

Testing

packages/chat/src/mock-adapter.ts exports test utilities:

  • createMockAdapter(name) — Adapter with vi.fn() mocks
  • createMockState() — in-memory subscriptions/locks/cache
  • createTestMessage(id, text, overrides?)
  • mockLogger

For production-traffic-driven testing, see packages/integration-tests/fixtures/replay/README.md (recording / export / replay workflow). Recordings are tagged with the deployed git SHA and exported via pnpm recording:list / pnpm recording:export <session-id> from examples/nextjs-chat.

Documentation

User-facing docs live in apps/docs/content/docs/ (rendered at chat-sdk.dev/docs). When changing behavior, public APIs, or env vars, update the relevant page in the same PR. Preview locally with pnpm --filter docs dev.

Releases

Uses Changesets with fixed versioning (every package shares one version). Every PR that changes a package's behavior must include a changeset (pnpm changeset). Full rules in .github/CONTRIBUTING.md.

Environment variables

Key env vars (see turbo.json for the full list):

  • SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET
  • TEAMS_APP_ID, TEAMS_APP_PASSWORD, TEAMS_APP_TENANT_ID
  • GOOGLE_CHAT_CREDENTIALS or GOOGLE_CHAT_USE_ADC
  • WHATSAPP_ACCESS_TOKEN, WHATSAPP_APP_SECRET, WHATSAPP_PHONE_NUMBER_ID, WHATSAPP_VERIFY_TOKEN
  • REDIS_URL — Redis state adapter
  • POSTGRES_URL / DATABASE_URL — PostgreSQL state adapter
  • BOT_USERNAME — default bot username

Community health files

  • .github/CONTRIBUTING.md — dev setup, signed commits, conventional commits, changesets, docs preview, building your own adapter
  • .github/SUPPORT.md — where to send help/usage questions
  • .github/SECURITY.md — private vulnerability reporting
  • .github/ISSUE_TEMPLATE/ — bug, feature, docs, and adapter-request templates
  • .github/CODEOWNERS — @vercel/chat-sdk owns everything; release plumbing is locked to @cramforce

Ultracite code standards

This project uses Ultracite (Biome-based). pnpm check / pnpm fix run it across the monorepo. Most issues auto-fix.

Beyond what Biome enforces:

  • Type safety — prefer unknown over any; as const for literals; named constants over magic numbers.
  • Modern JS/TS — for...of over .forEach; ?. and ??; const by default; template literals; destructure.
  • Async — always await returned promises; no async Promise executors.
  • React — function components only; hooks at top level; stable keys (prefer IDs over indices); no components defined inside other components; semantic HTML and ARIA; <Image> over <img>; ref-as-prop in React 19+.
  • Errors — throw Error objects with descriptive messages; early returns over nested conditionals; no console.log / debugger / alert in shipped code.
  • Performance — top-level regex literals; no spread-in-accumulator loops; specific imports over barrel files.
  • Security — rel="noopener" on target="_blank"; avoid dangerouslySetInnerHTML; never eval() or assign to document.cookie.