mirror of
https://github.com/vercel/chat.git
synced 2026-09-14 18:32:29 +08:00
6.1 KiB
6.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Build Commands
# Install dependencies
pnpm install
# Build all packages (uses Turborepo)
pnpm build
# Type-check all packages
pnpm typecheck
# Lint all packages
pnpm lint
# Check for unused exports/dependencies
pnpm knip
# Run all tests
pnpm test
# Run full validation. ALWAYS do this before declaring a task to be done.
pnpm validate
# Run dev mode (watch for changes)
pnpm dev
# Build a specific package
pnpm --filter chat build
pnpm --filter @chat-adapter/slack build
pnpm --filter @chat-adapter/gchat build
pnpm --filter @chat-adapter/teams build
# Run tests for a specific package
pnpm --filter chat test
pnpm --filter @chat-adapter/integration-tests test
# Run a single test file
pnpm --filter @chat-adapter/integration-tests test src/slack.test.ts
Code Style
- Install dependencies with
pnpm addrather than manually editing package.json sample-messages.mdfiles in adapter packages contain real-world webhook logs as examples
Architecture
This is a pnpm monorepo using Turborepo for build orchestration. All packages use ESM ("type": "module"), TypeScript, and tsup for bundling.
Package Structure
packages/chat-sdk- Core SDK (chatpackage) withChatclass, types, and markdown utilities (mdast-based)packages/adapter-slack- Slack adapter using@slack/web-apipackages/adapter-gchat- Google Chat adapter usinggoogleapispackages/adapter-teams- Microsoft Teams adapter usingbotbuilderpackages/state-memory- In-memory state adapter (for development/testing)packages/state-redis- Redis state adapter (for production)packages/integration-tests- Integration tests against real platform APIsexamples/nextjs-chat- Example Next.js app showing how to use the SDK
Core Concepts
- Chat (
packages/chat-sdk/src/chat.tsinchatpackage) - Main entry point that coordinates adapters and handlers - Adapter - Platform-specific implementations (Slack, Teams, Google Chat). Each adapter:
- Handles webhook verification and parsing
- Converts platform-specific message formats to/from normalized format
- Provides
FormatConverterfor markdown/AST transformations
- StateAdapter - Persistence layer for subscriptions and distributed locking
- Thread - Represents a conversation thread with methods like
post(),subscribe(),startTyping() - Message - Normalized message format with
text,formatted(mdast AST), andraw(platform-specific)
Thread ID Format
All thread IDs follow the pattern: {adapter}:{channel}:{thread}
- Slack:
slack:C123ABC:1234567890.123456 - Teams:
teams:{base64(conversationId)}:{base64(serviceUrl)} - Google Chat:
gchat:spaces/ABC123:{base64(threadName)}
Message Handling Flow
- Platform sends webhook to
/api/webhooks/{platform} - Adapter verifies request, parses message, calls
chat.handleIncomingMessage() - Chat class acquires lock on thread, then:
- Checks if thread is subscribed -> calls
onSubscribedMessagehandlers - Checks for @mention -> calls
onNewMentionhandlers - Checks message patterns -> calls matching
onNewMessagehandlers
- Checks if thread is subscribed -> calls
- Handler receives
ThreadandMessageobjects
Formatting System
Messages use mdast (Markdown AST) as the canonical format. Each adapter has a FormatConverter that:
toAst(platformText)- Converts platform format to mdastfromAst(ast)- Converts mdast to platform formatrenderPostable(message)- Renders aPostableMessageto platform string
Linting
Uses Biome with strict rules:
noUnusedImportsandnoUnusedVariablesas errorsuseImportTypeenforced - useimport typefor type-only importsnoExplicitAny- avoidanytypesnoNonNullAssertion- avoid!assertions
Recording & Replay Tests
Production webhook interactions can be recorded and converted into replay tests:
- Recording: Enable
RECORDING_ENABLED=truein deployed environment. Recordings are tagged with git SHA. - Export: Use
pnpm recording:listandpnpm recording:export <session-id>fromexamples/nextjs-chat - Convert: Extract webhook payloads and create JSON fixtures in
packages/integration-tests/fixtures/replay/ - Test: Write replay tests using helpers from
replay-test-utils.ts
See packages/integration-tests/fixtures/replay/README.md for detailed workflow.
Downloading and Analyzing Recordings
When debugging production issues, download recordings for the current git SHA:
cd examples/nextjs-chat
# Get current SHA
git rev-parse HEAD
# List all recording sessions (look for sessions starting with your SHA)
pnpm recording:list
# Export a specific session to a file
pnpm recording:export session-<SHA>-<timestamp>-<random> 2>&1 | \
grep -v "^>" | grep -v "^\[dotenv" | grep -v "^$" > /tmp/recording.json
# View number of entries
cat /tmp/recording.json | jq 'length'
# Group webhooks by platform
cat /tmp/recording.json | jq '[.[] | select(.type == "webhook")] | group_by(.platform) | .[] | {platform: .[0].platform, count: length}'
# Extract and analyze platform-specific webhooks
cat /tmp/recording.json | jq '[.[] | select(.type == "webhook" and .platform == "teams") | .body | fromjson]' > /tmp/teams-webhooks.json
cat /tmp/recording.json | jq '[.[] | select(.type == "webhook" and .platform == "slack") | .body | fromjson]' > /tmp/slack-webhooks.json
cat /tmp/recording.json | jq '[.[] | select(.type == "webhook" and .platform == "gchat") | .body | fromjson]' > /tmp/gchat-webhooks.json
# Inspect specific webhook fields (e.g., Teams channelData)
cat /tmp/teams-webhooks.json | jq '[.[] | {type, text, channelData, value}]'
Environment Variables
Key env vars used (see turbo.json for full list):
SLACK_BOT_TOKEN,SLACK_SIGNING_SECRET- Slack credentialsTEAMS_APP_ID,TEAMS_APP_PASSWORD,TEAMS_APP_TENANT_ID- Teams credentialsGOOGLE_CHAT_CREDENTIALSorGOOGLE_CHAT_USE_ADC- Google Chat authREDIS_URL- Redis connection for state adapterBOT_USERNAME- Default bot username