@zhin.js/adapter-slack 1.1.18 → 1.1.20

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.20
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [5e878ba]
8
+ - @zhin.js/page@1.1.12
9
+
10
+ ## 1.1.19
11
+
12
+ ### Patch Changes
13
+
14
+ - 2c3610a: Move account lifecycle ownership into the generic Adapter base and let native Endpoints retain their SDK Client inheritance. Infer platform-specific operation Sessions from a single adapter registry while preserving command parameter, option, configuration and factory inference.
15
+
16
+ Bind message replies, management ports, login challenges and Agent cancellation to the captured account incarnation. Persist runtime account intent with encrypted, revision-checked Host storage; keep account management independent of Root process restarts. Require explicit operator confirmation before importing existing accounts, and give replacement accounts a new identity without inheriting previous Sessions.
17
+
18
+ Expose account save, start, stop, update and replacement through the existing adapter Console, with exact account ownership, truthful pending/unknown outcomes and no startup configuration or environment-file rewrites.
19
+
20
+ Complete the target migration across every adapter, the public authoring API, generators, examples and Console. This intentionally removes the old create factory, inheritable Endpoint/ClientEndpoint classes, Client descriptors and file-rewrite account management; plugin authors must use createAdapter, native Client inheritance and the single AdapterRegistry. Satori and OneBot12 require explicit platform/userId selection, and WeCom requires a separate agentId.
21
+
22
+ Verify opaque credential changes before the same configuration snapshot is committed. Drain admitted native callbacks across close/rollback, cancel target work on stop, and keep raw transport parsing, platform ACK timing and SDK native methods under their existing owners. Account metadata conceals credentials carried in URLs.
23
+
24
+ - a9f4e48: PATCH COMPATIBILITY CUTOVER: this batch intentionally changes plugin APIs. The maintainer explicitly chose patch releases with declared version boundaries. Upgrade the complete tested dependency set; patch numbering does not promise compatibility with the removed interfaces.
25
+
26
+ The first planned floors are zhin.js 1.1.19, Core 1.1.54, Adapter 1.1.26, FeatureKit 1.1.10, Plugin Runtime 1.1.18, Runtime/Isolate 1.1.16 and Agent 1.1.45. Keep old-interface plugins with the earlier locked stack until they are migrated. Adapter's independent Feature API changes from 1.0.0 to 2.0.0; official consumers declare ^2.0.0. Existing Feature API admission rejects explicitly incompatible ranges; omitted API metadata keeps its existing behavior and does not certify compatibility. Runtime engine and patch-only release gates remain unchanged.
27
+
28
+ Use the native-Client Adapter target contract, canonical FeatureKit AdapterRegistry augmentation and named Endpoint control/management requests. Route message controls from canonical message/conversation refs; retain exact source authority and propagate caller/account/explicit-Root-stop cancellation. Replace removed Agent activity feedback exports with source-bound feedback. HMR pause/resume belongs to concrete plugin instances; plugins choose accepted-work policy without changing Controller commit/rollback authority. Cooperative worker/process control cancellation does not kill an isolate or reopen retired business admission.
29
+
30
+ Provide authenticated historical-data preview, exact selected binding, transactional application, authoritative inspection and explicit resumption, including active games. Preserve before-images and journals; never replay an unconfirmed effect, infer an account from an alias, or reuse historical permission grants. Owner V2 approvals remain inactive legacy data, while new writes use V3. Rollback requires matching software, lockfile and verified data; installing old code alone cannot read a new V3 approval file. Conflicting after-images are never overwritten.
31
+
32
+ See docs/plans/adapter-operation-version-boundaries.md and the Chinese/English upgrade guide for the complete version inventory, custom-plugin changes, acceptance and recovery sequence. These code and metadata changes do not authorize merging, publication, deployment, login, production migration or removal of installed workspace patches.
33
+
34
+ - Updated dependencies [2c3610a]
35
+ - Updated dependencies [a9f4e48]
36
+ - Updated dependencies [f8505b0]
37
+ - Updated dependencies [2c3610a]
38
+ - @zhin.js/adapter@1.1.26
39
+ - @zhin.js/feature-kit@1.1.10
40
+ - @zhin.js/core@1.1.54
41
+ - @zhin.js/host-http@1.1.12
42
+ - @zhin.js/client@1.1.22
43
+ - @zhin.js/page@1.1.11
44
+ - @zhin.js/agent-feature@1.1.11
45
+ - @zhin.js/skill@1.1.11
46
+ - @zhin.js/tool@1.1.13
47
+
3
48
  ## 1.1.18
4
49
 
5
50
  ### Patch Changes
package/README.md CHANGED
@@ -6,7 +6,7 @@ Zhin.js Slack 适配器(Plugin Runtime),优先 Socket Mode,也可经 Run
6
6
 
7
7
  - **Socket Mode**(默认):WebSocket 长连接,无需公网 URL
8
8
  - **HTTP Events API**:`httpHostToken` POST(签名验证),**非** legacy host-router/Koa
9
- - 入站经 `Endpoint.emit(...)`;出站 `send({ conversation, payload })` → `chat.postMessage` / Block Kit
9
+ - 入站经 `endpoint[endpointSpec].events`;出站 `send({ conversation, payload })` → `chat.postMessage` / Block Kit
10
10
  - 约定式 `defineAdapter` / `definePlugin`(无需 `usePlugin`)
11
11
  - Block Kit 按钮、斜杠命令、消息编辑、表情反应等(见 `tools/`)
12
12
 
@@ -19,12 +19,13 @@ pnpm add @zhin.js/adapter-slack
19
19
  ## Plugin Runtime
20
20
 
21
21
  - `@zhin.js/adapter` — 约定式 `adapters/slack/index.ts`(`defineAdapter`)
22
- - `@zhin.js/core` — `Endpoint.emit(...)` 入站、`outboundMessageToken` 出站
22
+ - `@zhin.js/core` — `endpoint[endpointSpec].events` 入站、`outboundMessageToken` 出站
23
23
  - `@zhin.js/host-http` — 仅 HTTP 模式需要 `httpHostToken` 注册 Events 路由
24
24
  - `zhin.js` — `plugin.ts`(`definePlugin`)
25
25
  - 配置经插件 `schema.json` 落到顶层 `<instanceKey>`
26
26
 
27
- 入站:`gateway.receive({ conversation, message: { conversation, id }, content: text, sender, metadata })`(`conversation` 为 ConversationRef:`channel_type: im` → kind `private`,其余 → kind `group`;线程根 ts 进 `threadId`)
27
+ 入站:`endpoint[endpointSpec].events.emit('message.receive', { conversation, message: { conversation, id }, content: text, sender, metadata })`(`conversation` 为 ConversationRef:`channel_type: im` → kind `private`,其余 → kind `group`;线程根 ts 进 `threadId`)
28
+
28
29
  出站:`send({ conversation, payload })` → Web API(`conversation.id` 为 channel,`conversation.threadId` 为 thread_ts)
29
30
 
30
31
  ### 平台权限(platform permit)
@@ -129,18 +130,24 @@ HTTP 模式下 Runtime Host(`http`)须已 listen;Slack App 的 Event Subsc
129
130
  - 入站 mrkdwn → Markdown 为启发式转换
130
131
  - Modals / Select menus — 暂不支持
131
132
  - OAuth 安装流程 — 暂不支持
132
- - 旧 `usePlugin` / `extends Adapter` / host-router 生产入口已删除
133
+ - 旧 `usePlugin`、`defineAdapter.create`、公开 Endpoint 基类与 host-router 生产入口已删除;平台 Adapter 继承统一 `Adapter` 基类,Endpoint 继承实际原生 Client
133
134
 
134
135
  ## Console 页面
135
136
 
136
137
  启动后打开 Console 的「Slack」页(地址 `/slack`),可以:
137
138
 
138
139
  - 查看运行中的连接、点「测试连接」做连通性诊断;
139
- - 增删 `plugins.slack.endpoints`(凭据写入 `.env`,配置里只保留 `${ENV}` 引用);
140
+ - 在账号库保存、修改、启动、停止、替换或删除该 Adapter 的账号;新增仅保存,不创建 SDK Client,需手动启动;
140
141
  - 如果适配器要求登录,页面会显示 LoginAssist 的扫码 / 滑块 / 设备确认待办;
141
142
 
142
143
  读取需要 `slack:read`,写操作需要 `slack:write`;管理员 full token 不受限。页面里的「添加 endpoint」等价于原来的 `slack endpoint add`。
143
144
 
145
+ 首次修改启动配置里的既有账号前,管理员必须核对清单并确认一次迁移。原 canonical 身份与历史保留,完整账号配置加密进入 Host 数据库;此后账号管理只写数据库,不修改启动文件或 `.env`,不重启进程。没有持久化账号端口的环境可使用静态配置连接,动态写操作明确不可用。
146
+
147
+ 启停意图在进程重启后恢复。停止或删除会取消并关闭目标账号的在途操作,其他账号继续运行;删除保留历史。已启动账号的连接配置更新先关闭旧 incarnation,再仅重连该账号;平台身份变化按替换处理,分配新内部身份、保留旧历史,新账号不继承旧 Session、个人设置或启动意图。提交结果未知时先刷新核实,不自动重复 CAS 或平台操作。
148
+
149
+ Slack 的 bot token 更新通过只读 `auth.test` 核验 workspace 与 bot user。App-Level Token 和 HTTP signing secret 没有对应的只读身份核验接口,变更须使用显式账号替换;不以 bot token 的身份结果冒充这两项凭据的身份。
150
+
144
151
  ## 故障排查
145
152
 
146
153
  | 现象 | 排查 |
@@ -3,10 +3,8 @@
3
3
  * Convention entry: discover `adapters/slack/index.ts` → defineAdapter.
4
4
  */
5
5
  import { defineAdapter } from 'zhin.js/adapter';
6
- import { httpHostToken } from '@zhin.js/host-http';
7
- import { SlackEndpoint } from "../../lib/endpoint.js";
8
- import { resolveSlackConfig, } from "../../lib/protocol.js";
9
- import { slackRuntimeStateToken } from "../../lib/slack-runtime-state.js";
6
+ import { SlackAdapter } from "../../lib/adapter.js";
7
+ import {} from "../../lib/protocol.js";
10
8
  export { SlackEndpoint } from "../../lib/endpoint.js";
11
9
  export default defineAdapter({
12
10
  capabilities: ['inbound', 'outbound'],
@@ -19,23 +17,5 @@ export default defineAdapter({
19
17
  interactive: 'native',
20
18
  markdown: 'native',
21
19
  },
22
- create(context) {
23
- const config = resolveSlackConfig(context.config);
24
- // 注册到插件运行时状态(slack endpoint list 的"运行中"数据源)
25
- context.use(slackRuntimeStateToken).endpoints.set(config.id, {
26
- id: config.id,
27
- mode: config.mode,
28
- });
29
- if (config.mode === 'http') {
30
- return new SlackEndpoint({
31
- id: context.id,
32
- http: context.use(httpHostToken),
33
- config,
34
- });
35
- }
36
- return new SlackEndpoint({
37
- id: context.id,
38
- config,
39
- });
40
- },
20
+ createAdapter: context => new SlackAdapter(context),
41
21
  });
@@ -2,13 +2,10 @@
2
2
  * Convention entry: discover `adapters/slack/index.ts` → defineAdapter.
3
3
  */
4
4
  import { defineAdapter } from 'zhin.js/adapter';
5
- import { httpHostToken } from '@zhin.js/host-http';
6
- import { SlackEndpoint } from '../../src/endpoint.js';
5
+ import { SlackAdapter } from '../../src/adapter.js';
7
6
  import {
8
- resolveSlackConfig,
9
7
  type SlackEndpointConfig,
10
8
  } from '../../src/protocol.js';
11
- import { slackRuntimeStateToken } from '../../src/slack-runtime-state.js';
12
9
 
13
10
  export { SlackEndpoint } from '../../src/endpoint.js';
14
11
  export type { SlackEndpointOptions, SlackSocketLike, SlackWebClientLike } from '../../src/endpoint.js';
@@ -24,23 +21,5 @@ export default defineAdapter<SlackEndpointConfig>({
24
21
  interactive: 'native',
25
22
  markdown: 'native',
26
23
  },
27
- create(context) {
28
- const config = resolveSlackConfig(context.config);
29
- // 注册到插件运行时状态(slack endpoint list 的"运行中"数据源)
30
- context.use(slackRuntimeStateToken).endpoints.set(config.id, {
31
- id: config.id,
32
- mode: config.mode,
33
- });
34
- if (config.mode === 'http') {
35
- return new SlackEndpoint({
36
- id: context.id,
37
- http: context.use(httpHostToken),
38
- config,
39
- });
40
- }
41
- return new SlackEndpoint({
42
- id: context.id,
43
- config,
44
- });
45
- },
24
+ createAdapter: context => new SlackAdapter(context),
46
25
  });
@@ -14,9 +14,9 @@ export default defineAgentTool({
14
14
  tags: ['slack'],
15
15
  async execute({ channel, message_ts, text }, context) {
16
16
  const client = context.$client;
17
- await editSlackContent(client, channel, message_ts, [
18
- { type: 'text', data: { text } },
19
- ]);
17
+ await editSlackContent(client, { channel: channel, ts: message_ts, content: [
18
+ { type: 'text', data: { text } },
19
+ ] });
20
20
  return { success: true, message: t(context.locale, 'messageEdited') };
21
21
  },
22
22
  });
@@ -18,9 +18,9 @@ export default defineAgentTool<{
18
18
  tags: ['slack'],
19
19
  async execute({ channel, message_ts, text }, context) {
20
20
  const client = context.$client;
21
- await editSlackContent(client, channel, message_ts, [
21
+ await editSlackContent(client, { channel: channel, ts: message_ts, content: [
22
22
  { type: 'text', data: { text } },
23
- ]);
23
+ ] });
24
24
  return { success: true, message: t(context.locale, 'messageEdited') };
25
25
  },
26
26
  });
@@ -5,7 +5,6 @@
5
5
  */
6
6
  import { createEndpointCommands } from 'zhin.js/adapter';
7
7
  import { defineCommand } from 'zhin.js/command';
8
- import { slackRuntimeStateToken } from "../../../lib/slack-runtime-state.js";
9
8
  export const slackEndpointCommands = createEndpointCommands({
10
9
  adapterKey: 'slack',
11
10
  adapterDisplayName: 'Slack',
@@ -14,6 +13,5 @@ export const slackEndpointCommands = createEndpointCommands({
14
13
  { key: 'signingSecret', env: true, description: '签名密钥(HTTP Events,socketMode: false 必填)', descriptionI18n: { en: "Signing secret (required for HTTP Events when socketMode is false)" } },
15
14
  { key: 'appToken', env: true, description: 'App-Level Token(xapp-...,Socket Mode)' },
16
15
  ],
17
- running: (use) => use(slackRuntimeStateToken).endpoints.values(),
18
16
  describeEntry: (entry) => `token: ${String(entry.token)}`,
19
17
  }, defineCommand);
@@ -4,7 +4,6 @@
4
4
  */
5
5
  import { createEndpointCommands } from 'zhin.js/adapter';
6
6
  import { defineCommand } from 'zhin.js/command';
7
- import { slackRuntimeStateToken } from '../../../src/slack-runtime-state.js';
8
7
 
9
8
  export const slackEndpointCommands = createEndpointCommands({
10
9
  adapterKey: 'slack',
@@ -14,6 +13,5 @@ export const slackEndpointCommands = createEndpointCommands({
14
13
  { key: 'signingSecret', env: true, description: '签名密钥(HTTP Events,socketMode: false 必填)', descriptionI18n: { en: "Signing secret (required for HTTP Events when socketMode is false)" } },
15
14
  { key: 'appToken', env: true, description: 'App-Level Token(xapp-...,Socket Mode)' },
16
15
  ],
17
- running: (use) => use(slackRuntimeStateToken).endpoints.values(),
18
16
  describeEntry: (entry) => `token: ${String(entry.token)}`,
19
17
  }, defineCommand);
@@ -0,0 +1,16 @@
1
+ import { Adapter, type AdapterContext, type EndpointCreationContext } from 'zhin.js/adapter';
2
+ import { type WebClientOptions } from '@slack/web-api';
3
+ import { SlackEndpoint } from './endpoint.js';
4
+ import { type SlackEndpointConfig } from './protocol.js';
5
+ import type { SlackClientEventMap } from './client.js';
6
+ export declare class SlackAdapter extends Adapter<SlackEndpoint, SlackEndpointConfig, SlackClientEventMap> {
7
+ private readonly context;
8
+ private readonly webOptions;
9
+ constructor(context: AdapterContext<SlackEndpointConfig>, webOptions?: WebClientOptions);
10
+ get configurationIdentityFields(): readonly string[];
11
+ get configurationIdentityProbeFields(): readonly string[];
12
+ get configurationUpdateFields(): readonly string[];
13
+ protected validateConfiguration(config: SlackEndpointConfig): void;
14
+ protected identifyConfiguration(input: SlackEndpointConfig, signal: AbortSignal, changedFields: readonly string[]): Promise<string | undefined>;
15
+ protected createEndpoint(input: SlackEndpointConfig, execution: EndpointCreationContext): SlackEndpoint;
16
+ }
package/lib/adapter.js ADDED
@@ -0,0 +1,54 @@
1
+ import { Adapter } from 'zhin.js/adapter';
2
+ import { httpHostToken } from '@zhin.js/host-http';
3
+ import { WebClient } from '@slack/web-api';
4
+ import { SlackEndpoint } from './endpoint.js';
5
+ import { slackWebClientOptions } from './web-client.js';
6
+ import { createSlackWebApiAgent } from './web-api-proxy.js';
7
+ import { resolveSlackConfig } from './protocol.js';
8
+ export class SlackAdapter extends Adapter {
9
+ context;
10
+ webOptions;
11
+ constructor(context, webOptions = {}) {
12
+ super();
13
+ this.context = context;
14
+ this.webOptions = webOptions;
15
+ }
16
+ get configurationIdentityFields() { return ['id']; }
17
+ get configurationIdentityProbeFields() { return ['token', 'appToken', 'signingSecret']; }
18
+ get configurationUpdateFields() {
19
+ return ['token', 'appToken', 'signingSecret', 'socketMode',
20
+ 'webhookPath', 'clientPingTimeout', 'webApiProxy', 'webApiProxy.port', 'streamProxy', 'streamProxy.port', 'streamProxy.serverName'];
21
+ }
22
+ validateConfiguration(config) { resolveSlackConfig(config); }
23
+ async identifyConfiguration(input, signal, changedFields) {
24
+ // Neither the app-level token nor the callback signing secret has a readonly identity API.
25
+ if (changedFields.some(field => field !== 'token'))
26
+ return undefined;
27
+ const config = resolveSlackConfig(input);
28
+ const agent = config.webApiProxy ? createSlackWebApiAgent(config.webApiProxy) : undefined;
29
+ const client = new WebClient(config.token, slackWebClientOptions({ ...this.webOptions, ...(agent ? { agent } : {}),
30
+ requestInterceptor: request => { request.signal = signal; return request; } }));
31
+ try {
32
+ const me = await client.auth.test();
33
+ if (typeof me.team_id !== 'string' || !me.team_id.trim()
34
+ || typeof me.user_id !== 'string' || !me.user_id.trim())
35
+ throw new Error('Slack identity response is incomplete');
36
+ return JSON.stringify(['slack', me.team_id, me.user_id]);
37
+ }
38
+ finally {
39
+ agent?.destroy();
40
+ }
41
+ }
42
+ createEndpoint(input, execution) {
43
+ const config = resolveSlackConfig(input);
44
+ const webApiAgent = config.webApiProxy ? createSlackWebApiAgent(config.webApiProxy) : undefined;
45
+ try {
46
+ return new SlackEndpoint({ id: execution.canonicalId, config, webApiAgent, webOptions: this.webOptions,
47
+ ...(config.mode === 'http' ? { http: this.context.use(httpHostToken) } : {}) });
48
+ }
49
+ catch (error) {
50
+ webApiAgent?.destroy();
51
+ throw error;
52
+ }
53
+ }
54
+ }
package/lib/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { SlackWebClientLike } from './endpoint.js';
1
+ import type { SlackAdapter } from './adapter.js';
2
2
  import type { SlackEvent } from './protocol.js';
3
3
  /** Slack users.info response fields projected by the bundled tools. */
4
4
  export interface SlackUserInfo {
@@ -15,11 +15,7 @@ export interface SlackUserInfo {
15
15
  }
16
16
  export type SlackClientEventMap = Record<string, SlackEvent>;
17
17
  declare module '@zhin.js/feature-kit' {
18
- interface AdapterClientRegistry {
19
- readonly slack: {
20
- readonly client: SlackWebClientLike;
21
- readonly events: SlackClientEventMap;
22
- };
18
+ interface AdapterRegistry {
19
+ readonly slack: SlackAdapter;
23
20
  }
24
21
  }
25
- export declare const slackClient: import("@zhin.js/adapter").EndpointClientToken<SlackWebClientLike, SlackClientEventMap>;
package/lib/client.js CHANGED
@@ -1,2 +1 @@
1
- import { defineEndpointClient } from 'zhin.js/adapter';
2
- export const slackClient = defineEndpointClient('slack');
1
+ export {};
@@ -5,6 +5,12 @@ export const slackConsoleSpec = {
5
5
  { key: 'token', required: true, env: true, description: 'Bot User OAuth Token(xoxb-...)' },
6
6
  { key: 'signingSecret', env: true, description: '签名密钥(HTTP Events,socketMode: false 必填)', descriptionI18n: { en: 'Signing secret (required for HTTP Events)' } },
7
7
  { key: 'appToken', env: true, description: 'App-Level Token(xapp-...,Socket Mode)', descriptionI18n: { en: 'App-level token (xapp-..., Socket Mode)' } },
8
+ { key: 'socketMode', type: 'boolean', description: 'Socket Mode; false selects HTTP Events' },
9
+ { key: 'webhookPath', description: 'HTTP Events route' },
10
+ { key: 'clientPingTimeout', type: 'number', description: 'SDK client ping timeout in milliseconds' },
11
+ { key: 'webApiProxy.port', type: 'number', description: 'Configured Web API loopback proxy port' },
12
+ { key: 'streamProxy.port', type: 'number', description: 'Configured Socket Mode loopback proxy port' },
13
+ { key: 'streamProxy.serverName', description: 'Expected Socket Mode TLS hostname' },
8
14
  ],
9
15
  docsUrl: 'https://zhin.js.org/adapters/slack',
10
16
  readPermission: 'slack:read',
package/lib/console.d.ts CHANGED
@@ -1,8 +1,2 @@
1
- /**
2
- * Slack Console RPC:运行状态 + endpoint 增删(原 `slack endpoint` 聊天命令)。
3
- *
4
- * 页面绑定 `pages/index`,读取 / 写入分别要求 `<adapter>:read` / `<adapter>:write`。
5
- */
6
- import { type AdapterConsoleResources } from 'zhin.js/adapter';
7
1
  import type { PluginConsoleRpc } from 'zhin.js';
8
- export declare function createSlackConsoleRpc(resources: AdapterConsoleResources, getConfig: () => unknown): PluginConsoleRpc;
2
+ export declare function createSlackConsoleRpc(getConfig: () => unknown): PluginConsoleRpc;
package/lib/console.js CHANGED
@@ -4,13 +4,10 @@
4
4
  * 页面绑定 `pages/index`,读取 / 写入分别要求 `<adapter>:read` / `<adapter>:write`。
5
5
  */
6
6
  import { createAdapterConsoleRpc } from 'zhin.js/adapter';
7
- import { slackRuntimeStateToken } from './slack-runtime-state.js';
8
7
  import { slackConsoleSpec } from './console-spec.js';
9
- export function createSlackConsoleRpc(resources, getConfig) {
10
- const state = resources.use(slackRuntimeStateToken);
8
+ export function createSlackConsoleRpc(getConfig) {
11
9
  return createAdapterConsoleRpc({
12
10
  ...slackConsoleSpec,
13
- running: () => state.endpoints.values(),
14
11
  getConfig,
15
- }, resources);
12
+ });
16
13
  }
package/lib/endpoint.d.ts CHANGED
@@ -1,8 +1,12 @@
1
- import { Endpoint, type EndpointControl, type EndpointManagement, type EndpointSendRequest } from 'zhin.js/adapter';
1
+ /**
2
+ * SlackEndpoint — lifecycle, outbound, admit, Socket Mode, agent tool surface.
3
+ */
4
+ import { WebClient, type WebClientOptions } from '@slack/web-api';
5
+ import { createSlackWebApiAgent } from './web-api-proxy.js';
6
+ import { endpointSpec, type Endpoint, type EndpointSpecification } from 'zhin.js/adapter';
2
7
  import type { HttpHost } from '@zhin.js/host-http';
3
8
  import type { CapabilityId } from 'zhin.js';
4
9
  import { type ResolvedSlackConfig, type SlackEvent, type SlackInteractionPayload, type SlackMessageEvent, type SlackSlashCommand } from './protocol.js';
5
- import { type SlackChatClient } from './slack-outbound.js';
6
10
  import { type SlackWebhookHandler } from './webhook.js';
7
11
  export interface SlackSocketLike {
8
12
  on(event: string, handler: (args: {
@@ -12,136 +16,29 @@ export interface SlackSocketLike {
12
16
  start(): Promise<void>;
13
17
  disconnect(): Promise<void>;
14
18
  }
15
- export interface SlackWebClientLike extends SlackChatClient {
16
- auth: {
17
- test(): Promise<{
18
- user_id?: string;
19
- user?: string;
20
- }>;
21
- };
22
- conversations: {
23
- invite(opts: {
24
- channel: string;
25
- users: string;
26
- }): Promise<unknown>;
27
- kick(opts: {
28
- channel: string;
29
- user: string;
30
- }): Promise<unknown>;
31
- setTopic(opts: {
32
- channel: string;
33
- topic: string;
34
- }): Promise<unknown>;
35
- setPurpose(opts: {
36
- channel: string;
37
- purpose: string;
38
- }): Promise<unknown>;
39
- archive(opts: {
40
- channel: string;
41
- }): Promise<unknown>;
42
- unarchive(opts: {
43
- channel: string;
44
- }): Promise<unknown>;
45
- rename(opts: {
46
- channel: string;
47
- name: string;
48
- }): Promise<unknown>;
49
- members(opts: {
50
- channel: string;
51
- }): Promise<{
52
- members?: string[];
53
- }>;
54
- info(opts: {
55
- channel: string;
56
- }): Promise<{
57
- channel?: unknown;
58
- }>;
59
- list(opts?: {
60
- types?: string;
61
- limit?: number;
62
- cursor?: string;
63
- exclude_archived?: boolean;
64
- }): Promise<{
65
- channels?: unknown[];
66
- response_metadata?: {
67
- next_cursor?: string;
68
- };
69
- }>;
70
- };
71
- users: {
72
- info(opts: {
73
- user: string;
74
- }): Promise<{
75
- user?: unknown;
76
- }>;
77
- list(opts?: {
78
- limit?: number;
79
- cursor?: string;
80
- }): Promise<{
81
- members?: unknown[];
82
- response_metadata?: {
83
- next_cursor?: string;
84
- };
85
- }>;
86
- };
87
- reactions: {
88
- add(opts: {
89
- channel: string;
90
- timestamp: string;
91
- name: string;
92
- }): Promise<unknown>;
93
- remove(opts: {
94
- channel: string;
95
- timestamp: string;
96
- name: string;
97
- }): Promise<unknown>;
98
- };
99
- pins: {
100
- add(opts: {
101
- channel: string;
102
- timestamp: string;
103
- }): Promise<unknown>;
104
- remove(opts: {
105
- channel: string;
106
- timestamp: string;
107
- }): Promise<unknown>;
108
- };
109
- chat: SlackChatClient['chat'] & {
110
- delete(opts: {
111
- channel: string;
112
- ts: string;
113
- }): Promise<unknown>;
114
- };
115
- }
19
+ export type SlackWebClientLike = WebClient;
116
20
  export interface SlackEndpointOptions {
117
21
  readonly id: CapabilityId;
118
22
  readonly config: ResolvedSlackConfig;
119
23
  readonly http?: HttpHost;
120
- readonly createClient?: (token: string) => SlackWebClientLike;
24
+ readonly webApiAgent?: ReturnType<typeof createSlackWebApiAgent>;
25
+ readonly webOptions?: WebClientOptions;
121
26
  readonly createSocket?: (opts: {
122
27
  readonly appToken: string;
123
28
  readonly clientPingTimeout: number;
124
29
  readonly autoReconnectEnabled: false;
125
30
  }) => SlackSocketLike;
126
31
  }
127
- export declare class SlackEndpoint extends Endpoint<SlackWebClientLike> implements SlackWebhookHandler {
32
+ export declare class SlackEndpoint extends WebClient implements Endpoint, SlackWebhookHandler {
128
33
  #private;
129
- readonly management: EndpointManagement;
130
- readonly control: EndpointControl;
34
+ readonly [endpointSpec]: EndpointSpecification;
131
35
  constructor(options: SlackEndpointOptions);
132
36
  /** Console 展示 / AdapterIndex live name(多 endpoint 时与 entry name 一致)。 */
133
37
  get name(): string;
134
- get client(): SlackWebClientLike;
135
- get transportState(): import("@zhin.js/adapter").EndpointLifecycleState;
136
38
  get platformUserId(): string | undefined;
137
39
  get config(): ResolvedSlackConfig;
138
- start(): Promise<void>;
139
- open(): void;
140
- close(): void;
141
- stop(): Promise<void>;
142
- send({ conversation, payload }: EndpointSendRequest): Promise<string>;
143
40
  /** Test / internal: admit a message event when open. */
144
- admit(event: SlackMessageEvent | SlackEvent): void;
41
+ admit(event: SlackMessageEvent | SlackEvent, original?: unknown): void;
145
42
  admitInteraction(payload: SlackInteractionPayload): void;
146
43
  admitSlashCommand(cmd: SlackSlashCommand): void;
147
44
  handleEnvelope(body: unknown): void;