experimental-ash 0.24.1 → 0.24.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 (126) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/src/chunks/authored-module-loader-DcCfCiBm.js +4 -0
  3. package/dist/src/chunks/client-DLHAGI2g.js +4 -0
  4. package/dist/src/chunks/dev-authored-source-watcher-CBID_Dwh.js +1 -0
  5. package/dist/src/chunks/{errors-DsO9xmQL.js → errors-HYWjHxV6.js} +1 -1
  6. package/dist/src/chunks/{gray-matter-BxS7ZG-J.js → gray-matter-D-9jHwOT.js} +4 -4
  7. package/dist/src/chunks/host-zBy9FyyX.js +70 -0
  8. package/dist/src/chunks/{jsdist-M7JFZoA4.js → jsdist-BkeWZ7EZ.js} +61 -61
  9. package/dist/src/chunks/package-HUaeub_D.js +1 -0
  10. package/dist/src/chunks/{paths-jcVjBqc3.js → paths-CebY5GCi.js} +2 -2
  11. package/dist/src/chunks/{picocolors-Bq-tZK9u.js → picocolors-aAkqW4On.js} +1 -1
  12. package/dist/src/chunks/token-D98SQdvs.js +1 -0
  13. package/dist/src/chunks/{url-BVRhVE2O.js → url-JdCGA634.js} +1 -1
  14. package/dist/src/cli/commands/info.js +1 -1
  15. package/dist/src/cli/dev/environment.d.ts +16 -2
  16. package/dist/src/cli/dev/environment.js +1 -1
  17. package/dist/src/cli/dev/input-requests.js +1 -1
  18. package/dist/src/cli/dev/repl.js +3 -3
  19. package/dist/src/cli/dev/url.js +1 -1
  20. package/dist/src/cli/run.js +1 -1
  21. package/dist/src/cli/ui/output.js +1 -1
  22. package/dist/src/client/index.d.ts +1 -0
  23. package/dist/src/client/index.js +1 -0
  24. package/dist/src/compiled/.vendor-stamp.json +7 -6
  25. package/dist/src/compiled/@ai-sdk/anthropic/index.js +1 -1
  26. package/dist/src/compiled/@ai-sdk/google/index.js +1 -1
  27. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  28. package/dist/src/compiled/@ai-sdk/openai/index.js +1 -1
  29. package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
  30. package/dist/src/compiled/@chat-adapter/slack/_slack-web-api.d.ts +7 -0
  31. package/dist/src/compiled/@chat-adapter/slack/index.d.ts +418 -109
  32. package/dist/src/compiled/@chat-adapter/slack/index.js +31 -27
  33. package/dist/src/compiled/@chat-adapter/slack/package.json +1 -1
  34. package/dist/src/compiled/@chat-adapter/state-memory/index.d.ts +8 -2
  35. package/dist/src/compiled/@chat-adapter/state-memory/index.js +1 -1
  36. package/dist/src/compiled/@chat-adapter/state-memory/package.json +1 -1
  37. package/dist/src/compiled/@opentelemetry/api/index.js +1 -1
  38. package/dist/src/compiled/@vercel/sandbox/index.js +19 -17
  39. package/dist/src/compiled/@vercel/sandbox/package.json +1 -1
  40. package/dist/src/compiled/@workflow/core/index.js +2 -2
  41. package/dist/src/compiled/@workflow/core/runtime.js +22 -22
  42. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  43. package/dist/src/compiled/@workflow/errors/index.js +1 -1
  44. package/dist/src/compiled/_chunks/node/auth-ZhCJAHxl.js +2 -0
  45. package/dist/src/compiled/_chunks/node/{dist-BdWHjlRQ.js → dist-BQYUcBqu.js} +31 -31
  46. package/dist/src/compiled/_chunks/node/{chunk-Dd2tEFlW.js → dist-BdTs18CF.js} +1 -1
  47. package/dist/src/compiled/_chunks/node/retry-DkR2H1Y0.js +1 -0
  48. package/dist/src/compiled/_chunks/node/token-CoIbMZkq.js +1 -0
  49. package/dist/src/compiled/_chunks/node/{version-BMyZn3Y2.js → version-D4IYmfaS.js} +1 -1
  50. package/dist/src/compiled/_chunks/workflow/coerce-BhzIW-Hm.js +1 -0
  51. package/dist/src/compiled/_chunks/workflow/{compat-CIROS3w4.js → compat-DcEvieoj.js} +1 -1
  52. package/dist/src/compiled/_chunks/workflow/{core-DOVmxHH8.js → core-XWIi7wKc.js} +3 -3
  53. package/dist/src/compiled/_chunks/workflow/{dist-C7wPwOI9.js → dist-DO14ZaQj.js} +1 -1
  54. package/dist/src/compiled/_chunks/workflow/{dist-CpUQh3NH.js → dist-DZZY3Zyp.js} +1 -1
  55. package/dist/src/compiled/_chunks/workflow/resume-hook-DOMbNs-S.js +51 -0
  56. package/dist/src/compiled/_chunks/workflow/{schemas-DFZoEyCn.js → schemas-DmgDnhW3.js} +1 -1
  57. package/dist/src/compiled/_chunks/workflow/sleep-CRjce49s.js +1 -0
  58. package/dist/src/compiled/_chunks/workflow/{src-ClRYdO4-.js → src-B54rYDvB.js} +1 -1
  59. package/dist/src/compiled/_chunks/workflow/symbols-D8paKc8P.js +9 -0
  60. package/dist/src/compiled/_chunks/workflow/{token-CsNmv7KW.js → token-D9z1dMB6.js} +1 -1
  61. package/dist/src/compiled/_chunks/workflow/{token-j5Cl4rrs.js → token-DV7rQw_t.js} +1 -1
  62. package/dist/src/compiled/chat/index.d.ts +6 -3143
  63. package/dist/src/compiled/chat/index.js +1 -1
  64. package/dist/src/compiled/chat/{jsx-runtime-DxGwoLu2.d.ts → jsx-runtime-CFq1K_Ve.d.ts} +1 -1
  65. package/dist/src/compiled/chat/package.json +1 -1
  66. package/dist/src/compiled/jose/index.js +2 -2
  67. package/dist/src/compiled/jsonc-parser/LICENSE.md +21 -0
  68. package/dist/src/compiled/jsonc-parser/index.d.ts +13 -0
  69. package/dist/src/compiled/jsonc-parser/index.js +15 -0
  70. package/dist/src/compiled/jsonc-parser/package.json +7 -0
  71. package/dist/src/compiled/just-bash/index.js +773 -773
  72. package/dist/src/compiled/just-bash/package.json +1 -1
  73. package/dist/src/compiled/turndown/index.js +1 -1
  74. package/dist/src/compiled/zod/index.js +1 -1
  75. package/dist/src/compiled/zod-validation-error/index.js +1 -1
  76. package/dist/src/evals/cli/eval.js +1 -1
  77. package/dist/src/evals/loaders/yaml.js +1 -1
  78. package/dist/src/evals/runner/discover.js +1 -1
  79. package/dist/src/evals/runner/execute-suite.js +1 -1
  80. package/dist/src/evals/runner/reporters/console.js +1 -1
  81. package/dist/src/evals/scorers/autoevals-client.js +1 -1
  82. package/dist/src/evals/scorers/autoevals.js +1 -1
  83. package/dist/src/evals/scorers/json.js +1 -1
  84. package/dist/src/evals/scorers/run.js +1 -1
  85. package/dist/src/evals/scorers/sql.js +1 -1
  86. package/dist/src/evals/scorers/text.js +1 -1
  87. package/dist/src/internal/application/package.js +1 -1
  88. package/dist/src/internal/authored-asset-import-plugin.d.ts +5 -0
  89. package/dist/src/internal/authored-asset-import-plugin.js +141 -0
  90. package/dist/src/internal/authored-module-bundle.d.ts +4 -0
  91. package/dist/src/internal/authored-module-bundle.js +19 -0
  92. package/dist/src/internal/authored-module-loader.d.ts +6 -0
  93. package/dist/src/internal/authored-module-loader.js +114 -125
  94. package/dist/src/internal/authored-package-tsconfig-paths.d.ts +9 -0
  95. package/dist/src/internal/authored-package-tsconfig-paths.js +209 -0
  96. package/dist/src/internal/nitro/host/channel-routes.d.ts +9 -2
  97. package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +12 -1
  98. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +19 -3
  99. package/dist/src/internal/nitro/host/schedule-task-routes.d.ts +7 -3
  100. package/dist/src/internal/nitro/host/start-development-server.js +2 -0
  101. package/package.json +17 -17
  102. package/dist/src/chunks/authored-module-loader-XcFLnl49.js +0 -2
  103. package/dist/src/chunks/client-nshDsWNF.js +0 -4
  104. package/dist/src/chunks/dev-authored-source-watcher-CApkYfee.js +0 -7
  105. package/dist/src/chunks/host-3sfHdmXL.js +0 -65
  106. package/dist/src/chunks/package-DmsQgn4v.js +0 -1
  107. package/dist/src/chunks/prewarm-DslujbK5.js +0 -6
  108. package/dist/src/chunks/token-DtoyQZy2.js +0 -1
  109. package/dist/src/chunks/token-util-CHjOk3A7.js +0 -1
  110. package/dist/src/compiled/_chunks/node/auth-vbe4XEEK.js +0 -2
  111. package/dist/src/compiled/_chunks/node/dist-DMSq2ehP.js +0 -1
  112. package/dist/src/compiled/_chunks/node/retry-BOcy5BbJ.js +0 -1
  113. package/dist/src/compiled/_chunks/node/token-D-BTJHoU.js +0 -1
  114. package/dist/src/compiled/_chunks/workflow/coerce-Dh0wa7P9.js +0 -1
  115. package/dist/src/compiled/_chunks/workflow/context-errors-Bbvvp-li.js +0 -6
  116. package/dist/src/compiled/_chunks/workflow/dist-C_oiE-l7.js +0 -40
  117. package/dist/src/compiled/_chunks/workflow/resume-hook-C3VWUPii.js +0 -12
  118. package/dist/src/compiled/_chunks/workflow/sleep-QTkC1VFe.js +0 -1
  119. package/dist/src/compiled/_chunks/workflow/symbols-QezhMuLg.js +0 -4
  120. package/dist/src/compiled/chat/_workflow-serde.d.ts +0 -5
  121. /package/dist/src/chunks/{chunk-8L7ocgPr.js → chunk-DSjMdhoD.js} +0 -0
  122. /package/dist/src/chunks/{guards-CjJ3lmju.js → guards-26p6sOw3.js} +0 -0
  123. /package/dist/src/chunks/{input-requests-BsBi7_5K.js → input-requests-DJiy6dG9.js} +0 -0
  124. /package/dist/src/chunks/{runtime-model-BWu6M_hq.js → runtime-model-Dh0Nz64z.js} +0 -0
  125. /package/dist/src/chunks/{types-MZUhN0Zy.js → types-DDA2QUED.js} +0 -0
  126. /package/dist/src/compiled/_chunks/workflow/{chunk-DHhdAPOb.js → chunk-DSjMdhoD.js} +0 -0
@@ -1,28 +1,8 @@
1
- import { CardElement, BaseFormatConverter, Root, AdapterPostableMessage, Logger, Adapter, ChatInstance, UserInfo, WebhookOptions, Attachment, RawMessage, EphemeralMessage, ScheduledMessage, ModalElement, EmojiValue, StreamChunk, StreamOptions, FetchOptions, FetchResult, ThreadInfo, Message, ChannelVisibility, ListThreadsOptions, ListThreadsResult, ChannelInfo, FormattedContent } from '#compiled/chat/index.js';
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { WebClient } from './_slack-web-api.js';
3
+ import { BaseFormatConverter, Root, AdapterPostableMessage, CardElement, Logger, Adapter, ChatInstance, UserInfo, WebhookOptions, OptionsLoadResult, ModalResponse, ModalElement, LinkPreview, Message, Attachment, RawMessage, EphemeralMessage, ScheduledMessage, FileUpload, PlanModel, PlanContent, EmojiValue, StreamChunk, StreamOptions, FetchOptions, FetchResult, ThreadInfo, ChannelVisibility, ListThreadsOptions, ListThreadsResult, ChannelInfo, FormattedContent } from '#compiled/chat/index.js';
2
4
  export { EncryptedTokenData, decodeKey } from './_chat-adapter-shared.js';
3
5
 
4
- /**
5
- * Slack Block Kit converter for cross-platform cards.
6
- *
7
- * Converts CardElement to Slack Block Kit blocks.
8
- * @see https://api.slack.com/block-kit
9
- */
10
-
11
- interface SlackBlock {
12
- block_id?: string;
13
- type: string;
14
- [key: string]: unknown;
15
- }
16
- /**
17
- * Convert a CardElement to Slack Block Kit blocks.
18
- */
19
- declare function cardToBlockKit(card: CardElement): SlackBlock[];
20
- /**
21
- * Generate fallback text from a card element.
22
- * Used when blocks aren't supported or for notifications.
23
- */
24
- declare function cardToFallbackText(card: CardElement): string;
25
-
26
6
  /**
27
7
  * Slack format conversion.
28
8
  *
@@ -75,6 +55,62 @@ declare class SlackFormatConverter extends BaseFormatConverter {
75
55
  private nodeToMrkdwn;
76
56
  }
77
57
 
58
+ /**
59
+ * Slack Block Kit converter for cross-platform cards.
60
+ *
61
+ * Converts CardElement to Slack Block Kit blocks.
62
+ * @see https://api.slack.com/block-kit
63
+ */
64
+
65
+ interface SlackBlock {
66
+ block_id?: string;
67
+ type: string;
68
+ [key: string]: unknown;
69
+ }
70
+ /**
71
+ * Convert a CardElement to Slack Block Kit blocks.
72
+ */
73
+ declare function cardToBlockKit(card: CardElement): SlackBlock[];
74
+ /**
75
+ * Generate fallback text from a card element.
76
+ * Used when blocks aren't supported or for notifications.
77
+ */
78
+ declare function cardToFallbackText(card: CardElement): string;
79
+
80
+ /**
81
+ * Slack modal (view) converter.
82
+ * Converts ModalElement to Slack Block Kit view format.
83
+ */
84
+
85
+ interface SlackView {
86
+ blocks: SlackBlock[];
87
+ callback_id: string;
88
+ close?: {
89
+ type: "plain_text";
90
+ text: string;
91
+ };
92
+ notify_on_close?: boolean;
93
+ private_metadata?: string;
94
+ submit?: {
95
+ type: "plain_text";
96
+ text: string;
97
+ };
98
+ title: {
99
+ type: "plain_text";
100
+ text: string;
101
+ };
102
+ type: "modal";
103
+ }
104
+ interface SlackModalResponse {
105
+ errors?: Record<string, string>;
106
+ response_action?: "errors" | "update" | "push" | "clear";
107
+ view?: SlackView;
108
+ }
109
+
110
+ /**
111
+ * Slack adapter types.
112
+ */
113
+
78
114
  type SlackAdapterMode = "webhook" | "socket";
79
115
  /**
80
116
  * Bot token configuration. Can be a static string, or a function that returns
@@ -82,6 +118,12 @@ type SlackAdapterMode = "webhook" | "socket";
82
118
  * token is needed, enabling rotation or lazy retrieval from a secret manager.
83
119
  */
84
120
  type SlackBotToken = string | (() => string | Promise<string>);
121
+ /** Data stored per Slack workspace installation */
122
+ interface SlackInstallation {
123
+ botToken: string;
124
+ botUserId?: string;
125
+ teamName?: string;
126
+ }
85
127
  interface SlackAdapterConfig {
86
128
  /** Override the Slack API base URL (e.g. "https://slack-gov.com/api/" for GovSlack). Defaults to SLACK_API_URL env var. */
87
129
  apiUrl?: string;
@@ -109,6 +151,17 @@ interface SlackAdapterConfig {
109
151
  * Defaults to `slack:installation`. The full key will be `{prefix}:{teamId}`.
110
152
  */
111
153
  installationKeyPrefix?: string;
154
+ /**
155
+ * External installation provider for multi-workspace apps using external
156
+ * token management (e.g., Vercel Connect). When set, the adapter bypasses
157
+ * internal StateAdapter storage for token lookups.
158
+ *
159
+ * For Enterprise Grid org-wide installs, `installationId` will be the
160
+ * enterprise ID; otherwise it will be the team ID.
161
+ */
162
+ installationProvider?: {
163
+ getInstallation: (installationId: string, isEnterpriseInstall: boolean) => Promise<SlackInstallation | null>;
164
+ };
112
165
  /** Logger instance for error reporting. Defaults to ConsoleLogger. */
113
166
  logger?: Logger;
114
167
  /** Connection mode: "webhook" (default) or "socket" */
@@ -129,8 +182,8 @@ interface SlackAdapterConfig {
129
182
  * raw body for downstream parsing — useful when the verifier needs to
130
183
  * canonicalize or substitute the verified payload.
131
184
  *
132
- * When both `signingSecret` and `webhookVerifier` are specified,
133
- * `signingSecret` takes precedence.
185
+ * `webhookVerifier` takes precedence over `signingSecret` and the
186
+ * `SLACK_SIGNING_SECRET` env var; when it is set, those are ignored.
134
187
  *
135
188
  * SECURITY: When this is used in place of `signingSecret`, the built-in
136
189
  * Slack timestamp tolerance check is NOT performed. Implementations are
@@ -140,16 +193,18 @@ interface SlackAdapterConfig {
140
193
  */
141
194
  webhookVerifier?: (request: Request, body: string) => unknown | Promise<unknown>;
142
195
  }
196
+
197
+ /** Envelope for events forwarded from a socket mode listener via HTTP POST */
198
+ interface SlackForwardedSocketEvent {
199
+ body: Record<string, unknown>;
200
+ eventType: string;
201
+ timestamp: number;
202
+ type: "socket_event";
203
+ }
143
204
  interface SlackOAuthCallbackOptions {
144
205
  /** Redirect URI to send to Slack during the OAuth code exchange. */
145
206
  redirectUri?: string;
146
207
  }
147
- /** Data stored per Slack workspace installation */
148
- interface SlackInstallation {
149
- botToken: string;
150
- botUserId?: string;
151
- teamName?: string;
152
- }
153
208
  /** Slack-specific thread ID data */
154
209
  interface SlackThreadId {
155
210
  channel: string;
@@ -229,52 +284,276 @@ interface SlackReactionEvent {
229
284
  type: "reaction_added" | "reaction_removed";
230
285
  user: string;
231
286
  }
287
+ /** Slack assistant_thread_started event payload */
288
+ interface SlackAssistantThreadStartedEvent {
289
+ assistant_thread: {
290
+ user_id: string;
291
+ channel_id: string;
292
+ thread_ts: string;
293
+ context: {
294
+ channel_id?: string;
295
+ team_id?: string;
296
+ enterprise_id?: string;
297
+ thread_entry_point?: string;
298
+ force_search?: boolean;
299
+ };
300
+ };
301
+ event_ts: string;
302
+ type: "assistant_thread_started";
303
+ }
304
+ /** Slack assistant_thread_context_changed event payload */
305
+ interface SlackAssistantContextChangedEvent {
306
+ assistant_thread: {
307
+ user_id: string;
308
+ channel_id: string;
309
+ thread_ts: string;
310
+ context: {
311
+ channel_id?: string;
312
+ team_id?: string;
313
+ enterprise_id?: string;
314
+ thread_entry_point?: string;
315
+ force_search?: boolean;
316
+ };
317
+ };
318
+ event_ts: string;
319
+ type: "assistant_thread_context_changed";
320
+ }
321
+ /** Slack app_home_opened event payload */
322
+ interface SlackAppHomeOpenedEvent {
323
+ channel: string;
324
+ event_ts: string;
325
+ tab: string;
326
+ type: "app_home_opened";
327
+ user: string;
328
+ }
329
+ /** Slack member_joined_channel event payload */
330
+ interface SlackMemberJoinedChannelEvent {
331
+ channel: string;
332
+ channel_type?: string;
333
+ event_ts: string;
334
+ inviter?: string;
335
+ team?: string;
336
+ type: "member_joined_channel";
337
+ user: string;
338
+ }
339
+ /** Slack user_change event payload */
340
+ interface SlackUserChangeEvent {
341
+ event_ts: string;
342
+ type: "user_change";
343
+ user: {
344
+ id: string;
345
+ name?: string;
346
+ real_name?: string;
347
+ profile?: {
348
+ display_name?: string;
349
+ real_name?: string;
350
+ };
351
+ };
352
+ }
353
+ /** Slack webhook payload envelope */
354
+ interface SlackWebhookPayload {
355
+ challenge?: string;
356
+ /** Enterprise ID for Enterprise Grid org-wide installs */
357
+ enterprise_id?: string;
358
+ event?: SlackEvent | SlackReactionEvent | SlackAssistantThreadStartedEvent | SlackAssistantContextChangedEvent | SlackAppHomeOpenedEvent | SlackMemberJoinedChannelEvent | SlackUserChangeEvent;
359
+ event_id?: string;
360
+ event_time?: number;
361
+ /** Whether this is an Enterprise Grid org-wide install */
362
+ is_enterprise_install?: boolean;
363
+ /** Whether this event occurred in an externally shared channel (Slack Connect) */
364
+ is_ext_shared_channel?: boolean;
365
+ team_id?: string;
366
+ type: string;
367
+ }
368
+ /** Slack interactive payload (block_actions) for button clicks */
369
+ interface SlackBlockActionsPayload {
370
+ actions: Array<{
371
+ type: string;
372
+ action_id: string;
373
+ block_id?: string;
374
+ value?: string;
375
+ action_ts?: string;
376
+ selected_option?: {
377
+ value: string;
378
+ };
379
+ }>;
380
+ channel: {
381
+ id: string;
382
+ name: string;
383
+ };
384
+ container: {
385
+ type: string;
386
+ message_ts: string;
387
+ channel_id: string;
388
+ is_ephemeral?: boolean;
389
+ thread_ts?: string;
390
+ };
391
+ message: {
392
+ ts: string;
393
+ thread_ts?: string;
394
+ };
395
+ response_url?: string;
396
+ trigger_id: string;
397
+ type: "block_actions";
398
+ user: {
399
+ id: string;
400
+ username: string;
401
+ name?: string;
402
+ };
403
+ }
404
+ interface SlackViewSubmissionPayload {
405
+ trigger_id: string;
406
+ type: "view_submission";
407
+ user: {
408
+ id: string;
409
+ username: string;
410
+ name?: string;
411
+ };
412
+ view: {
413
+ id: string;
414
+ callback_id: string;
415
+ private_metadata?: string;
416
+ state: {
417
+ values: Record<string, Record<string, {
418
+ value?: string;
419
+ selected_option?: {
420
+ value: string;
421
+ };
422
+ }>>;
423
+ };
424
+ };
425
+ }
426
+ interface SlackViewClosedPayload {
427
+ type: "view_closed";
428
+ user: {
429
+ id: string;
430
+ username: string;
431
+ name?: string;
432
+ };
433
+ view: {
434
+ id: string;
435
+ callback_id: string;
436
+ private_metadata?: string;
437
+ };
438
+ }
439
+ interface SlackBlockSuggestionPayload {
440
+ action_id: string;
441
+ block_id: string;
442
+ team?: {
443
+ id: string;
444
+ };
445
+ type: "block_suggestion";
446
+ user: {
447
+ id: string;
448
+ username?: string;
449
+ name?: string;
450
+ };
451
+ value?: string;
452
+ }
453
+ type SlackInteractivePayload = SlackBlockActionsPayload | SlackBlockSuggestionPayload | SlackViewSubmissionPayload | SlackViewClosedPayload;
454
+ /** Cached user info */
455
+ interface CachedUser {
456
+ avatarUrl?: string;
457
+ displayName: string;
458
+ email?: string;
459
+ isBot?: boolean;
460
+ realName: string;
461
+ }
232
462
  declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
233
463
  readonly name = "slack";
234
464
  readonly userName: string;
235
- private readonly client;
236
- private readonly signingSecret;
237
- private readonly webhookVerifier;
238
- private readonly defaultBotTokenProvider;
239
- private chat;
240
- private readonly logger;
241
- private _botUserId;
242
- private _botId;
243
- private readonly formatConverter;
244
- private static USER_CACHE_TTL_MS;
245
- private static CHANNEL_CACHE_TTL_MS;
246
- private static REVERSE_INDEX_TTL_MS;
465
+ protected readonly _client: WebClient;
466
+ protected readonly tokenClientCache: Map<string, WebClient>;
467
+ protected readonly slackApiUrl: string | undefined;
468
+ protected readonly signingSecret: string | undefined;
469
+ protected readonly webhookVerifier: ((request: Request, body: string) => unknown | Promise<unknown>) | undefined;
470
+ protected readonly defaultBotTokenProvider: (() => string | Promise<string>) | undefined;
471
+ protected chat: ChatInstance | null;
472
+ protected readonly logger: Logger;
473
+ protected _botUserId: string | null;
474
+ protected _botId: string | null;
475
+ protected readonly formatConverter: SlackFormatConverter;
476
+ protected static readonly USER_CACHE_TTL_MS: number;
477
+ protected static readonly CHANNEL_CACHE_TTL_MS: number;
478
+ protected static readonly REVERSE_INDEX_TTL_MS: number;
247
479
  /**
248
480
  * Cache of channel IDs known to be external/shared (Slack Connect).
249
481
  * Populated from `is_ext_shared_channel` in incoming webhook payloads.
250
482
  */
251
483
  private readonly _externalChannels;
252
- private readonly appToken;
253
- private readonly mode;
254
- private readonly socketForwardingSecret;
484
+ protected readonly appToken: string | undefined;
485
+ protected readonly mode: SlackAdapterMode;
486
+ protected readonly socketForwardingSecret: string | undefined;
255
487
  private socketClient;
256
- private readonly clientId;
257
- private readonly clientSecret;
258
- private readonly encryptionKey;
259
- private readonly installationKeyPrefix;
260
- private readonly requestContext;
488
+ protected readonly clientId: string | undefined;
489
+ protected readonly clientSecret: string | undefined;
490
+ protected readonly encryptionKey: Buffer | undefined;
491
+ protected readonly installationKeyPrefix: string;
492
+ protected readonly installationProvider: SlackAdapterConfig["installationProvider"];
493
+ protected readonly requestContext: AsyncLocalStorage<{
494
+ token: string;
495
+ botUserId?: string;
496
+ isExtSharedChannel?: boolean;
497
+ enterpriseId?: string;
498
+ isEnterpriseInstall?: boolean;
499
+ }>;
261
500
  /** Bot user ID (e.g., U_BOT_123) used for mention detection */
262
501
  get botUserId(): string | undefined;
263
502
  get isSocketMode(): boolean;
503
+ /**
504
+ * Direct access to a [`WebClient`](https://github.com/slackapi/node-slack-sdk/tree/main/packages/web-api)
505
+ * from `@slack/web-api` bound to the bot token for the current request
506
+ * context (multi-workspace) or the configured default token
507
+ * (single-workspace). Use for any Slack Web API call not covered by the
508
+ * SDK's high-level methods — for example
509
+ * `adapter.webClient.pins.add(...)` or
510
+ * `adapter.webClient.usergroups.list(...)`.
511
+ *
512
+ * Resolution order:
513
+ * 1. Token from the current `requestContext` (set during webhook
514
+ * handling, or by `withBotToken()`).
515
+ * 2. The default bot token, when configured as a static string or
516
+ * synchronous resolver function.
517
+ *
518
+ * Throws `AuthenticationError` if neither is available — typical causes
519
+ * are calling `.webClient` outside any webhook/`withBotToken()` context
520
+ * in multi-workspace mode, or having configured `botToken` as an async
521
+ * function. In the latter case wrap the work in
522
+ * `adapter.withBotToken(token, () => adapter.webClient...)`.
523
+ *
524
+ * @example
525
+ * ```ts
526
+ * const slack = bot.getAdapter("slack").webClient;
527
+ * await slack.pins.add({
528
+ * channel: "C123ABC",
529
+ * timestamp: "1234567890.123456",
530
+ * });
531
+ * ```
532
+ */
533
+ get webClient(): WebClient;
534
+ /**
535
+ * @deprecated Use {@link SlackAdapter.webClient | `webClient`} instead.
536
+ * This alias is preserved for backwards compatibility and will be
537
+ * removed in a future major release.
538
+ */
539
+ get client(): WebClient;
540
+ private getClientForToken;
264
541
  constructor(config?: SlackAdapterConfig);
265
542
  /**
266
543
  * Get the current bot token for API calls.
267
544
  * Checks request context (multi-workspace) → default token provider
268
545
  * (single-workspace) → throws.
269
546
  */
270
- private getToken;
547
+ protected getToken(): Promise<string>;
271
548
  /**
272
549
  * Add the current token to API call options.
273
550
  * Workaround for Slack WebClient types not including `token` in per-method args.
274
551
  */
275
- private withToken;
552
+ protected withToken<T extends Record<string, any>>(options: T): Promise<T & {
553
+ token: string;
554
+ }>;
276
555
  initialize(chat: ChatInstance): Promise<void>;
277
- private installationKey;
556
+ protected installationKey(teamId: string): string;
278
557
  /**
279
558
  * Save a Slack workspace installation.
280
559
  * Call this from your OAuth callback route after a successful installation.
@@ -303,61 +582,71 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
303
582
  */
304
583
  withBotToken<T>(token: string, fn: () => T): T;
305
584
  /**
306
- * Resolve the bot token for a team from the state adapter.
585
+ * Resolve the bot token for an installation from the external provider or state adapter.
586
+ * @param installationId - team_id or enterprise_id depending on install type
587
+ * @param isEnterpriseInstall - true if this is an Enterprise Grid org-wide install
307
588
  */
308
- private resolveTokenForTeam;
589
+ protected resolveTokenForTeam(installationId: string, isEnterpriseInstall?: boolean): Promise<{
590
+ token: string;
591
+ botUserId?: string;
592
+ } | null>;
309
593
  /**
310
- * Extract team_id from an interactive payload (form-urlencoded).
594
+ * Extract installation info from an interactive payload (form-urlencoded).
595
+ * For Enterprise Grid org-wide installs, returns enterprise_id; otherwise team_id.
311
596
  */
312
- private extractTeamIdFromInteractive;
597
+ protected extractInstallationFromInteractive(body: string): {
598
+ installationId: string;
599
+ isEnterpriseInstall: boolean;
600
+ enterpriseId?: string;
601
+ } | null;
313
602
  /**
314
603
  * Look up user info from Slack API with caching via state adapter.
315
604
  * Returns null when the API call fails.
316
605
  */
317
- private lookupUser;
606
+ protected lookupUser(userId: string): Promise<CachedUser | null>;
318
607
  /**
319
608
  * Look up channel name from Slack API with caching via state adapter.
320
609
  * Returns channel name, or falls back to channel ID.
321
610
  */
322
- private lookupChannel;
611
+ protected lookupChannel(channelId: string): Promise<string>;
323
612
  getUser(userId: string): Promise<UserInfo | null>;
324
613
  handleWebhook(request: Request, options?: WebhookOptions): Promise<Response>;
325
614
  /** Extract and dispatch events from a validated payload */
326
- private processEventPayload;
615
+ protected processEventPayload(payload: SlackWebhookPayload, options?: WebhookOptions): void;
327
616
  /**
328
617
  * Handle Slack interactive payloads (button clicks, view submissions, etc.).
329
618
  * These are sent as form-urlencoded with a `payload` JSON field.
330
619
  */
331
- private handleInteractivePayload;
620
+ protected handleInteractivePayload(body: string, options?: WebhookOptions): Response | Promise<Response>;
332
621
  /**
333
622
  * Dispatch a pre-parsed interactive payload to the correct handler.
334
623
  * Used by both webhook and socket mode paths.
335
624
  */
336
- private dispatchInteractivePayload;
625
+ protected dispatchInteractivePayload(payload: SlackInteractivePayload, options?: WebhookOptions): Response | Promise<Response>;
337
626
  /**
338
627
  * Handle Slack slash command payloads.
339
628
  * Slash commands are sent as form-urlencoded with command, text, user_id, channel_id, etc.
340
629
  */
341
- private handleSlashCommand;
630
+ protected handleSlashCommand(params: URLSearchParams, options?: WebhookOptions): Promise<Response>;
342
631
  /**
343
632
  * Handle block_actions payload (button clicks in Block Kit).
344
633
  */
345
- private handleBlockActions;
346
- private handleBlockSuggestion;
347
- private optionsLoadResponse;
348
- private handleViewSubmission;
349
- private handleViewClosed;
350
- private modalResponseToSlack;
351
- private convertModalJSX;
634
+ protected handleBlockActions(payload: SlackBlockActionsPayload, options?: WebhookOptions): void;
635
+ protected handleBlockSuggestion(payload: SlackBlockSuggestionPayload, options?: WebhookOptions): Promise<Response>;
636
+ protected optionsLoadResponse(result: OptionsLoadResult): Response;
637
+ protected handleViewSubmission(payload: SlackViewSubmissionPayload, options?: WebhookOptions): Promise<Response>;
638
+ protected handleViewClosed(payload: SlackViewClosedPayload, options?: WebhookOptions): void;
639
+ protected modalResponseToSlack(response: ModalResponse, contextId?: string): SlackModalResponse;
640
+ protected convertModalJSX(modal: ModalElement): ModalElement;
352
641
  /**
353
642
  * Start Socket Mode connection.
354
643
  * Creates a SocketModeClient, registers event handlers, and connects.
355
644
  */
356
- private startSocketMode;
645
+ protected startSocketMode(): Promise<void>;
357
646
  /**
358
647
  * Route a socket mode event to the appropriate handler.
359
648
  */
360
- private routeSocketEvent;
649
+ protected routeSocketEvent(body: Record<string, unknown>, eventType: string, ack: (response?: Record<string, unknown>) => Promise<void>, options?: WebhookOptions): Promise<void>;
361
650
  /**
362
651
  * Start a transient Socket Mode listener for serverless environments.
363
652
  * The listener maintains a WebSocket for `durationMs`, acks events, and
@@ -372,48 +661,48 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
372
661
  /**
373
662
  * Run the socket mode listener for a specified duration.
374
663
  */
375
- private runSocketModeListener;
664
+ protected runSocketModeListener(durationMs: number, abortSignal?: AbortSignal, webhookUrl?: string, options?: WebhookOptions): Promise<void>;
376
665
  /**
377
666
  * Forward a socket mode event to the webhook endpoint.
378
667
  */
379
- private forwardSocketEvent;
668
+ protected forwardSocketEvent(webhookUrl: string, event: SlackForwardedSocketEvent): Promise<void>;
380
669
  /**
381
670
  * Disconnect the socket mode client.
382
671
  * No-op if not connected.
383
672
  */
384
673
  disconnect(): Promise<void>;
385
- private verifySignature;
674
+ protected verifySignature(body: string, timestamp: string | null, signature: string | null): boolean;
386
675
  /**
387
676
  * Handle message events from Slack.
388
677
  * Bot message filtering (isMe) is handled centrally by the Chat class.
389
678
  */
390
- private handleMessageEvent;
391
- private handleMessageChanged;
679
+ protected handleMessageEvent(event: SlackEvent, options?: WebhookOptions): void;
680
+ protected handleMessageChanged(event: SlackEvent, _options?: WebhookOptions): void;
392
681
  /**
393
682
  * Handle reaction events from Slack (reaction_added, reaction_removed).
394
683
  */
395
- private handleReactionEvent;
684
+ protected handleReactionEvent(event: SlackReactionEvent, options?: WebhookOptions): Promise<void>;
396
685
  /**
397
686
  * Handle assistant_thread_started events from Slack's Assistants API.
398
687
  * Fires when a user opens a new assistant thread (DM with the bot).
399
688
  */
400
- private handleAssistantThreadStarted;
689
+ protected handleAssistantThreadStarted(event: SlackAssistantThreadStartedEvent, options?: WebhookOptions): void;
401
690
  /**
402
691
  * Handle assistant_thread_context_changed events from Slack's Assistants API.
403
692
  * Fires when a user navigates to a different channel with the assistant panel open.
404
693
  */
405
- private handleAssistantContextChanged;
694
+ protected handleAssistantContextChanged(event: SlackAssistantContextChangedEvent, options?: WebhookOptions): void;
406
695
  /**
407
696
  * Handle app_home_opened events from Slack.
408
697
  * Fires when a user opens the bot's Home tab.
409
698
  */
410
- private handleAppHomeOpened;
699
+ protected handleAppHomeOpened(event: SlackAppHomeOpenedEvent, options?: WebhookOptions): void;
411
700
  /**
412
701
  * Handle member_joined_channel events from Slack.
413
702
  * Fires when a user (including the bot) joins a channel.
414
703
  */
415
- private handleMemberJoinedChannel;
416
- private handleUserChange;
704
+ protected handleMemberJoinedChannel(event: SlackMemberJoinedChannelEvent, options?: WebhookOptions): void;
705
+ protected handleUserChange(event: SlackUserChangeEvent): Promise<void>;
417
706
  /**
418
707
  * Publish a Home tab view for a user.
419
708
  * Slack API: views.publish
@@ -449,37 +738,47 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
449
738
  * parsing historical/channel messages where mention detection doesn't
450
739
  * apply.
451
740
  */
452
- private resolveInlineMentions;
741
+ protected resolveInlineMentions(text: string, skipSelfMention: boolean): Promise<string>;
453
742
  /**
454
743
  * Extract link URLs from a Slack event.
455
744
  * Uses the `blocks` field (rich_text blocks with link elements) when available,
456
745
  * falling back to parsing `<url>` patterns from the text field.
457
746
  */
458
- private extractLinks;
747
+ protected extractLinks(event: SlackEvent): LinkPreview[];
459
748
  /**
460
749
  * Create a LinkPreview for a URL. If the URL points to a Slack message,
461
750
  * includes a `fetchMessage` callback that fetches and parses the linked message.
462
751
  */
463
- private createLinkPreview;
464
- private parseSlackMessage;
465
- private enrichLinks;
752
+ protected createLinkPreview(url: string): LinkPreview;
753
+ protected parseSlackMessage(event: SlackEvent, threadId: string, options?: {
754
+ skipSelfMention?: boolean;
755
+ }): Promise<Message<unknown>>;
756
+ protected enrichLinks(links: LinkPreview[], messageTs?: string): Promise<LinkPreview[]>;
466
757
  /**
467
758
  * Create an Attachment object from a Slack file.
468
759
  * Includes a fetchData method that uses the bot token for auth.
469
760
  */
470
- private createAttachment;
471
- private fetchSlackFile;
761
+ protected createAttachment(file: {
762
+ id?: string;
763
+ mimetype?: string;
764
+ url_private?: string;
765
+ name?: string;
766
+ size?: number;
767
+ original_w?: number;
768
+ original_h?: number;
769
+ }, teamId?: string): Attachment;
770
+ protected fetchSlackFile(url: string, token: string): Promise<Buffer>;
472
771
  rehydrateAttachment(attachment: Attachment): Attachment;
473
772
  /**
474
773
  * Resolve @name mentions in text to Slack <@USER_ID> format using the
475
774
  * reverse user cache. When multiple users share a display name, prefers
476
775
  * the one who is a participant in the given thread.
477
776
  */
478
- private resolveOutgoingMentions;
777
+ protected resolveOutgoingMentions(text: string, threadId: string): Promise<string>;
479
778
  /**
480
779
  * Pre-process an outgoing message to resolve @name mentions before rendering.
481
780
  */
482
- private resolveMessageMentions;
781
+ protected resolveMessageMentions(message: AdapterPostableMessage, threadId: string): Promise<AdapterPostableMessage>;
483
782
  postMessage(threadId: string, _message: AdapterPostableMessage): Promise<RawMessage<unknown>>;
484
783
  postEphemeral(threadId: string, userId: string, _message: AdapterPostableMessage): Promise<EphemeralMessage>;
485
784
  scheduleMessage(threadId: string, _message: AdapterPostableMessage, options: {
@@ -495,14 +794,17 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
495
794
  * Upload files to Slack and share them to a channel.
496
795
  * Returns the file IDs of uploaded files.
497
796
  */
498
- private uploadFiles;
797
+ protected uploadFiles(files: FileUpload[], channel: string, threadTs?: string): Promise<string[]>;
499
798
  editMessage(threadId: string, messageId: string, _message: AdapterPostableMessage): Promise<RawMessage<unknown>>;
500
799
  postObject(threadId: string, kind: string, data: unknown): Promise<RawMessage<unknown>>;
501
800
  editObject(threadId: string, messageId: string, kind: string, data: unknown): Promise<RawMessage<unknown>>;
502
- private renderPlanFallbackText;
503
- private planToBlockKit;
504
- private planContentToPlainText;
505
- private planContentToRichText;
801
+ protected renderPlanFallbackText(plan: PlanModel): string;
802
+ protected planToBlockKit(plan: PlanModel): unknown[];
803
+ protected planContentToPlainText(content: PlanContent | undefined): string;
804
+ protected planContentToRichText(content: PlanContent | undefined): {
805
+ type: "rich_text";
806
+ elements: unknown[];
807
+ } | undefined;
506
808
  deleteMessage(threadId: string, messageId: string): Promise<void>;
507
809
  addReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
508
810
  removeReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
@@ -543,7 +845,7 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
543
845
  * Fetch messages in forward direction (oldest first, efficient).
544
846
  * Uses native Slack cursor pagination.
545
847
  */
546
- private fetchMessagesForward;
848
+ protected fetchMessagesForward(channel: string, threadTs: string, threadId: string, limit: number, cursor?: string): Promise<FetchResult<unknown>>;
547
849
  /**
548
850
  * Fetch messages in backward direction (most recent first).
549
851
  *
@@ -555,7 +857,7 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
555
857
  * Note: For very large threads (>1000 messages), the first backward call
556
858
  * may not return the absolute most recent messages. This is a Slack API limitation.
557
859
  */
558
- private fetchMessagesBackward;
860
+ protected fetchMessagesBackward(channel: string, threadTs: string, threadId: string, limit: number, cursor?: string): Promise<FetchResult<unknown>>;
559
861
  fetchThread(threadId: string): Promise<ThreadInfo>;
560
862
  /**
561
863
  * Fetch a single message by ID (timestamp).
@@ -582,7 +884,7 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
582
884
  * Synchronous message parsing without user lookup.
583
885
  * Used for parseMessage interface - falls back to user ID for username.
584
886
  */
585
- private parseSlackMessageSync;
887
+ protected parseSlackMessageSync(event: SlackEvent, threadId: string): Message<unknown>;
586
888
  /**
587
889
  * Derive channel ID from a Slack thread ID.
588
890
  * Slack thread IDs are "slack:CHANNEL:THREAD_TS", channel ID is "slack:CHANNEL".
@@ -592,8 +894,8 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
592
894
  * Fetch channel-level messages (conversations.history, not thread replies).
593
895
  */
594
896
  fetchChannelMessages(channelId: string, options?: FetchOptions): Promise<FetchResult<unknown>>;
595
- private fetchChannelMessagesForward;
596
- private fetchChannelMessagesBackward;
897
+ protected fetchChannelMessagesForward(channel: string, limit: number, cursor?: string): Promise<FetchResult<unknown>>;
898
+ protected fetchChannelMessagesBackward(channel: string, limit: number, cursor?: string): Promise<FetchResult<unknown>>;
597
899
  /**
598
900
  * List threads in a Slack channel.
599
901
  * Fetches channel history and filters for messages with replies.
@@ -619,23 +921,30 @@ declare class SlackAdapter implements Adapter<SlackThreadId, unknown> {
619
921
  * - _botUserId is the user ID (U_xxx) - matches event.user
620
922
  * - _botId is the bot ID (B_xxx) - matches event.bot_id
621
923
  */
622
- private isMessageFromSelf;
623
- private handleSlackError;
924
+ protected isMessageFromSelf(event: SlackEvent): boolean;
925
+ protected handleSlackError(error: unknown): never;
624
926
  /**
625
927
  * Encode response_url and userId into messageId for ephemeral messages.
626
928
  * This allows edit/delete operations to work via response_url.
627
929
  */
628
- private encodeEphemeralMessageId;
930
+ protected encodeEphemeralMessageId(messageTs: string, responseUrl: string, userId: string): string;
629
931
  /**
630
932
  * Decode ephemeral messageId to extract messageTs, responseUrl, and userId.
631
933
  * Returns null if the messageId is not an ephemeral encoding.
632
934
  */
633
- private decodeEphemeralMessageId;
935
+ protected decodeEphemeralMessageId(messageId: string): {
936
+ messageTs: string;
937
+ responseUrl: string;
938
+ userId: string;
939
+ } | null;
634
940
  /**
635
941
  * Send a request to Slack's response_url to modify an ephemeral message.
636
942
  */
637
- private sendToResponseUrl;
943
+ protected sendToResponseUrl(responseUrl: string, action: "replace" | "delete", options?: {
944
+ message?: AdapterPostableMessage;
945
+ threadTs?: string;
946
+ }): Promise<Record<string, unknown>>;
638
947
  }
639
- declare function createSlackAdapter(config?: Partial<SlackAdapterConfig>): SlackAdapter;
948
+ declare function createSlackAdapter(config?: SlackAdapterConfig): SlackAdapter;
640
949
 
641
950
  export { SlackAdapter, type SlackAdapterConfig, type SlackAdapterMode, type SlackBotToken, type SlackEvent, SlackFormatConverter, type SlackInstallation, SlackFormatConverter as SlackMarkdownConverter, type SlackOAuthCallbackOptions, type SlackReactionEvent, type SlackThreadId, cardToBlockKit, cardToFallbackText, createSlackAdapter };