mirror of
https://github.com/vercel/chat.git
synced 2026-09-14 18:32:29 +08:00
d2ffcc2cbe
We've acquired `chat` on npm. This plan covers renaming all packages and setting up automated publishing.
| Current Name | New Name | Version |
|--------------|----------|---------|
| `chat-sdk` | `chat` | 4.0.0 |
| `@chat-sdk/slack` | `@chat-adapter/slack` | 4.0.0 |
| `@chat-sdk/gchat` | `@chat-adapter/gchat` | 4.0.0 |
| `@chat-sdk/teams` | `@chat-adapter/teams` | 4.0.0 |
| `@chat-sdk/state-memory` | `@chat-adapter/state-memory` | 4.0.0 |
| `@chat-sdk/state-redis` | `@chat-adapter/state-redis` | 4.0.0 |
| `@chat-sdk/state-ioredis` | `@chat-adapter/state-ioredis` | 4.0.0 |
1. **Main package** (`packages/chat-sdk/package.json`):
- Change `"name": "chat-sdk"` → `"name": "chat"`
- Change `"version": "0.1.0"` → `"version": "4.0.0"`
2. **Adapter packages**:
- `packages/adapter-slack/package.json`: `@chat-sdk/slack` → `@chat-adapter/slack`
- `packages/adapter-gchat/package.json`: `@chat-sdk/gchat` → `@chat-adapter/gchat`
- `packages/adapter-teams/package.json`: `@chat-sdk/teams` → `@chat-adapter/teams`
- Update all versions to `4.0.0`
- Update dependency on `chat-sdk` → `chat`
3. **State packages**:
- `packages/state-memory/package.json`: `@chat-sdk/state-memory` → `@chat-adapter/state-memory`
- `packages/state-redis/package.json`: `@chat-sdk/state-redis` → `@chat-adapter/state-redis`
- `packages/state-ioredis/package.json`: `@chat-sdk/state-ioredis` → `@chat-adapter/state-ioredis`
- Update all versions to `4.0.0`
- Update dependency on `chat-sdk` → `chat`
Update `peerDependencies` and `dependencies` in each package:
```json
// Before
"peerDependencies": {
"chat-sdk": "workspace:*"
}
// After
"peerDependencies": {
"chat": "workspace:*"
}
```
Search and replace across the codebase:
| Find | Replace |
|------|---------|
| `from "chat-sdk"` | `from "chat"` |
| `from 'chat-sdk'` | `from 'chat'` |
| `import("chat-sdk")` | `import("chat")` |
| `from "@chat-sdk/slack"` | `from "@chat-adapter/slack"` |
| `from "@chat-sdk/gchat"` | `from "@chat-adapter/gchat"` |
| `from "@chat-sdk/teams"` | `from "@chat-adapter/teams"` |
| `from "@chat-sdk/state-memory"` | `from "@chat-adapter/state-memory"` |
| `from "@chat-sdk/state-redis"` | `from "@chat-adapter/state-redis"` |
| `from "@chat-sdk/state-ioredis"` | `from "@chat-adapter/state-ioredis"` |
Update any references to old package names in:
- `pnpm-workspace.yaml`
- `turbo.json` (task filters)
- Root `package.json` scripts
1. **README.md files** in each package
2. **Examples** (`examples/nextjs-chat/`)
3. **AGENTS.md** and other docs
4. **JSDoc comments** referencing package names
1. **Install changesets**:
```bash
pnpm add -D @changesets/cli
pnpm changeset init
```
2. **Configure `.changeset/config.json`**:
```json
{
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [
["chat", "@chat-adapter/*"]
],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["example-nextjs-chat"]
}
```
3. **Add GitHub Action** (`.github/workflows/release.yml`):
```yaml
name: Release
on:
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install
- run: pnpm build
- run: pnpm test
- name: Create Release Pull Request or Publish
uses: changesets/action@v1
with:
publish: pnpm changeset publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
```
4. **Add publish config to each package.json**:
```json
"publishConfig": {
"access": "public"
}
```
1. Run full build: `pnpm build`
2. Run typecheck: `pnpm typecheck`
3. Run lint: `pnpm lint`
4. Run tests: `pnpm test`
5. Test local linking in example app
| File | Changes |
|------|---------|
| `packages/chat-sdk/package.json` | Rename to `chat`, version 4.0.0 |
| `packages/adapter-slack/package.json` | Rename to `@chat-adapter/slack`, update deps |
| `packages/adapter-gchat/package.json` | Rename to `@chat-adapter/gchat`, update deps |
| `packages/adapter-teams/package.json` | Rename to `@chat-adapter/teams`, update deps |
| `packages/state-memory/package.json` | Rename to `@chat-adapter/state-memory`, update deps |
| `packages/state-redis/package.json` | Rename to `@chat-adapter/state-redis`, update deps |
| `packages/state-ioredis/package.json` | Rename to `@chat-adapter/state-ioredis`, update deps |
| `examples/nextjs-chat/package.json` | Update all dependencies |
| `packages/integration-tests/package.json` | Update all dependencies |
| `turbo.json` | Update package references |
| All `*.ts` files | Update import statements |
| All `README.md` files | Update package names in docs |
| `.changeset/config.json` | Create new |
| `.github/workflows/release.yml` | Create new |
1. Update all `package.json` files (names, versions, dependencies)
2. Run `pnpm install` to update lockfile
3. Update all import statements in source files
4. Update all import statements in test files
5. Update documentation
6. Set up changesets
7. Run full validation
8. Create initial changeset for 4.0.0 release
9. Commit and push
If issues arise:
1. Git revert the rename commit
2. Run `pnpm install` to restore lockfile
3. Previous npm versions remain available
4.2 KiB
4.2 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
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