@cuylabs/channel-slack 0.6.0 → 0.7.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.
package/dist/app-home.js CHANGED
@@ -1,3 +1,7 @@
1
+ import {
2
+ publishSlackHomeView
3
+ } from "./chunk-IRFKUPJN.js";
4
+
1
5
  // src/app-home.ts
2
6
  function installSlackAppHome({
3
7
  boltApp,
@@ -7,8 +11,9 @@ function installSlackAppHome({
7
11
  boltApp.event("app_home_opened", async ({ event, client }) => {
8
12
  const homeEvent = event;
9
13
  try {
10
- await client.views.publish({
11
- user_id: homeEvent.user,
14
+ await publishSlackHomeView({
15
+ client,
16
+ userId: homeEvent.user,
12
17
  view: await buildView({ event: homeEvent })
13
18
  });
14
19
  logger?.debug?.("Slack App Home published", {
@@ -0,0 +1,235 @@
1
+ // src/views/client.ts
2
+ async function openSlackModal({
3
+ client,
4
+ triggerId,
5
+ view,
6
+ token
7
+ }) {
8
+ return await requireViewsMethod(
9
+ client,
10
+ "open"
11
+ )({
12
+ ...tokenArgs(token),
13
+ trigger_id: requireTrimmed(triggerId, "triggerId"),
14
+ view
15
+ });
16
+ }
17
+ async function pushSlackModal({
18
+ client,
19
+ triggerId,
20
+ view,
21
+ token
22
+ }) {
23
+ return await requireViewsMethod(
24
+ client,
25
+ "push"
26
+ )({
27
+ ...tokenArgs(token),
28
+ trigger_id: requireTrimmed(triggerId, "triggerId"),
29
+ view
30
+ });
31
+ }
32
+ async function updateSlackView({
33
+ client,
34
+ view,
35
+ viewId,
36
+ externalId,
37
+ hash,
38
+ token
39
+ }) {
40
+ const normalizedViewId = trimOptional(viewId);
41
+ const normalizedExternalId = trimOptional(externalId);
42
+ if (!normalizedViewId && !normalizedExternalId) {
43
+ throw new Error("updateSlackView requires viewId or externalId.");
44
+ }
45
+ return await requireViewsMethod(
46
+ client,
47
+ "update"
48
+ )({
49
+ ...tokenArgs(token),
50
+ ...normalizedViewId ? { view_id: normalizedViewId } : {},
51
+ ...normalizedExternalId ? { external_id: normalizedExternalId } : {},
52
+ ...trimOptional(hash) ? { hash: hash?.trim() } : {},
53
+ view
54
+ });
55
+ }
56
+ async function publishSlackHomeView({
57
+ client,
58
+ userId,
59
+ view,
60
+ hash,
61
+ token
62
+ }) {
63
+ return await requireViewsMethod(
64
+ client,
65
+ "publish"
66
+ )({
67
+ ...tokenArgs(token),
68
+ user_id: requireTrimmed(userId, "userId"),
69
+ ...trimOptional(hash) ? { hash: hash?.trim() } : {},
70
+ view
71
+ });
72
+ }
73
+ function requireViewsMethod(client, methodName) {
74
+ const method = client.views?.[methodName];
75
+ if (typeof method !== "function") {
76
+ throw new Error(`Slack client does not expose views.${methodName}.`);
77
+ }
78
+ return method.bind(client.views);
79
+ }
80
+ function requireTrimmed(value, label) {
81
+ const trimmed = value.trim();
82
+ if (!trimmed) {
83
+ throw new Error(`${label} is required.`);
84
+ }
85
+ return trimmed;
86
+ }
87
+ function trimOptional(value) {
88
+ const trimmed = value?.trim();
89
+ return trimmed ? trimmed : void 0;
90
+ }
91
+ function tokenArgs(token) {
92
+ const trimmed = token?.trim();
93
+ return trimmed ? { token: trimmed } : {};
94
+ }
95
+
96
+ // src/views/metadata.ts
97
+ var SLACK_VIEW_PRIVATE_METADATA_MAX_CHARS = 3e3;
98
+ function encodeSlackViewPrivateMetadata(value) {
99
+ if (value === void 0 || value === null) {
100
+ return "";
101
+ }
102
+ const encoded = typeof value === "string" ? value : JSON.stringify(value);
103
+ if (encoded.length > SLACK_VIEW_PRIVATE_METADATA_MAX_CHARS) {
104
+ throw new Error(
105
+ `Slack view private_metadata exceeds ${SLACK_VIEW_PRIVATE_METADATA_MAX_CHARS} characters.`
106
+ );
107
+ }
108
+ return encoded;
109
+ }
110
+ function decodeSlackViewPrivateMetadata(privateMetadata) {
111
+ const normalized = privateMetadata?.trim();
112
+ if (!normalized) {
113
+ return void 0;
114
+ }
115
+ try {
116
+ return JSON.parse(normalized);
117
+ } catch {
118
+ return normalized;
119
+ }
120
+ }
121
+ function readSlackViewPrivateMetadata(view) {
122
+ return decodeSlackViewPrivateMetadata(view.private_metadata);
123
+ }
124
+
125
+ // src/views/workflow.ts
126
+ function registerSlackViewWorkflow({
127
+ boltApp,
128
+ callbackId,
129
+ decodePrivateMetadata,
130
+ onSubmission,
131
+ onClose,
132
+ onError
133
+ }) {
134
+ if (onSubmission) {
135
+ boltApp.view(
136
+ { callback_id: callbackId, type: "view_submission" },
137
+ // Bolt's listener args are structurally stable, but the exact generic
138
+ // narrows differ between view_submission and view_closed.
139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
+ async ({ ack, body, client, view }) => {
141
+ const baseContext = createWorkflowContext({
142
+ body,
143
+ client,
144
+ view
145
+ });
146
+ try {
147
+ const metadata = resolveMetadata(
148
+ decodePrivateMetadata,
149
+ view,
150
+ baseContext
151
+ );
152
+ const response = await onSubmission({
153
+ ...baseContext,
154
+ metadata
155
+ });
156
+ await ack(response);
157
+ } catch (error) {
158
+ try {
159
+ await ack();
160
+ } catch {
161
+ }
162
+ await onError?.(error, baseContext);
163
+ }
164
+ }
165
+ );
166
+ }
167
+ if (onClose) {
168
+ boltApp.view(
169
+ { callback_id: callbackId, type: "view_closed" },
170
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
171
+ async ({ ack, body, client, view }) => {
172
+ const baseContext = createWorkflowContext({
173
+ body,
174
+ client,
175
+ view
176
+ });
177
+ await ack();
178
+ try {
179
+ const metadata = resolveMetadata(
180
+ decodePrivateMetadata,
181
+ view,
182
+ baseContext
183
+ );
184
+ await onClose({
185
+ ...baseContext,
186
+ metadata
187
+ });
188
+ } catch (error) {
189
+ await onError?.(error, baseContext);
190
+ }
191
+ }
192
+ );
193
+ }
194
+ return { callbackId };
195
+ }
196
+ function createWorkflowContext({
197
+ body,
198
+ client,
199
+ view
200
+ }) {
201
+ const bodyRecord = isRecord(body) ? body : {};
202
+ const user = isRecord(bodyRecord.user) ? bodyRecord.user : {};
203
+ const team = isRecord(bodyRecord.team) ? bodyRecord.team : {};
204
+ const enterprise = isRecord(bodyRecord.enterprise) ? bodyRecord.enterprise : {};
205
+ return {
206
+ body,
207
+ client,
208
+ view,
209
+ ...typeof view.callback_id === "string" ? { callbackId: view.callback_id } : {},
210
+ ...typeof bodyRecord.trigger_id === "string" ? { triggerId: bodyRecord.trigger_id } : {},
211
+ actor: {
212
+ ...typeof user.id === "string" ? { userId: user.id } : {},
213
+ ...typeof team.id === "string" ? { teamId: team.id } : {},
214
+ ...typeof enterprise.id === "string" ? { enterpriseId: enterprise.id } : {}
215
+ }
216
+ };
217
+ }
218
+ function resolveMetadata(decodePrivateMetadata, view, context) {
219
+ return decodePrivateMetadata ? decodePrivateMetadata(view.private_metadata, context) : decodeSlackViewPrivateMetadata(view.private_metadata);
220
+ }
221
+ function isRecord(value) {
222
+ return typeof value === "object" && value !== null;
223
+ }
224
+
225
+ export {
226
+ openSlackModal,
227
+ pushSlackModal,
228
+ updateSlackView,
229
+ publishSlackHomeView,
230
+ SLACK_VIEW_PRIVATE_METADATA_MAX_CHARS,
231
+ encodeSlackViewPrivateMetadata,
232
+ decodeSlackViewPrivateMetadata,
233
+ readSlackViewPrivateMetadata,
234
+ registerSlackViewWorkflow
235
+ };
@@ -1,3 +1,7 @@
1
+ import {
2
+ openSlackModal
3
+ } from "../chunk-IRFKUPJN.js";
4
+
1
5
  // src/feedback/block.ts
2
6
  var SLACK_FEEDBACK_ACTION_ID = "agent_feedback";
3
7
  function createSlackFeedbackBlock(options = {}) {
@@ -76,13 +80,7 @@ function registerSlackFeedbackAction(app, options) {
76
80
  "Slack feedback payload did not include trigger_id."
77
81
  );
78
82
  }
79
- if (typeof client.views?.open !== "function") {
80
- throw new Error("Slack client does not expose views.open.");
81
- }
82
- await client.views.open({
83
- trigger_id: triggerId,
84
- view
85
- });
83
+ await openSlackModal({ client, triggerId, view });
86
84
  };
87
85
  const acknowledgeEphemeral = async (text) => {
88
86
  await client.chat.postEphemeral({
@@ -1,6 +1,6 @@
1
1
  import { I as InspectSlackConnectionOptions, f as SlackDiagnosticsClient, c as SlackConnectionInspection } from '../inspect-BpY5JA0K.js';
2
2
 
3
- type SlackSetupFeature = "assistant" | "app-mentions" | "direct-messages" | "channel-messages" | "slash-commands" | "shortcuts" | "artifacts" | "canvas-artifacts" | "history" | "interactivity" | "feedback" | "user-profiles" | "user-emails" | "workspace-search";
3
+ type SlackSetupFeature = "assistant" | "app-mentions" | "direct-messages" | "channel-messages" | "slash-commands" | "shortcuts" | "artifacts" | "canvas-artifacts" | "history" | "interactivity" | "views" | "feedback" | "user-profiles" | "user-emails" | "workspace-search";
4
4
  type SlackSetupFeaturePreset = "assistant" | "channel-adapter" | "agent-app";
5
5
  type SlackSetupTransport = "http" | "socket";
6
6
  interface SlackSetupEnvironmentVariable {
@@ -53,6 +53,9 @@ var FEATURE_REQUIREMENTS = {
53
53
  botScopes: ["chat:write"],
54
54
  interactivity: true
55
55
  },
56
+ views: {
57
+ interactivity: true
58
+ },
56
59
  feedback: {
57
60
  botScopes: ["chat:write"],
58
61
  interactivity: true
@@ -1,3 +1,6 @@
1
+ import {
2
+ createSlackBoltApp
3
+ } from "../chunk-QJYCHWN6.js";
1
4
  import {
2
5
  acquireSlackSocketModePostgresLock,
3
6
  acquireSlackSocketModeProcessLock,
@@ -7,9 +10,6 @@ import {
7
10
  createSlackSocketModeRuntime,
8
11
  redactSlackSocketModeLogValue
9
12
  } from "../chunk-73QXT7MA.js";
10
- import {
11
- createSlackBoltApp
12
- } from "../chunk-QJYCHWN6.js";
13
13
  import "../chunk-S3SWPYXJ.js";
14
14
  export {
15
15
  acquireSlackSocketModePostgresLock,
@@ -0,0 +1,98 @@
1
+ import { App } from '@slack/bolt';
2
+ import { View, HomeView } from '@slack/types';
3
+
4
+ type SlackViewCallbackId = string | RegExp;
5
+ interface SlackViewApiResponse {
6
+ ok?: boolean;
7
+ view?: unknown;
8
+ [key: string]: unknown;
9
+ }
10
+ interface SlackViewsClient {
11
+ views?: {
12
+ open?: unknown;
13
+ push?: unknown;
14
+ update?: unknown;
15
+ publish?: unknown;
16
+ };
17
+ }
18
+ interface OpenSlackModalOptions {
19
+ client: SlackViewsClient;
20
+ triggerId: string;
21
+ view: View;
22
+ token?: string;
23
+ }
24
+ interface PushSlackModalOptions {
25
+ client: SlackViewsClient;
26
+ triggerId: string;
27
+ view: View;
28
+ token?: string;
29
+ }
30
+ interface UpdateSlackViewOptions {
31
+ client: SlackViewsClient;
32
+ view: View;
33
+ viewId?: string;
34
+ externalId?: string;
35
+ hash?: string;
36
+ token?: string;
37
+ }
38
+ interface PublishSlackHomeViewOptions {
39
+ client: SlackViewsClient;
40
+ userId: string;
41
+ view: HomeView;
42
+ hash?: string;
43
+ token?: string;
44
+ }
45
+ interface SlackViewPayload {
46
+ id?: string;
47
+ callback_id?: string;
48
+ private_metadata?: string;
49
+ state?: unknown;
50
+ hash?: string;
51
+ [key: string]: unknown;
52
+ }
53
+ interface SlackViewActor {
54
+ userId?: string;
55
+ teamId?: string;
56
+ enterpriseId?: string;
57
+ }
58
+ interface SlackViewSubmissionAckResponse {
59
+ response_action: "clear" | "errors" | "push" | "update";
60
+ errors?: Record<string, string>;
61
+ view?: View;
62
+ }
63
+ interface SlackViewWorkflowContext<TMetadata = unknown> {
64
+ body: unknown;
65
+ client: SlackViewsClient;
66
+ view: SlackViewPayload;
67
+ callbackId?: string;
68
+ triggerId?: string;
69
+ actor: SlackViewActor;
70
+ metadata: TMetadata | undefined;
71
+ }
72
+ interface RegisterSlackViewWorkflowOptions<TMetadata = unknown> {
73
+ boltApp: App;
74
+ callbackId: SlackViewCallbackId;
75
+ decodePrivateMetadata?: (privateMetadata: string | undefined, context: Omit<SlackViewWorkflowContext<TMetadata>, "metadata">) => TMetadata | undefined;
76
+ onSubmission?: (context: SlackViewWorkflowContext<TMetadata>) => SlackViewSubmissionAckResponse | void | Promise<SlackViewSubmissionAckResponse | void>;
77
+ onClose?: (context: SlackViewWorkflowContext<TMetadata>) => void | Promise<void>;
78
+ onError?: (error: unknown, context: Omit<SlackViewWorkflowContext<TMetadata>, "metadata"> & {
79
+ metadata?: TMetadata | undefined;
80
+ }) => void | Promise<void>;
81
+ }
82
+ interface SlackViewWorkflowRegistration {
83
+ callbackId: SlackViewCallbackId;
84
+ }
85
+
86
+ declare function openSlackModal({ client, triggerId, view, token, }: OpenSlackModalOptions): Promise<SlackViewApiResponse>;
87
+ declare function pushSlackModal({ client, triggerId, view, token, }: PushSlackModalOptions): Promise<SlackViewApiResponse>;
88
+ declare function updateSlackView({ client, view, viewId, externalId, hash, token, }: UpdateSlackViewOptions): Promise<SlackViewApiResponse>;
89
+ declare function publishSlackHomeView({ client, userId, view, hash, token, }: PublishSlackHomeViewOptions): Promise<SlackViewApiResponse>;
90
+
91
+ declare const SLACK_VIEW_PRIVATE_METADATA_MAX_CHARS = 3000;
92
+ declare function encodeSlackViewPrivateMetadata(value: unknown): string;
93
+ declare function decodeSlackViewPrivateMetadata<T = unknown>(privateMetadata: string | undefined): T | undefined;
94
+ declare function readSlackViewPrivateMetadata<T = unknown>(view: Pick<SlackViewPayload, "private_metadata">): T | undefined;
95
+
96
+ declare function registerSlackViewWorkflow<TMetadata = unknown>({ boltApp, callbackId, decodePrivateMetadata, onSubmission, onClose, onError, }: RegisterSlackViewWorkflowOptions<TMetadata>): SlackViewWorkflowRegistration;
97
+
98
+ export { type OpenSlackModalOptions, type PublishSlackHomeViewOptions, type PushSlackModalOptions, type RegisterSlackViewWorkflowOptions, SLACK_VIEW_PRIVATE_METADATA_MAX_CHARS, type SlackViewActor, type SlackViewApiResponse, type SlackViewCallbackId, type SlackViewPayload, type SlackViewSubmissionAckResponse, type SlackViewWorkflowContext, type SlackViewWorkflowRegistration, type SlackViewsClient, type UpdateSlackViewOptions, decodeSlackViewPrivateMetadata, encodeSlackViewPrivateMetadata, openSlackModal, publishSlackHomeView, pushSlackModal, readSlackViewPrivateMetadata, registerSlackViewWorkflow, updateSlackView };
@@ -0,0 +1,22 @@
1
+ import {
2
+ SLACK_VIEW_PRIVATE_METADATA_MAX_CHARS,
3
+ decodeSlackViewPrivateMetadata,
4
+ encodeSlackViewPrivateMetadata,
5
+ openSlackModal,
6
+ publishSlackHomeView,
7
+ pushSlackModal,
8
+ readSlackViewPrivateMetadata,
9
+ registerSlackViewWorkflow,
10
+ updateSlackView
11
+ } from "../chunk-IRFKUPJN.js";
12
+ export {
13
+ SLACK_VIEW_PRIVATE_METADATA_MAX_CHARS,
14
+ decodeSlackViewPrivateMetadata,
15
+ encodeSlackViewPrivateMetadata,
16
+ openSlackModal,
17
+ publishSlackHomeView,
18
+ pushSlackModal,
19
+ readSlackViewPrivateMetadata,
20
+ registerSlackViewWorkflow,
21
+ updateSlackView
22
+ };
package/docs/README.md CHANGED
@@ -19,6 +19,7 @@ your adapter or application needs.
19
19
  - [Setup requirements](concepts/setup-requirements.md)
20
20
  - [Supplemental history](concepts/supplemental-history.md)
21
21
  - [Transport runtime](concepts/transport-runtime.md)
22
+ - [Views](concepts/views.md)
22
23
 
23
24
  ## Recipes
24
25
 
@@ -0,0 +1,46 @@
1
+ # Slack Views
2
+
3
+ `@cuylabs/channel-slack/views` provides Slack-runtime primitives for modal and
4
+ Home view workflows. It keeps Slack Web API and Bolt details in
5
+ `channel-slack` while product packages decide what a workflow means.
6
+
7
+ ```typescript
8
+ import {
9
+ encodeSlackViewPrivateMetadata,
10
+ openSlackModal,
11
+ registerSlackViewWorkflow,
12
+ } from "@cuylabs/channel-slack/views";
13
+
14
+ await openSlackModal({
15
+ client,
16
+ triggerId,
17
+ view: {
18
+ type: "modal",
19
+ callback_id: "incident_triage",
20
+ private_metadata: encodeSlackViewPrivateMetadata({
21
+ workflowId: "triage-123",
22
+ }),
23
+ title: { type: "plain_text", text: "Triage incident" },
24
+ submit: { type: "plain_text", text: "Continue" },
25
+ close: { type: "plain_text", text: "Cancel" },
26
+ blocks: [],
27
+ },
28
+ });
29
+
30
+ registerSlackViewWorkflow({
31
+ boltApp,
32
+ callbackId: "incident_triage",
33
+ onSubmission: async ({ metadata, view, actor }) => {
34
+ // Load product-owned workflow state by metadata.workflowId, validate
35
+ // view.state, then continue the workflow or return field errors.
36
+ return { response_action: "clear" };
37
+ },
38
+ });
39
+ ```
40
+
41
+ Use `private_metadata` for compact routing data such as a workflow id, request
42
+ id, or session id. Store durable workflow state outside the view, for example in
43
+ the application database or the existing interactive-request store.
44
+
45
+ The `views` setup feature does not require a special bot scope, but it does
46
+ require Slack interactivity to be enabled for the app.
@@ -3,23 +3,24 @@
3
3
  Use feature subpaths for new code. They make dependency expectations clearer and
4
4
  keep application code close to the package boundary it uses.
5
5
 
6
- | Export | Depends on | Notes |
7
- | ------------------------------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
8
- | `@cuylabs/channel-slack/core` | no Slack SDK runtime imports | Transport-neutral parsing, formatting, types, sessions, turn context |
9
- | `@cuylabs/channel-slack/policy` | `pg` only when using connection-string Postgres state | Message admission and in-memory/Postgres policy state |
10
- | `@cuylabs/channel-slack/history` | `@slack/web-api` types | History reader accepts a Slack WebClient or minimal conversations client |
11
- | `@cuylabs/channel-slack/app-home` | `@slack/bolt`, `@slack/types` | Slack App Home registration helper |
12
- | `@cuylabs/channel-slack/artifacts` | no Slack SDK runtime imports; requires a Web API-like client at call time | Text, file, image, link, and Canvas artifact publishing |
13
- | `@cuylabs/channel-slack/auth` | no Slack SDK runtime imports; `pg` is not required | Auth option types, auth resolution, OAuth installation stores |
14
- | `@cuylabs/channel-slack/transports` | `@slack/bolt`, `express`; `pg` only when using connection-string Postgres locks | HTTP and Socket Mode transport helpers |
15
- | `@cuylabs/channel-slack/transports/http` | `@slack/bolt`, `express` | HTTP Events API Bolt app factory |
16
- | `@cuylabs/channel-slack/transports/socket` | `@slack/bolt`; `pg` only when using connection-string Postgres locks | Socket Mode app factory, runtime guard, process/Postgres locks |
17
- | `@cuylabs/channel-slack/setup` | diagnostics only when inspecting live tokens | Setup requirements and app manifest helpers |
18
- | `@cuylabs/channel-slack/diagnostics` | `@slack/web-api` | Token, auth, and scope inspection |
19
- | `@cuylabs/channel-slack/entrypoints` | no Slack SDK runtime imports | Slash command and shortcut payload normalization |
20
- | `@cuylabs/channel-slack/users` | `@slack/web-api` when using default client | User profile lookup and mention enrichment |
21
- | `@cuylabs/channel-slack/targets` | no Slack SDK runtime imports unless resolving names through a client | Parse and resolve channel/user targets |
22
- | `@cuylabs/channel-slack/feedback` | `@slack/types` types | Feedback block and action helpers |
6
+ | Export | Depends on | Notes |
7
+ | ------------------------------------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
8
+ | `@cuylabs/channel-slack/core` | no Slack SDK runtime imports | Transport-neutral parsing, formatting, types, sessions, turn context |
9
+ | `@cuylabs/channel-slack/policy` | `pg` only when using connection-string Postgres state | Message admission and in-memory/Postgres policy state |
10
+ | `@cuylabs/channel-slack/history` | `@slack/web-api` types | History reader accepts a Slack WebClient or minimal conversations client |
11
+ | `@cuylabs/channel-slack/app-home` | `@slack/bolt`, `@slack/types` | Slack App Home registration helper |
12
+ | `@cuylabs/channel-slack/artifacts` | no Slack SDK runtime imports; requires a Web API-like client at call time | Text, file, image, link, and Canvas artifact publishing |
13
+ | `@cuylabs/channel-slack/auth` | no Slack SDK runtime imports; `pg` is not required | Auth option types, auth resolution, OAuth installation stores |
14
+ | `@cuylabs/channel-slack/transports` | `@slack/bolt`, `express`; `pg` only when using connection-string Postgres locks | HTTP and Socket Mode transport helpers |
15
+ | `@cuylabs/channel-slack/transports/http` | `@slack/bolt`, `express` | HTTP Events API Bolt app factory |
16
+ | `@cuylabs/channel-slack/transports/socket` | `@slack/bolt`; `pg` only when using connection-string Postgres locks | Socket Mode app factory, runtime guard, process/Postgres locks |
17
+ | `@cuylabs/channel-slack/setup` | diagnostics only when inspecting live tokens | Setup requirements and app manifest helpers |
18
+ | `@cuylabs/channel-slack/diagnostics` | `@slack/web-api` | Token, auth, and scope inspection |
19
+ | `@cuylabs/channel-slack/entrypoints` | no Slack SDK runtime imports | Slash command and shortcut payload normalization |
20
+ | `@cuylabs/channel-slack/users` | `@slack/web-api` when using default client | User profile lookup and mention enrichment |
21
+ | `@cuylabs/channel-slack/targets` | no Slack SDK runtime imports unless resolving names through a client | Parse and resolve channel/user targets |
22
+ | `@cuylabs/channel-slack/feedback` | `@slack/types` types | Feedback block and action helpers |
23
+ | `@cuylabs/channel-slack/views` | `@slack/bolt`, `@slack/types` | Modal/Home view operations and workflow registration |
23
24
 
24
25
  The root export remains available for lightweight core and policy helpers:
25
26
 
@@ -29,6 +29,7 @@ src/
29
29
  socket/ Socket Mode Bolt app factory, runtime, locks
30
30
  targets/ channel/user target parsing and resolution
31
31
  users/ profile lookup and mention enrichment
32
+ views/ modal/Home view operations and workflow registration
32
33
  ```
33
34
 
34
35
  For public export details and peer dependency expectations, see
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cuylabs/channel-slack",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Agent-runtime-agnostic Slack channel primitives for AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -90,6 +90,11 @@
90
90
  "types": "./dist/users/index.d.ts",
91
91
  "import": "./dist/users/index.js",
92
92
  "default": "./dist/users/index.js"
93
+ },
94
+ "./views": {
95
+ "types": "./dist/views/index.d.ts",
96
+ "import": "./dist/views/index.js",
97
+ "default": "./dist/views/index.js"
93
98
  }
94
99
  },
95
100
  "files": [
@@ -143,9 +148,9 @@
143
148
  "node": ">=20"
144
149
  },
145
150
  "scripts": {
146
- "build": "tsup src/index.ts src/app-home.ts src/artifacts/index.ts src/core.ts src/assistant/index.ts src/auth/index.ts src/diagnostics/index.ts src/entrypoints/index.ts src/feedback/index.ts src/history/index.ts src/policy/index.ts src/setup/index.ts src/targets/index.ts src/transports/index.ts src/transports/http/index.ts src/transports/socket/index.ts src/users/index.ts --format esm --dts --clean",
151
+ "build": "tsup src/index.ts src/app-home.ts src/artifacts/index.ts src/core.ts src/assistant/index.ts src/auth/index.ts src/diagnostics/index.ts src/entrypoints/index.ts src/feedback/index.ts src/history/index.ts src/policy/index.ts src/setup/index.ts src/targets/index.ts src/transports/index.ts src/transports/http/index.ts src/transports/socket/index.ts src/users/index.ts src/views/index.ts --format esm --dts --clean",
147
152
  "clean": "rm -rf dist",
148
- "dev": "tsup src/index.ts src/app-home.ts src/artifacts/index.ts src/core.ts src/assistant/index.ts src/auth/index.ts src/diagnostics/index.ts src/entrypoints/index.ts src/feedback/index.ts src/history/index.ts src/policy/index.ts src/setup/index.ts src/targets/index.ts src/transports/index.ts src/transports/http/index.ts src/transports/socket/index.ts src/users/index.ts --format esm --dts --watch",
153
+ "dev": "tsup src/index.ts src/app-home.ts src/artifacts/index.ts src/core.ts src/assistant/index.ts src/auth/index.ts src/diagnostics/index.ts src/entrypoints/index.ts src/feedback/index.ts src/history/index.ts src/policy/index.ts src/setup/index.ts src/targets/index.ts src/transports/index.ts src/transports/http/index.ts src/transports/socket/index.ts src/users/index.ts src/views/index.ts --format esm --dts --watch",
149
154
  "lint": "eslint \"src/**/*.{ts,tsx}\" \"tests/**/*.{ts,tsx}\" --max-warnings=0",
150
155
  "test": "vitest run",
151
156
  "test:watch": "vitest",