chat 4.18.0 → 4.19.0

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