@zhin.js/adapter-slack 6.0.12 → 6.0.14

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,46 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.0.14
4
+
5
+ ### Patch Changes
6
+
7
+ - 5969c5b: Add SideEventGateway so adapters forward notice/request/system into HandlerIndex. HandlerContext now exposes only generation-safe capabilities and prompt ports; live Endpoint escape hatches are removed.
8
+ - Updated dependencies [5969c5b]
9
+ - Updated dependencies [d336a3f]
10
+ - Updated dependencies [0c82a7e]
11
+ - Updated dependencies [b9217e4]
12
+ - Updated dependencies [5969c5b]
13
+ - Updated dependencies [5969c5b]
14
+ - Updated dependencies [974772e]
15
+ - Updated dependencies [5969c5b]
16
+ - Updated dependencies [5969c5b]
17
+ - Updated dependencies [2f786bd]
18
+ - Updated dependencies [63d89f9]
19
+ - Updated dependencies [71c7cdd]
20
+ - Updated dependencies [3cca0ea]
21
+ - Updated dependencies [1312ca0]
22
+ - Updated dependencies [985fa22]
23
+ - Updated dependencies [04b861d]
24
+ - Updated dependencies [a23d544]
25
+ - Updated dependencies [8cddabf]
26
+ - Updated dependencies [dbe5081]
27
+ - @zhin.js/im-contract@1.0.4
28
+ - @zhin.js/core@1.5.12
29
+ - @zhin.js/adapter@1.1.11
30
+ - @zhin.js/agent@1.1.14
31
+ - @zhin.js/host-http@1.0.11
32
+ - @zhin.js/command@1.0.15
33
+ - zhin.js@6.0.12
34
+ - @zhin.js/permission@1.0.3
35
+
36
+ ## 6.0.13
37
+
38
+ ### Patch Changes
39
+
40
+ - @zhin.js/core@1.5.11
41
+ - @zhin.js/agent@1.1.13
42
+ - zhin.js@6.0.11
43
+
3
44
  ## 6.0.12
4
45
 
5
46
  ### Patch Changes
package/adapters/slack.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Convention entry: discover `adapters/slack.ts` → defineAdapter.
4
4
  */
5
5
  import { defineAdapter } from 'zhin.js/adapter';
6
- import { messageGatewayToken } from '@zhin.js/core/runtime';
6
+ import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
7
7
  import { httpHostToken } from '@zhin.js/host-http';
8
8
  import { SlackEndpoint } from "../lib/endpoint.js";
9
9
  import { resolveSlackConfig, } from "../lib/protocol.js";
@@ -29,6 +29,7 @@ export default defineAdapter({
29
29
  return new SlackEndpoint({
30
30
  id: context.id,
31
31
  gateway: context.use(messageGatewayToken),
32
+ sideEvents: context.use(sideEventGatewayToken),
32
33
  http: context.use(httpHostToken),
33
34
  config,
34
35
  });
@@ -36,6 +37,7 @@ export default defineAdapter({
36
37
  return new SlackEndpoint({
37
38
  id: context.id,
38
39
  gateway: context.use(messageGatewayToken),
40
+ sideEvents: context.use(sideEventGatewayToken),
39
41
  config,
40
42
  });
41
43
  },
package/adapters/slack.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Convention entry: discover `adapters/slack.ts` → defineAdapter.
3
3
  */
4
4
  import { defineAdapter } from 'zhin.js/adapter';
5
- import { messageGatewayToken } from '@zhin.js/core/runtime';
5
+ import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
6
6
  import { httpHostToken } from '@zhin.js/host-http';
7
7
  import { SlackEndpoint } from '../src/endpoint.js';
8
8
  import {
@@ -34,6 +34,7 @@ export default defineAdapter<SlackAdapterConfig>({
34
34
  return new SlackEndpoint({
35
35
  id: context.id,
36
36
  gateway: context.use(messageGatewayToken),
37
+ sideEvents: context.use(sideEventGatewayToken),
37
38
  http: context.use(httpHostToken),
38
39
  config,
39
40
  });
@@ -41,6 +42,7 @@ export default defineAdapter<SlackAdapterConfig>({
41
42
  return new SlackEndpoint({
42
43
  id: context.id,
43
44
  gateway: context.use(messageGatewayToken),
45
+ sideEvents: context.use(sideEventGatewayToken),
44
46
  config,
45
47
  });
46
48
  },
package/lib/endpoint.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { EndpointInstance, EndpointManagement, EndpointSendRequest } from 'zhin.js/adapter';
2
- import type { MessageGateway } from '@zhin.js/core/runtime';
2
+ import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
3
3
  import type { HttpHost } from '@zhin.js/host-http';
4
4
  import type { CapabilityId } from 'zhin.js';
5
5
  import { type ResolvedSlackConfig, type SlackEvent, type SlackInteractionPayload, type SlackMessageEvent, type SlackSlashCommand } from './protocol.js';
@@ -118,6 +118,7 @@ export interface SlackWebClientLike extends SlackChatClient {
118
118
  export interface SlackEndpointOptions {
119
119
  readonly id: CapabilityId;
120
120
  readonly gateway: MessageGateway;
121
+ readonly sideEvents?: SideEventGateway;
121
122
  readonly config: ResolvedSlackConfig;
122
123
  readonly http?: HttpHost;
123
124
  readonly createClient?: (token: string) => SlackWebClientLike;
package/lib/endpoint.js CHANGED
@@ -12,6 +12,7 @@ import { normalizeSlackReactionName } from './slack-reaction.js';
12
12
  import { postSlackEphemeral } from './slack-response-url.js';
13
13
  import { editSlackContent, sendSlackContent } from './slack-outbound.js';
14
14
  import { registerSlackWebhookRoutes } from './webhook.js';
15
+ import { receiveSlackSideEvent } from './side-event-dispatch.js';
15
16
  export class SlackEndpoint {
16
17
  #logger;
17
18
  #options;
@@ -216,7 +217,12 @@ export class SlackEndpoint {
216
217
  handleEnvelope(body) {
217
218
  const envelope = body;
218
219
  if (envelope?.type === 'event_callback' && envelope.event) {
219
- this.admit(envelope.event);
220
+ const event = envelope.event;
221
+ if (event.type !== 'message' && event.type !== 'app_mention') {
222
+ receiveSlackSideEvent(this.#options.sideEvents, String(this.#options.id), this.#options.config.id, event, this.#logger);
223
+ return;
224
+ }
225
+ this.admit(event);
220
226
  }
221
227
  }
222
228
  trackMessageChannel(ts, channel) {
@@ -0,0 +1,4 @@
1
+ import type { SideEventGateway } from '@zhin.js/core/runtime';
2
+ import { type getAdapterLogger } from '@zhin.js/logger';
3
+ import type { SlackEvent } from './protocol.js';
4
+ export declare function receiveSlackSideEvent(sideEvents: SideEventGateway | undefined, endpointKey: string, configId: string, event: SlackEvent, logger: ReturnType<typeof getAdapterLogger>): void;
@@ -0,0 +1,45 @@
1
+ import { buildNotice, mapNoticeParts, senderFromId, SLACK_NOTICE_PARTS_MAP } from '@zhin.js/core';
2
+ import { formatCompact } from '@zhin.js/logger';
3
+ export function receiveSlackSideEvent(sideEvents, endpointKey, configId, event, logger) {
4
+ if (!sideEvents)
5
+ return;
6
+ const eventType = String(event.type ?? '');
7
+ if (!Object.prototype.hasOwnProperty.call(SLACK_NOTICE_PARTS_MAP, eventType))
8
+ return;
9
+ const record = event;
10
+ const parts = mapNoticeParts('slack', eventType);
11
+ const channel = typeof record.channel === 'string' ? record.channel : undefined;
12
+ const user = typeof record.user === 'string' ? record.user : undefined;
13
+ const sceneId = channel ?? user ?? configId;
14
+ const dedupeKey = [
15
+ eventType,
16
+ channel ?? '',
17
+ user ?? '',
18
+ String(record.ts ?? record.event_ts ?? ''),
19
+ ].join(':');
20
+ void sideEvents.receiveNotice(buildNotice(record, {
21
+ $id: `slack:${dedupeKey}`,
22
+ $adapter: 'slack',
23
+ $endpoint: configId,
24
+ $type: 'notice',
25
+ $scene_id: sceneId,
26
+ $scene_type: parts.scene_type,
27
+ $sub_type: parts.sub_type,
28
+ $actor: senderFromId(user),
29
+ $target: senderFromId(typeof record.item_user === 'string' ? record.item_user : undefined),
30
+ $timestamp: toMillis(record.event_ts ?? record.ts),
31
+ })).catch((err) => {
32
+ logger.warn(formatCompact({
33
+ op: 'slack_side_event_failed',
34
+ endpoint: configId,
35
+ event: eventType,
36
+ error: err instanceof Error ? err.message : String(err),
37
+ }));
38
+ });
39
+ }
40
+ function toMillis(time) {
41
+ const value = Number(time);
42
+ if (!Number.isFinite(value) || value <= 0)
43
+ return Date.now();
44
+ return value < 1e12 ? Math.round(value * 1000) : Math.round(value);
45
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-slack",
3
- "version": "6.0.12",
3
+ "version": "6.0.14",
4
4
  "description": "Zhin.js Slack adapter for Plugin Runtime (Socket Mode / HTTP Events)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -34,21 +34,21 @@
34
34
  "dependencies": {
35
35
  "@slack/socket-mode": "^2.0.7",
36
36
  "@slack/web-api": "^7.19.0",
37
- "@zhin.js/adapter": "1.1.10",
38
- "@zhin.js/core": "1.5.10",
39
- "@zhin.js/host-http": "1.0.10",
40
- "@zhin.js/im-contract": "1.0.3",
37
+ "@zhin.js/adapter": "1.1.11",
38
+ "@zhin.js/core": "1.5.12",
39
+ "@zhin.js/host-http": "1.0.11",
40
+ "@zhin.js/im-contract": "1.0.4",
41
41
  "@zhin.js/logger": "1.0.76"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "zod": "^4.0.0",
45
- "@zhin.js/adapter": "1.1.10",
46
- "@zhin.js/agent": "1.1.12",
47
- "@zhin.js/command": "1.0.14",
48
- "@zhin.js/core": "1.5.10",
49
- "@zhin.js/host-http": "1.0.10",
50
- "@zhin.js/permission": "1.0.2",
51
- "zhin.js": "6.0.10"
45
+ "@zhin.js/adapter": "1.1.11",
46
+ "@zhin.js/agent": "1.1.14",
47
+ "@zhin.js/command": "1.0.15",
48
+ "@zhin.js/core": "1.5.12",
49
+ "@zhin.js/host-http": "1.0.11",
50
+ "@zhin.js/permission": "1.0.3",
51
+ "zhin.js": "6.0.12"
52
52
  },
53
53
  "peerDependenciesMeta": {
54
54
  "@zhin.js/agent": {
@@ -69,8 +69,8 @@
69
69
  "typescript": "^6.0.3",
70
70
  "vitest": "^4.1.10",
71
71
  "zod": "^4.4.3",
72
- "@zhin.js/agent": "1.1.12",
73
- "zhin.js": "6.0.10"
72
+ "@zhin.js/agent": "1.1.14",
73
+ "zhin.js": "6.0.12"
74
74
  },
75
75
  "files": [
76
76
  "adapters",
package/src/endpoint.ts CHANGED
@@ -10,7 +10,7 @@ import type {
10
10
  EndpointManagement,
11
11
  EndpointSendRequest,
12
12
  } from 'zhin.js/adapter';
13
- import type { MessageGateway } from '@zhin.js/core/runtime';
13
+ import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
14
14
  import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
15
15
  import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
16
16
  import type { CapabilityId } from 'zhin.js';
@@ -37,6 +37,7 @@ import { normalizeSlackReactionName } from './slack-reaction.js';
37
37
  import { postSlackEphemeral } from './slack-response-url.js';
38
38
  import { editSlackContent, sendSlackContent, type SlackChatClient } from './slack-outbound.js';
39
39
  import { registerSlackWebhookRoutes, type SlackWebhookHandler } from './webhook.js';
40
+ import { receiveSlackSideEvent } from './side-event-dispatch.js';
40
41
 
41
42
  export interface SlackSocketLike {
42
43
  on(
@@ -91,6 +92,7 @@ export interface SlackWebClientLike extends SlackChatClient {
91
92
  export interface SlackEndpointOptions {
92
93
  readonly id: CapabilityId;
93
94
  readonly gateway: MessageGateway;
95
+ readonly sideEvents?: SideEventGateway;
94
96
  readonly config: ResolvedSlackConfig;
95
97
  readonly http?: HttpHost;
96
98
  readonly createClient?: (token: string) => SlackWebClientLike;
@@ -316,7 +318,18 @@ export class SlackEndpoint implements EndpointInstance, SlackWebhookHandler {
316
318
  handleEnvelope(body: unknown): void {
317
319
  const envelope = body as SlackEventEnvelope;
318
320
  if (envelope?.type === 'event_callback' && envelope.event) {
319
- this.admit(envelope.event);
321
+ const event = envelope.event;
322
+ if (event.type !== 'message' && event.type !== 'app_mention') {
323
+ receiveSlackSideEvent(
324
+ this.#options.sideEvents,
325
+ String(this.#options.id),
326
+ this.#options.config.id,
327
+ event,
328
+ this.#logger,
329
+ );
330
+ return;
331
+ }
332
+ this.admit(event);
320
333
  }
321
334
  }
322
335
 
@@ -0,0 +1,54 @@
1
+ import { buildNotice, mapNoticeParts, senderFromId, SLACK_NOTICE_PARTS_MAP } from '@zhin.js/core';
2
+ import type { SideEventGateway } from '@zhin.js/core/runtime';
3
+ import { formatCompact, type getAdapterLogger } from '@zhin.js/logger';
4
+ import type { SlackEvent } from './protocol.js';
5
+
6
+ export function receiveSlackSideEvent(
7
+ sideEvents: SideEventGateway | undefined,
8
+ endpointKey: string,
9
+ configId: string,
10
+ event: SlackEvent,
11
+ logger: ReturnType<typeof getAdapterLogger>,
12
+ ): void {
13
+ if (!sideEvents) return;
14
+ const eventType = String(event.type ?? '');
15
+ if (!Object.prototype.hasOwnProperty.call(SLACK_NOTICE_PARTS_MAP, eventType)) return;
16
+ const record = event as Record<string, unknown>;
17
+ const parts = mapNoticeParts('slack', eventType);
18
+ const channel = typeof record.channel === 'string' ? record.channel : undefined;
19
+ const user = typeof record.user === 'string' ? record.user : undefined;
20
+ const sceneId = channel ?? user ?? configId;
21
+ const dedupeKey = [
22
+ eventType,
23
+ channel ?? '',
24
+ user ?? '',
25
+ String(record.ts ?? record.event_ts ?? ''),
26
+ ].join(':');
27
+ void sideEvents.receiveNotice(buildNotice(record, {
28
+ $id: `slack:${dedupeKey}`,
29
+ $adapter: 'slack' as never,
30
+ $endpoint: configId,
31
+ $type: 'notice',
32
+ $scene_id: sceneId,
33
+ $scene_type: parts.scene_type,
34
+ $sub_type: parts.sub_type,
35
+ $actor: senderFromId(user),
36
+ $target: senderFromId(
37
+ typeof record.item_user === 'string' ? record.item_user : undefined,
38
+ ),
39
+ $timestamp: toMillis(record.event_ts ?? record.ts),
40
+ })).catch((err) => {
41
+ logger.warn(formatCompact({
42
+ op: 'slack_side_event_failed',
43
+ endpoint: configId,
44
+ event: eventType,
45
+ error: err instanceof Error ? err.message : String(err),
46
+ }));
47
+ });
48
+ }
49
+
50
+ function toMillis(time: unknown): number {
51
+ const value = Number(time);
52
+ if (!Number.isFinite(value) || value <= 0) return Date.now();
53
+ return value < 1e12 ? Math.round(value * 1000) : Math.round(value);
54
+ }