chat 4.13.0 → 4.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +19 -31
  2. package/dist/{chunk-WKJEG4FE.js → chunk-THM4ACIE.js} +12 -4
  3. package/dist/chunk-THM4ACIE.js.map +1 -0
  4. package/dist/index.d.ts +409 -415
  5. package/dist/index.js +63 -29
  6. package/dist/index.js.map +1 -1
  7. package/dist/{jsx-runtime-COVsDskT.d.ts → jsx-runtime-Bdt1Dwzf.d.ts} +71 -71
  8. package/dist/jsx-runtime.d.ts +1 -1
  9. package/dist/jsx-runtime.js +1 -1
  10. package/docs/actions.mdx +98 -0
  11. package/docs/adapters/discord.mdx +217 -0
  12. package/docs/adapters/gchat.mdx +232 -0
  13. package/docs/adapters/github.mdx +225 -0
  14. package/docs/adapters/index.mdx +110 -0
  15. package/docs/adapters/linear.mdx +207 -0
  16. package/docs/adapters/meta.json +12 -0
  17. package/docs/adapters/slack.mdx +293 -0
  18. package/docs/adapters/teams.mdx +225 -0
  19. package/docs/api/cards.mdx +217 -0
  20. package/docs/api/channel.mdx +176 -0
  21. package/docs/api/chat.mdx +469 -0
  22. package/docs/api/index.mdx +29 -0
  23. package/docs/api/markdown.mdx +235 -0
  24. package/docs/api/message.mdx +163 -0
  25. package/docs/api/meta.json +14 -0
  26. package/docs/api/modals.mdx +222 -0
  27. package/docs/api/postable-message.mdx +166 -0
  28. package/docs/api/thread.mdx +186 -0
  29. package/docs/cards.mdx +213 -0
  30. package/docs/direct-messages.mdx +56 -0
  31. package/docs/emoji.mdx +77 -0
  32. package/docs/ephemeral-messages.mdx +77 -0
  33. package/docs/error-handling.mdx +147 -0
  34. package/docs/files.mdx +77 -0
  35. package/docs/getting-started.mdx +12 -0
  36. package/docs/guides/code-review-hono.mdx +248 -0
  37. package/docs/guides/discord-nuxt.mdx +237 -0
  38. package/docs/guides/meta.json +4 -0
  39. package/docs/guides/slack-nextjs.mdx +245 -0
  40. package/docs/index.mdx +92 -0
  41. package/docs/meta.json +20 -0
  42. package/docs/modals.mdx +208 -0
  43. package/docs/posting-messages.mdx +177 -0
  44. package/docs/slash-commands.mdx +110 -0
  45. package/docs/state/index.mdx +31 -0
  46. package/docs/state/ioredis.mdx +81 -0
  47. package/docs/state/memory.mdx +52 -0
  48. package/docs/state/meta.json +9 -0
  49. package/docs/state/redis.mdx +93 -0
  50. package/docs/streaming.mdx +99 -0
  51. package/docs/usage.mdx +338 -0
  52. package/package.json +10 -10
  53. package/dist/chunk-WKJEG4FE.js.map +0 -1
@@ -0,0 +1,207 @@
1
+ ---
2
+ title: Linear
3
+ description: Configure the Linear adapter to respond to @mentions in issue comment threads.
4
+ type: integration
5
+ prerequisites:
6
+ - /docs/getting-started
7
+ ---
8
+
9
+ The Linear adapter treats issue comments as messages and issues as threads.
10
+
11
+ ## Installation
12
+
13
+ ```sh title="Terminal"
14
+ pnpm add @chat-adapter/linear
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```typescript title="lib/bot.ts" lineNumbers
20
+ import { Chat } from "chat";
21
+ import { createLinearAdapter } from "@chat-adapter/linear";
22
+
23
+ const bot = new Chat({
24
+ userName: "my-bot",
25
+ adapters: {
26
+ linear: createLinearAdapter({
27
+ apiKey: process.env.LINEAR_API_KEY!,
28
+ webhookSecret: process.env.LINEAR_WEBHOOK_SECRET!,
29
+ userName: "my-bot",
30
+ }),
31
+ },
32
+ });
33
+
34
+ bot.onNewMention(async (thread, message) => {
35
+ await thread.post("Hello from Linear!");
36
+ });
37
+ ```
38
+
39
+ ## Authentication
40
+
41
+ ### Option A: Personal API key
42
+
43
+ Best for personal projects, testing, or single-workspace bots. Actions are attributed to you as an individual.
44
+
45
+ 1. Go to [Settings > Security & Access](https://linear.app/settings/account/security)
46
+ 2. Under **Personal API keys**, click **Create key**
47
+ 3. Select **Only select permissions** and enable Create issues, Create comments
48
+ 4. Choose team access
49
+ 5. Click **Create** and set `LINEAR_API_KEY`
50
+
51
+ ```typescript title="lib/bot.ts" lineNumbers
52
+ createLinearAdapter({
53
+ apiKey: process.env.LINEAR_API_KEY!,
54
+ webhookSecret: process.env.LINEAR_WEBHOOK_SECRET!,
55
+ userName: "my-bot",
56
+ });
57
+ ```
58
+
59
+ ### Option B: OAuth application (recommended)
60
+
61
+ The bot gets its own identity in Linear. The adapter handles token management internally.
62
+
63
+ 1. Go to [Settings > API > Applications](https://linear.app/settings/api/applications/new)
64
+ 2. Create an OAuth2 application with your bot's name and icon
65
+ 3. **Enable client credentials tokens** in the app settings
66
+ 4. Note the **Client ID** and **Client Secret**
67
+
68
+ ```typescript title="lib/bot.ts" lineNumbers
69
+ createLinearAdapter({
70
+ clientId: process.env.LINEAR_CLIENT_ID!,
71
+ clientSecret: process.env.LINEAR_CLIENT_SECRET!,
72
+ webhookSecret: process.env.LINEAR_WEBHOOK_SECRET!,
73
+ userName: "my-bot",
74
+ });
75
+ ```
76
+
77
+ The adapter uses the client credentials grant to obtain tokens automatically. Tokens are valid for 30 days and auto-refresh when expired.
78
+
79
+ ### Making the bot @-mentionable (optional)
80
+
81
+ To make the bot appear in Linear's `@` mention dropdown as an Agent:
82
+
83
+ 1. In your OAuth app settings, enable **Agent session events** under webhooks
84
+ 2. Have a workspace admin install the app with `actor=app` and the `app:mentionable` scope:
85
+
86
+ ```
87
+ https://linear.app/oauth/authorize?
88
+ client_id=your_client_id&
89
+ redirect_uri=https://your-domain.com/callback&
90
+ response_type=code&
91
+ scope=read,write,comments:create,app:mentionable&
92
+ actor=app
93
+ ```
94
+
95
+ See the [Linear Agents docs](https://linear.app/developers/agents) for full details.
96
+
97
+ ## Webhook setup
98
+
99
+ <Callout type="info">
100
+ Webhook management requires workspace admin access. If you don't see the API settings page, ask a workspace admin to create the webhook for you.
101
+ </Callout>
102
+
103
+ 1. Go to **Settings > API** and click **Create webhook**
104
+ 2. Fill in:
105
+ - **Label**: A descriptive name (e.g., "Chat Bot")
106
+ - **URL**: `https://your-domain.com/api/webhooks/linear`
107
+ 3. Copy the **Signing secret** as `LINEAR_WEBHOOK_SECRET`
108
+ 4. Under **Data change events**, select:
109
+ - **Comments** (required)
110
+ - **Issues** (recommended)
111
+ - **Emoji reactions** (optional)
112
+ 5. Under **Team selection**, choose **All public teams** or a specific team
113
+ 6. Click **Create webhook**
114
+
115
+ ## Thread model
116
+
117
+ Linear has two levels of comment threading:
118
+
119
+ | Type | Description | Thread ID format |
120
+ |------|-------------|-----------------|
121
+ | Issue-level | Top-level comments on an issue | `linear:{issueId}` |
122
+ | Comment thread | Replies nested under a specific comment | `linear:{issueId}:c:{commentId}` |
123
+
124
+ When a user writes a comment, the bot replies within the same comment thread.
125
+
126
+ ## Reactions
127
+
128
+ | SDK emoji | Linear emoji |
129
+ |-----------|-------------|
130
+ | `thumbs_up` | 👍 |
131
+ | `thumbs_down` | 👎 |
132
+ | `heart` | ❤️ |
133
+ | `fire` | 🔥 |
134
+ | `rocket` | 🚀 |
135
+ | `eyes` | 👀 |
136
+ | `sparkles` | ✨ |
137
+ | `wave` | 👋 |
138
+
139
+ ## Configuration
140
+
141
+ | Option | Required | Description |
142
+ |--------|----------|-------------|
143
+ | `apiKey` | Yes* | Personal API key |
144
+ | `clientId` | Yes* | OAuth app client ID |
145
+ | `clientSecret` | Yes* | OAuth app client secret |
146
+ | `accessToken` | Yes* | Pre-obtained OAuth access token |
147
+ | `webhookSecret` | Yes | Webhook signing secret for verification |
148
+ | `userName` | Yes | Bot display name for @mention detection |
149
+
150
+ *One of `apiKey`, `clientId`/`clientSecret`, or `accessToken` is required.
151
+
152
+ ## Environment variables
153
+
154
+ ```bash title=".env.local"
155
+ # API Key auth
156
+ LINEAR_API_KEY=lin_api_xxxxxxxxxxxx
157
+
158
+ # OR OAuth app auth
159
+ LINEAR_CLIENT_ID=your-client-id
160
+ LINEAR_CLIENT_SECRET=your-client-secret
161
+
162
+ # Required
163
+ LINEAR_WEBHOOK_SECRET=your-webhook-secret
164
+ ```
165
+
166
+ ## Features
167
+
168
+ | Feature | Supported |
169
+ |---------|-----------|
170
+ | Mentions | Yes |
171
+ | Reactions (add) | Yes |
172
+ | Cards | Markdown |
173
+ | Modals | No |
174
+ | Streaming | No |
175
+ | DMs | No |
176
+ | File uploads | No |
177
+ | Typing indicator | No |
178
+ | Message history | Yes |
179
+
180
+ ## Limitations
181
+
182
+ - **No typing indicators** — Linear doesn't support typing indicators
183
+ - **No streaming** — Messages posted in full (editing supported for updates)
184
+ - **No DMs** — Linear doesn't have direct messages
185
+ - **No modals** — Linear doesn't support interactive modals
186
+ - **Action buttons** — Rendered as text; use link buttons for clickable actions
187
+ - **Remove reaction** — Requires reaction ID lookup (not directly supported)
188
+
189
+ ## Troubleshooting
190
+
191
+ ### "Invalid signature" error
192
+
193
+ - Verify `LINEAR_WEBHOOK_SECRET` matches the secret from your webhook configuration
194
+ - The webhook secret is shown only once at creation — regenerate if lost
195
+
196
+ ### Bot not responding to mentions
197
+
198
+ - Verify webhook events are configured with **Comments** resource type
199
+ - Check that the webhook URL is correct and accessible
200
+ - Ensure the `userName` config matches how users mention the bot
201
+ - Linear may auto-disable webhooks after repeated failures
202
+
203
+ ### "Webhook expired" error
204
+
205
+ - Webhook timestamp is too old (> 5 minutes)
206
+ - Usually indicates a delivery delay or clock skew
207
+ - Check that your server time is synchronized
@@ -0,0 +1,12 @@
1
+ {
2
+ "title": "Adapters",
3
+ "pages": [
4
+ "index",
5
+ "slack",
6
+ "teams",
7
+ "gchat",
8
+ "discord",
9
+ "github",
10
+ "linear"
11
+ ]
12
+ }
@@ -0,0 +1,293 @@
1
+ ---
2
+ title: Slack
3
+ description: Configure the Slack adapter for single-workspace or multi-workspace OAuth deployments.
4
+ type: integration
5
+ prerequisites:
6
+ - /docs/getting-started
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```sh title="Terminal"
12
+ pnpm add @chat-adapter/slack
13
+ ```
14
+
15
+ ## Single-workspace mode
16
+
17
+ For bots deployed to a single Slack workspace:
18
+
19
+ ```typescript title="lib/bot.ts" lineNumbers
20
+ import { Chat } from "chat";
21
+ import { createSlackAdapter } from "@chat-adapter/slack";
22
+
23
+ const bot = new Chat({
24
+ userName: "mybot",
25
+ adapters: {
26
+ slack: createSlackAdapter({
27
+ botToken: process.env.SLACK_BOT_TOKEN!,
28
+ signingSecret: process.env.SLACK_SIGNING_SECRET!,
29
+ }),
30
+ },
31
+ });
32
+
33
+ bot.onNewMention(async (thread, message) => {
34
+ await thread.post("Hello from Slack!");
35
+ });
36
+ ```
37
+
38
+ ## Multi-workspace mode
39
+
40
+ For apps installed across multiple Slack workspaces via OAuth, omit `botToken` and provide OAuth credentials instead. The adapter resolves tokens dynamically from your state adapter using the `team_id` from incoming webhooks.
41
+
42
+ ```typescript title="lib/bot.ts" lineNumbers
43
+ import { createSlackAdapter } from "@chat-adapter/slack";
44
+ import { createRedisState } from "@chat-adapter/state-redis";
45
+
46
+ const slackAdapter = createSlackAdapter({
47
+ signingSecret: process.env.SLACK_SIGNING_SECRET!,
48
+ clientId: process.env.SLACK_CLIENT_ID!,
49
+ clientSecret: process.env.SLACK_CLIENT_SECRET!,
50
+ encryptionKey: process.env.SLACK_ENCRYPTION_KEY,
51
+ });
52
+
53
+ const bot = new Chat({
54
+ userName: "mybot",
55
+ adapters: { slack: slackAdapter },
56
+ state: createRedisState({ url: process.env.REDIS_URL! }),
57
+ });
58
+ ```
59
+
60
+ ### OAuth callback
61
+
62
+ The adapter handles the full Slack OAuth V2 exchange. Point your OAuth redirect URL to a route that calls `handleOAuthCallback`:
63
+
64
+ ```typescript title="app/api/slack/install/callback/route.ts"
65
+ import { slackAdapter } from "@/lib/bot";
66
+
67
+ export async function GET(request: Request) {
68
+ const { teamId } = await slackAdapter.handleOAuthCallback(request);
69
+ return new Response(`Installed for team ${teamId}!`);
70
+ }
71
+ ```
72
+
73
+ ### Using the adapter outside webhooks
74
+
75
+ During webhook handling, the adapter resolves tokens automatically from `team_id`. Outside that context (e.g. cron jobs or background workers), use `getInstallation` and `withBotToken`:
76
+
77
+ ```typescript title="lib/bot.ts" lineNumbers
78
+ const install = await slackAdapter.getInstallation(teamId);
79
+ if (!install) throw new Error("Workspace not installed");
80
+
81
+ await slackAdapter.withBotToken(install.botToken, async () => {
82
+ const thread = bot.thread("slack:C12345:1234567890.123456");
83
+ await thread.post("Hello from a cron job!");
84
+ });
85
+ ```
86
+
87
+ `withBotToken` uses `AsyncLocalStorage` under the hood, so concurrent calls with different tokens are isolated.
88
+
89
+ ### Removing installations
90
+
91
+ ```typescript title="lib/bot.ts"
92
+ await slackAdapter.deleteInstallation(teamId);
93
+ ```
94
+
95
+ ### Token encryption
96
+
97
+ Pass a base64-encoded 32-byte key as `encryptionKey` to encrypt bot tokens at rest using AES-256-GCM:
98
+
99
+ ```sh title="Terminal"
100
+ openssl rand -base64 32
101
+ ```
102
+
103
+ When `encryptionKey` is set, `setInstallation()` encrypts the token before storing and `getInstallation()` decrypts it transparently.
104
+
105
+ ## Slack app setup
106
+
107
+ ### 1. Create a Slack app from manifest
108
+
109
+ 1. Go to [api.slack.com/apps](https://api.slack.com/apps)
110
+ 2. Click **Create New App** then **From an app manifest**
111
+ 3. Select your workspace and paste the following manifest:
112
+
113
+ ```yaml title="slack-manifest.yml"
114
+ display_information:
115
+ name: My Bot
116
+ description: A bot built with chat-sdk
117
+
118
+ features:
119
+ bot_user:
120
+ display_name: My Bot
121
+ always_online: true
122
+
123
+ oauth_config:
124
+ scopes:
125
+ bot:
126
+ - app_mentions:read
127
+ - channels:history
128
+ - channels:read
129
+ - chat:write
130
+ - groups:history
131
+ - groups:read
132
+ - im:history
133
+ - im:read
134
+ - mpim:history
135
+ - mpim:read
136
+ - reactions:read
137
+ - reactions:write
138
+ - users:read
139
+
140
+ settings:
141
+ event_subscriptions:
142
+ request_url: https://your-domain.com/api/webhooks/slack
143
+ bot_events:
144
+ - app_mention
145
+ - message.channels
146
+ - message.groups
147
+ - message.im
148
+ - message.mpim
149
+ - assistant_thread_started
150
+ - assistant_thread_context_changed
151
+ interactivity:
152
+ is_enabled: true
153
+ request_url: https://your-domain.com/api/webhooks/slack
154
+ org_deploy_enabled: false
155
+ socket_mode_enabled: false
156
+ token_rotation_enabled: false
157
+ ```
158
+
159
+ 4. Replace `https://your-domain.com/api/webhooks/slack` with your deployed webhook URL
160
+ 5. Click **Create**
161
+
162
+ ### 2. Get credentials
163
+
164
+ After creating the app, go to **Basic Information** → **App Credentials** and copy:
165
+
166
+ - **Signing Secret** as `SLACK_SIGNING_SECRET`
167
+ - **Client ID** as `SLACK_CLIENT_ID` (multi-workspace only)
168
+ - **Client Secret** as `SLACK_CLIENT_SECRET` (multi-workspace only)
169
+
170
+ **Single workspace:** Go to **OAuth & Permissions**, click **Install to Workspace**, and copy the **Bot User OAuth Token** (`xoxb-...`) as `SLACK_BOT_TOKEN`.
171
+
172
+ **Multi-workspace:** Enable **Manage Distribution** under **Basic Information** and set up an OAuth redirect URL pointing to your callback route.
173
+
174
+ ### 3. Configure slash commands (optional)
175
+
176
+ 1. Go to **Slash Commands** in your app settings
177
+ 2. Click **Create New Command**
178
+ 3. Set **Command** (e.g., `/feedback`)
179
+ 4. Set **Request URL** to `https://your-domain.com/api/webhooks/slack`
180
+ 5. Add a description and click **Save**
181
+
182
+ ## Configuration
183
+
184
+ | Option | Required | Description |
185
+ |--------|----------|-------------|
186
+ | `botToken` | No | Bot token (`xoxb-...`). Required for single-workspace, omit for multi-workspace |
187
+ | `signingSecret` | Yes | Signing secret for webhook verification |
188
+ | `clientId` | No | App client ID (required for multi-workspace OAuth) |
189
+ | `clientSecret` | No | App client secret (required for multi-workspace OAuth) |
190
+ | `encryptionKey` | No | Base64-encoded 32-byte AES-256-GCM key for encrypting stored tokens |
191
+
192
+ ## Environment variables
193
+
194
+ ```bash title=".env.local"
195
+ SLACK_BOT_TOKEN=xoxb-... # Single-workspace only
196
+ SLACK_SIGNING_SECRET=...
197
+ SLACK_CLIENT_ID=... # Multi-workspace only
198
+ SLACK_CLIENT_SECRET=... # Multi-workspace only
199
+ SLACK_ENCRYPTION_KEY=... # Optional, for token encryption
200
+ ```
201
+
202
+ ## Features
203
+
204
+ | Feature | Supported |
205
+ |---------|-----------|
206
+ | Mentions | Yes |
207
+ | Reactions (add/remove) | Yes |
208
+ | Cards (Block Kit) | Yes |
209
+ | Modals | Yes |
210
+ | Slash commands | Yes |
211
+ | Streaming | Native API |
212
+ | DMs | Yes |
213
+ | Ephemeral messages | Yes (native) |
214
+ | File uploads | Yes |
215
+ | Typing indicator | Yes |
216
+ | Message history | Yes |
217
+ | Assistants API | Yes |
218
+ | App Home tab | Yes |
219
+
220
+ ## Slack Assistants API
221
+
222
+ The adapter supports Slack's [Assistants API](https://api.slack.com/docs/apps/ai) for building AI-powered assistant experiences. This enables suggested prompts, status indicators, and thread titles in assistant DM threads.
223
+
224
+ ### Event handlers
225
+
226
+ Register handlers on the `Chat` instance:
227
+
228
+ ```typescript title="lib/bot.ts" lineNumbers
229
+ bot.onAssistantThreadStarted(async (event) => {
230
+ const slack = bot.getAdapter("slack") as SlackAdapter;
231
+ await slack.setSuggestedPrompts(event.channelId, event.threadTs, [
232
+ { title: "Summarize", message: "Summarize this channel" },
233
+ { title: "Draft", message: "Help me draft a message" },
234
+ ]);
235
+ });
236
+
237
+ bot.onAssistantContextChanged(async (event) => {
238
+ // User navigated to a different channel with the assistant panel open
239
+ });
240
+ ```
241
+
242
+ ### Adapter methods
243
+
244
+ The `SlackAdapter` exposes these methods for the Assistants API:
245
+
246
+ | Method | Description |
247
+ |--------|-------------|
248
+ | `setSuggestedPrompts(channelId, threadTs, prompts, title?)` | Show prompt suggestions in the thread |
249
+ | `setAssistantStatus(channelId, threadTs, status)` | Show a thinking/status indicator |
250
+ | `setAssistantTitle(channelId, threadTs, title)` | Set the thread title (shown in History) |
251
+ | `publishHomeView(userId, view)` | Publish a Home tab view for a user |
252
+
253
+ ### Required scopes and events
254
+
255
+ Add these to your Slack app manifest for Assistants API support:
256
+
257
+ ```yaml title="slack-manifest.yml"
258
+ oauth_config:
259
+ scopes:
260
+ bot:
261
+ - assistant:write
262
+
263
+ settings:
264
+ event_subscriptions:
265
+ bot_events:
266
+ - assistant_thread_started
267
+ - assistant_thread_context_changed
268
+ ```
269
+
270
+ ### Stream with stop blocks
271
+
272
+ When streaming in an assistant thread, you can attach Block Kit elements to the final message:
273
+
274
+ ```typescript title="lib/bot.ts"
275
+ await thread.stream(textStream, {
276
+ stopBlocks: [
277
+ { type: "actions", elements: [{ type: "button", text: { type: "plain_text", text: "Retry" }, action_id: "retry" }] },
278
+ ],
279
+ });
280
+ ```
281
+
282
+ ## Troubleshooting
283
+
284
+ ### "Invalid signature" error
285
+
286
+ - Verify `SLACK_SIGNING_SECRET` is correct
287
+ - Check that the request timestamp is within 5 minutes (clock sync issue)
288
+
289
+ ### Bot not responding to messages
290
+
291
+ - Verify event subscriptions are configured
292
+ - Check that the bot has been added to the channel
293
+ - Ensure the webhook URL is correct and accessible