@assemblyline-agents/slack 1.0.0 → 3.0.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 OpenEve contributors
3
+ Copyright (c) 2026 Assembly Line contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -2,7 +2,113 @@
2
2
 
3
3
  Official Assembly Line Slack channel plugin.
4
4
 
5
- It exports `defineSlackChannel(options)`, which receives Slack Events API callbacks over HTTP (with request-signature verification) and delivers agent replies through the Slack Web API, including file uploads and recent-activity context. The package also registers a Slack connection plugin (`defineSlackConnection`) and bundles a skill under `skills/` that teaches agents Slack-specific behavior. Requires `SLACK_SIGNING_SECRET` and `SLACK_BOT_TOKEN`.
5
+ It exports `defineSlackChannel(options)`, which receives Slack Events API callbacks over HTTP (with request-signature verification) and delivers agent replies through the Slack Web API, including file uploads and recent-activity context. The package also registers a Slack connection plugin (`defineSlackConnection`). A single installation requires `SLACK_SIGNING_SECRET`, `SLACK_BOT_TOKEN`, and the default bot scopes including `files:read` and `files:write`.
6
+
7
+ Inbound message text is decoded from Slack's mrkdwn transport form before it
8
+ reaches the agent: auto-linked URLs (`<https://…>`, `<https://…|label>`)
9
+ collapse back to the bare URL and Slack's HTML entity escapes (`&amp;`,
10
+ `&lt;`, `&gt;`) are restored, so pasted content such as one-time connection
11
+ pairing packets arrives exactly as the user typed it. Mention and command
12
+ sequences (`<@…>`, `<#…>`, `<!…>`) pass through unchanged.
13
+
14
+ Inbound files preserve their Slack media type and attachment classification.
15
+ Voice clips are therefore routed through any configured gateway media processor,
16
+ such as `openRouterAudioTranscription()`, before the model receives the turn.
17
+
18
+ Text-only outbound replies use Slack's standard-Markdown `markdown_text` field, so
19
+ headings, bold text, labeled links, lists, tables, and code from an agent render
20
+ natively without Slack-specific prompting. Responses larger than Slack's
21
+ 12,000-character field limit are split at natural text boundaries and delivered
22
+ as consecutive messages to the same preserved channel and thread. Delivery also
23
+ neutralizes broadcast commands: `<!here>`, `<!channel>`, and `<!everyone>`
24
+ (with or without a `|label`) are replaced with their plain-text forms (`@here`,
25
+ `@channel`, `@everyone`), which Slack renders inert. An agent that quotes user
26
+ input therefore cannot ping the whole channel; links and user mentions in
27
+ outbound text keep working.
28
+
29
+ File delivery is explicit and durable. An agent calls `deliver_artifact` once
30
+ for every completed `/workspace` file it needs to attach. The connector posts
31
+ the final response together with all selected files and reports success only
32
+ when Slack confirms every file id. Upload or completion failures leave the
33
+ combined delivery unsent for that attempt and the durable queue retries it. If
34
+ the queue exhausts its attempts, the runtime records `deliveryStatus: "failed"`
35
+ on the run and creates one text-only failure notice naming the preserved files
36
+ and containing the real delivery error. The ticket declares the exact byte
37
+ length to Slack; the raw upload leaves HTTP `Content-Length` framing to the
38
+ runtime fetch implementation.
39
+
40
+ The connector uses Slack's native agent loading status on every turn. It starts
41
+ with `is working...` and cycles these ten messages under the composer in a new
42
+ random order for each turn:
43
+
44
+ `Beboppin'`, `Boondoggling`, `Cerebrating`, `Combobulating`, `Cooking`,
45
+ `Elucidating`, `Flibbertigibbeting`, `Hullaballooing`, `Ionizing`, and
46
+ `Photosynthesizing`.
47
+
48
+ This behavior is automatic for every deployment and uses the required
49
+ `chat:write` scope. The connector refreshes the status every 90 seconds so it
50
+ stays visible for turns longer than Slack's two-minute status timeout, then
51
+ stops the heartbeat and clears the status when the turn exits. Status updates
52
+ are best-effort, so a Slack-side status error does not prevent the agent from
53
+ completing or delivering its reply. Each heartbeat reuses the turn's shuffled
54
+ order so the sequence does not reset or change while that turn is running.
55
+
56
+ One agent endpoint can serve multiple Slack workspace installations by setting
57
+ `SLACK_WORKSPACE_CREDENTIALS_JSON`. The object is keyed by Slack team ID, and
58
+ each value may contain `signingSecret`, `botToken`, and `botUserId`:
59
+
60
+ ```json
61
+ {
62
+ "T01234567": {
63
+ "signingSecret": "...",
64
+ "botToken": "xoxb-...",
65
+ "botUserId": "U01234567"
66
+ }
67
+ }
68
+ ```
69
+
70
+ The original single-workspace variables remain the fallback. Incoming request
71
+ verification, private-file downloads, replies, and uploads all select the
72
+ credentials associated with the event's team ID. Slack URL-verification
73
+ callbacks may omit that ID, so only that callback shape is checked against the
74
+ configured signing-secret set; team-identified events remain pinned to their
75
+ mapped secret.
76
+
77
+ Slack turns include a provider-scoped user principal by default. Map that
78
+ sender to a canonical company identity before agent hooks run when roles,
79
+ memory, or connection grants must follow the employee across channels:
80
+
81
+ ```ts
82
+ export default defineSlackChannel({
83
+ async resolvePrincipal(turn) {
84
+ const employee = await lookupEmployee(turn.userId!);
85
+ if (!employee) throw new Error("Unknown Slack user.");
86
+ return {
87
+ type: "user",
88
+ id: employee.id,
89
+ issuer: "company-directory",
90
+ attributes: { roles: employee.roles }
91
+ };
92
+ }
93
+ });
94
+ ```
95
+
96
+ Slack also reports each surface's privacy. DMs and assistant threads are
97
+ private to the authenticated principal; channel threads are shared. When the
98
+ agent opts into `audienceIsolation: true` in `agent.ts`, the runtime uses that
99
+ boundary for memory, history, personal connections, subagents, schedules, and
100
+ delivery, so private DM context is unavailable in a channel or another user's
101
+ DM. Without the opt-in (the default), every surface is trusted and the signal
102
+ has no effect.
103
+
104
+ Under isolation, a personal Slack where every channel belongs to one trusted
105
+ owner can still mark every surface private:
106
+
107
+ ```ts
108
+ export default defineSlackChannel({
109
+ isPrivateSurface: () => true
110
+ });
111
+ ```
6
112
 
7
113
  ## Install
8
114
 
@@ -10,6 +116,32 @@ It exports `defineSlackChannel(options)`, which receives Slack Events API callba
10
116
  npm install @assemblyline-agents/slack
11
117
  ```
12
118
 
119
+ With the Assembly Line CLI, add the channel instead:
120
+
121
+ ```sh
122
+ assembly-line add slack /path/to/agent
123
+ ```
124
+
125
+ This creates both `channels/slack.ts` and `slack-app-manifest.json`. The latter
126
+ comes from the package's reusable
127
+ [`templates/slack-app-manifest.json`](templates/slack-app-manifest.json) and
128
+ contains the bot scopes and `app_mention`/`message.im` event subscriptions
129
+ expected by the connector.
130
+
131
+ 1. Replace `https://your-agent.example.com/slack/events` in the generated
132
+ manifest with the deployed agent URL.
133
+ 2. In Slack's app dashboard, create an app **from an app manifest** and paste or
134
+ upload the JSON.
135
+ 3. Install the app to the workspace.
136
+ 4. Set `SLACK_SIGNING_SECRET` from **Basic Information** and
137
+ `SLACK_BOT_TOKEN` from **OAuth & Permissions** in the agent environment.
138
+ 5. Verify the installation with `assembly-line channels check /path/to/agent`.
139
+
140
+ The loading indicator only needs `chat:write`. The default manifest also
141
+ includes optional `groups:history` so private-channel thread context works
142
+ without another reinstall. Remove `groups:history` if the bot will never be
143
+ invited to private channels.
144
+
13
145
  ## Part of Assembly Line
14
146
 
15
147
  This package is part of [Assembly Line](https://github.com/jasonbadeaux/assembly-line), a vendor-neutral, filesystem-first framework for durable AI agents. See the developer documentation in [docs/developers/](https://github.com/jasonbadeaux/assembly-line/tree/main/docs/developers) for setup, agent authoring, and deployment guides.
@@ -0,0 +1,7 @@
1
+ import type { JsonObject } from "@assemblyline-agents/core";
2
+ import type { ChannelContext, ChannelTurn } from "@assemblyline-agents/runtime";
3
+ export declare function augmentContext(turn: ChannelTurn, ctx: ChannelContext): Promise<{
4
+ recentHistory?: string[];
5
+ channelContext?: JsonObject;
6
+ } | void>;
7
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EAIZ,MAAM,8BAA8B,CAAC;AAetC,wBAAsB,cAAc,CAClC,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC;IAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,CAAC,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAAC,CAyF3E"}
@@ -0,0 +1,236 @@
1
+ import { principalKey } from "@assemblyline-agents/runtime";
2
+ import { slackApi } from "./slack-api.js";
3
+ import { slackHistoryObservation } from "./message-context.js";
4
+ const SLACK_RECENT_ACTIVITY_HOURS = 24;
5
+ const SLACK_RECENT_ACTIVITY_LIMIT = 3;
6
+ const SLACK_RECENT_HISTORY_LIMIT = 20;
7
+ const SLACK_THREAD_DELTA_SCAN_LIMIT = 60;
8
+ const SLACK_THREAD_DELTA_LIMIT = 12;
9
+ const SLACK_CHANNEL_MATCH_LIMIT = 8;
10
+ const SLACK_CHANNEL_RECENT_LIMIT = 3;
11
+ const SLACK_HISTORY_HYDRATION_LIMIT = 15;
12
+ const SLACK_SUMMARY_MAX_CHARS = 240;
13
+ export async function augmentContext(turn, ctx) {
14
+ const slack = recordValue(turn.metadata?.slack);
15
+ const source = recordValue(turn.metadata?.source);
16
+ const surface = stringValue(slack?.surface);
17
+ const hydration = surface === "channel"
18
+ ? await hydrateSlackChannelHistory(turn, ctx, slack, source)
19
+ : { status: "not_applicable", observed: 0 };
20
+ const conversationMessages = await ctx.state.listRecentMessages(turn.conversationId, SLACK_THREAD_DELTA_SCAN_LIMIT);
21
+ const recentHistory = conversationMessages
22
+ .filter((message) => message.content.observed !== true)
23
+ .slice(-SLACK_RECENT_HISTORY_LIMIT)
24
+ .map(messageHistoryLine);
25
+ const threadDelta = surface === "channel"
26
+ ? unseenObservedThreadMessages(conversationMessages).map((message) => historyContextMessage(message, {}))
27
+ : [];
28
+ const channelSearchScope = surface === "channel" && source
29
+ ? {
30
+ agentScope: ctx.agentScope,
31
+ channel: turn.channel,
32
+ source: {
33
+ provider: stringValue(source.provider) ?? "slack",
34
+ workspaceId: stringValue(source.workspaceId) ?? "unknown",
35
+ channelId: stringValue(source.channelId) ?? stringValue(slack?.channel) ?? "unknown"
36
+ },
37
+ excludeConversationId: turn.conversationId,
38
+ limit: SLACK_CHANNEL_MATCH_LIMIT
39
+ }
40
+ : undefined;
41
+ const [relevantChannelMessages, recentChannelMessages] = channelSearchScope
42
+ ? await Promise.all([
43
+ ctx.state.searchMessages({
44
+ ...channelSearchScope,
45
+ query: slackHistoryQuery(turn.message)
46
+ }),
47
+ ctx.state.searchMessages({
48
+ ...channelSearchScope,
49
+ limit: SLACK_CHANNEL_RECENT_LIMIT
50
+ })
51
+ ])
52
+ : [[], []];
53
+ const channelMatches = uniqueMessageMatches([...relevantChannelMessages, ...recentChannelMessages], SLACK_CHANNEL_MATCH_LIMIT);
54
+ const since = new Date(Date.now() - SLACK_RECENT_ACTIVITY_HOURS * 60 * 60 * 1000).toISOString();
55
+ const relatedConversations = turn.audience?.private !== false && surface !== "channel" && turn.userId && ctx.state.listRecentConversationsBySubject
56
+ ? await ctx.state.listRecentConversationsBySubject({
57
+ agentScope: ctx.agentScope,
58
+ channel: turn.channel,
59
+ subject: turn.principal ? principalKey(turn.principal) : turn.userId,
60
+ since,
61
+ limit: SLACK_RECENT_ACTIVITY_LIMIT,
62
+ excludeId: turn.conversationId
63
+ })
64
+ : [];
65
+ const related = await Promise.all(relatedConversations.map((conversation) => summarizeConversation(ctx, conversation)));
66
+ return {
67
+ recentHistory,
68
+ channelContext: compactJsonObject({
69
+ provider: "slack",
70
+ surface: stringValue(slack?.surface),
71
+ teamId: stringValue(slack?.teamId),
72
+ enterpriseId: stringValue(slack?.enterpriseId),
73
+ channelId: stringValue(slack?.channel),
74
+ threadTs: stringValue(slack?.threadTs),
75
+ currentConversation: {
76
+ id: turn.conversationId,
77
+ userId: turn.userId ?? null,
78
+ eventId: turn.eventId
79
+ },
80
+ threadDelta,
81
+ channelMatches: channelMatches.map((match) => historyContextMessage(match.message, match.conversationMetadata, match.score)),
82
+ relatedConversations: related,
83
+ contextPolicy: {
84
+ source: "assembly_line_state",
85
+ channelHistory: surface === "channel" ? "scoped_relevance_plus_recency" : "not_applicable",
86
+ hydration,
87
+ threadDeltaLimit: SLACK_THREAD_DELTA_LIMIT,
88
+ channelMatchLimit: SLACK_CHANNEL_MATCH_LIMIT,
89
+ maxRelatedConversations: SLACK_RECENT_ACTIVITY_LIMIT,
90
+ maxAgeHours: SLACK_RECENT_ACTIVITY_HOURS,
91
+ note: "Slack history stays in durable state; only unseen thread messages and bounded scoped search matches enter this turn."
92
+ }
93
+ })
94
+ };
95
+ }
96
+ async function hydrateSlackChannelHistory(turn, ctx, slack, turnSource) {
97
+ const conversation = await ctx.state.getConversation(turn.conversationId);
98
+ const priorHydration = recordValue(conversation?.metadata.slackContextHydration);
99
+ if (stringValue(priorHydration?.hydratedAt)) {
100
+ return compactJsonObject({ status: "cached", observed: numberValue(priorHydration?.observed) ?? 0 });
101
+ }
102
+ if (typeof ctx.agent?.observe !== "function")
103
+ return { status: "unavailable", observed: 0 };
104
+ const channelId = stringValue(turnSource?.channelId) ?? stringValue(slack?.channel);
105
+ const workspaceId = stringValue(turnSource?.workspaceId) ?? stringValue(slack?.enterpriseId) ?? stringValue(slack?.teamId);
106
+ const messageTs = stringValue(slack?.ts) ?? stringValue(recordValue(turn.delivery)?.ts);
107
+ const threadTs = stringValue(slack?.threadTs) ?? stringValue(recordValue(turn.delivery)?.threadTs);
108
+ if (!channelId || !workspaceId || !messageTs)
109
+ return { status: "unavailable", observed: 0 };
110
+ const threaded = Boolean(threadTs && threadTs !== messageTs);
111
+ const method = threaded ? "conversations.replies" : "conversations.history";
112
+ const request = threaded
113
+ ? { channel: channelId, ts: threadTs, limit: SLACK_HISTORY_HYDRATION_LIMIT }
114
+ : { channel: channelId, latest: messageTs, inclusive: true, limit: SLACK_HISTORY_HYDRATION_LIMIT };
115
+ try {
116
+ const result = await slackApi(ctx, method, request, stringValue(slack?.teamId));
117
+ const messages = Array.isArray(result.messages) ? result.messages.filter(isJsonObject) : [];
118
+ let observed = 0;
119
+ for (const message of messages) {
120
+ const observation = slackHistoryObservation(message, {
121
+ channelId,
122
+ workspaceId,
123
+ teamId: stringValue(slack?.teamId),
124
+ channelType: stringValue(slack?.channelType),
125
+ currentMessageTs: messageTs
126
+ });
127
+ if (!observation)
128
+ continue;
129
+ await ctx.agent.observe(observation);
130
+ observed += 1;
131
+ }
132
+ const hydratedAt = new Date().toISOString();
133
+ await ctx.state.updateConversation?.(turn.conversationId, {
134
+ metadata: {
135
+ slackContextHydration: { hydratedAt, method, observed }
136
+ }
137
+ });
138
+ return { status: "hydrated", method, observed };
139
+ }
140
+ catch (error) {
141
+ return {
142
+ status: "failed",
143
+ method,
144
+ observed: 0,
145
+ error: error instanceof Error ? truncate(error.message, SLACK_SUMMARY_MAX_CHARS) : "Slack history hydration failed."
146
+ };
147
+ }
148
+ }
149
+ function uniqueMessageMatches(matches, limit) {
150
+ const seen = new Set();
151
+ return matches.filter((match) => {
152
+ if (seen.has(match.message.id))
153
+ return false;
154
+ seen.add(match.message.id);
155
+ return true;
156
+ }).slice(0, limit);
157
+ }
158
+ async function summarizeConversation(ctx, conversation) {
159
+ const messages = await ctx.state.listRecentMessages(conversation.id, 8);
160
+ const latestUser = latestText(messages, "user");
161
+ const latestAssistant = latestText(messages, "assistant");
162
+ const slack = recordValue(conversation.metadata.slack);
163
+ return compactJsonObject({
164
+ conversationId: conversation.id,
165
+ updatedAt: conversation.updatedAt,
166
+ surface: stringValue(slack?.surface),
167
+ channelId: stringValue(slack?.channel),
168
+ threadTs: stringValue(slack?.threadTs),
169
+ latestUser,
170
+ latestAssistant
171
+ });
172
+ }
173
+ function latestText(messages, role) {
174
+ const message = [...messages].reverse().find((candidate) => candidate.role === role);
175
+ const text = typeof message?.content.text === "string" ? message.content.text : undefined;
176
+ return text ? truncate(text, SLACK_SUMMARY_MAX_CHARS) : undefined;
177
+ }
178
+ function messageHistoryLine(message) {
179
+ const text = typeof message.content.text === "string" ? message.content.text : JSON.stringify(message.content);
180
+ return `${message.role}: ${text}`;
181
+ }
182
+ function unseenObservedThreadMessages(messages) {
183
+ let latestAssistantIndex = -1;
184
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
185
+ if (messages[index]?.role === "assistant") {
186
+ latestAssistantIndex = index;
187
+ break;
188
+ }
189
+ }
190
+ return messages
191
+ .slice(latestAssistantIndex + 1)
192
+ .filter((message) => message.content.observed === true && message.content.deleted !== true)
193
+ .slice(-SLACK_THREAD_DELTA_LIMIT);
194
+ }
195
+ function historyContextMessage(message, conversationMetadata, score) {
196
+ const messageSource = recordValue(message.content.source);
197
+ const conversationSource = recordValue(conversationMetadata.source);
198
+ const source = messageSource ?? conversationSource;
199
+ return compactJsonObject({
200
+ messageId: message.id,
201
+ conversationId: message.conversationId,
202
+ role: message.role,
203
+ authorId: stringValue(source?.authorId),
204
+ text: truncate(stringValue(message.content.text) ?? "", SLACK_SUMMARY_MAX_CHARS),
205
+ createdAt: message.createdAt,
206
+ permalink: stringValue(source?.permalink),
207
+ score
208
+ });
209
+ }
210
+ function slackHistoryQuery(message) {
211
+ return message.replace(/<@[^>]+>/gu, " ").replace(/\s+/gu, " ").trim();
212
+ }
213
+ function compactJsonObject(input) {
214
+ const out = {};
215
+ for (const [key, value] of Object.entries(input)) {
216
+ if (value !== undefined)
217
+ out[key] = value;
218
+ }
219
+ return out;
220
+ }
221
+ function recordValue(value) {
222
+ return isJsonObject(value) ? value : undefined;
223
+ }
224
+ function isJsonObject(value) {
225
+ return typeof value === "object" && value !== null && !Array.isArray(value);
226
+ }
227
+ function stringValue(value) {
228
+ return typeof value === "string" && value.length > 0 ? value : undefined;
229
+ }
230
+ function numberValue(value) {
231
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
232
+ }
233
+ function truncate(value, max) {
234
+ return value.length <= max ? value : `${value.slice(0, max - 1)}…`;
235
+ }
236
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Preserve useful transport diagnostics hidden in nested fetch error causes. */
2
+ export declare function errorDetail(error: unknown): string;
3
+ //# sourceMappingURL=error-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-detail.d.ts","sourceRoot":"","sources":["../src/error-detail.ts"],"names":[],"mappings":"AAEA,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAwBlD"}
@@ -0,0 +1,27 @@
1
+ const MAX_ERROR_CAUSE_DEPTH = 5;
2
+ /** Preserve useful transport diagnostics hidden in nested fetch error causes. */
3
+ export function errorDetail(error) {
4
+ if (!(error instanceof Error))
5
+ return String(error);
6
+ const rootMessage = error.message;
7
+ const details = [];
8
+ const seen = new Set([error]);
9
+ let cause = error.cause;
10
+ let depth = 0;
11
+ while (cause instanceof Error && depth < MAX_ERROR_CAUSE_DEPTH && !seen.has(cause)) {
12
+ seen.add(cause);
13
+ const code = typeof cause.code === "string"
14
+ ? cause.code
15
+ : undefined;
16
+ const detail = [code, cause.message].filter(Boolean).join(": ");
17
+ const duplicatesParent = cause.message === rootMessage || rootMessage.endsWith(`: ${cause.message}`);
18
+ if (detail && (!duplicatesParent || code))
19
+ details.push(detail);
20
+ cause = cause.cause;
21
+ depth += 1;
22
+ }
23
+ return details.length > 0
24
+ ? `${rootMessage} (${details.join("; caused by ")})`
25
+ : rootMessage;
26
+ }
27
+ //# sourceMappingURL=error-detail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-detail.js","sourceRoot":"","sources":["../src/error-detail.ts"],"names":[],"mappings":"AAAA,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEhC,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IAEpD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;IAClC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACrC,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACxB,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,KAAK,YAAY,KAAK,IAAI,KAAK,GAAG,qBAAqB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACnF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChB,MAAM,IAAI,GAAG,OAAQ,KAAoC,CAAC,IAAI,KAAK,QAAQ;YACzE,CAAC,CAAE,KAAkC,CAAC,IAAI;YAC1C,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,KAAK,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrG,IAAI,MAAM,IAAI,CAAC,CAAC,gBAAgB,IAAI,IAAI,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACpB,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC;QACvB,CAAC,CAAC,GAAG,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG;QACpD,CAAC,CAAC,WAAW,CAAC;AAClB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  import { type ChannelDefinition, type JsonObject, type McpPluginConnectionOptions } from "@assemblyline-agents/core";
2
- import { type ChannelAttachmentRequest, type ChannelContext, type ChannelDelivery, type ChannelHttpRequest, type ChannelHttpResult, type ChannelTurn, type ChannelTurnLifecycle } from "@assemblyline-agents/runtime";
2
+ import { type ChannelAttachmentRequest, type ChannelContext, type ChannelDelivery, type ChannelHttpRequest, type ChannelHttpResult, type ChannelModule, type ChannelTurn, type ChannelTurnLifecycle } from "@assemblyline-agents/runtime";
3
+ export { slackSigningSecrets, slackWorkspaceCredentialMap, slackWorkspaceCredentials, type SlackWorkspaceCredentials } from "./workspace-credentials.js";
4
+ export { augmentContext } from "./context.js";
3
5
  export declare const SLACK_REQUIRED_ENV: readonly ["SLACK_SIGNING_SECRET", "SLACK_BOT_TOKEN"];
4
- export declare const SLACK_OPTIONAL_ENV: readonly ["SLACK_BOT_USER_ID", "SLACK_ASSISTANT_ENABLED"];
6
+ export declare const SLACK_OPTIONAL_ENV: readonly ["SLACK_BOT_USER_ID", "SLACK_ASSISTANT_ENABLED", "SLACK_WORKSPACE_CREDENTIALS_JSON"];
7
+ export declare const SLACK_REQUIRED_BOT_SCOPES: readonly ["app_mentions:read", "channels:history", "chat:write", "files:read", "files:write", "im:history"];
8
+ export declare const SLACK_OPTIONAL_BOT_SCOPES: readonly ["assistant:write", "groups:history"];
9
+ export declare const SLACK_DEFAULT_STATUS = "is working...";
10
+ export declare const SLACK_DEFAULT_LOADING_MESSAGES: readonly ["Beboppin'", "Boondoggling", "Cerebrating", "Combobulating", "Cooking", "Elucidating", "Flibbertigibbeting", "Hullaballooing", "Ionizing", "Photosynthesizing"];
5
11
  /** Production ingress-auth requirement (any-of groups): Slack request signing. */
6
12
  export declare const SLACK_INGRESS_SECRET_ENV: string[][];
7
13
  export type SlackConnectionOptions = McpPluginConnectionOptions;
@@ -13,14 +19,14 @@ export interface SlackChannelOptions {
13
19
  methods?: string[];
14
20
  connection?: string;
15
21
  metadata?: JsonObject;
22
+ /** Map the verified Slack sender to the application's canonical user. */
23
+ resolvePrincipal?: NonNullable<ChannelModule["resolvePrincipal"]>;
24
+ /** Override the default DM=principal, channel/thread=conversation trust boundary. */
25
+ isPrivateSurface?: NonNullable<ChannelModule["isPrivateSurface"]>;
16
26
  }
17
27
  export declare function defineSlackChannel(options?: SlackChannelOptions): ChannelDefinition;
18
28
  export declare function normalizeHttp(request: ChannelHttpRequest, ctx: ChannelContext): ChannelHttpResult;
19
29
  export declare function startTurn(turn: ChannelTurn, ctx: ChannelContext): Promise<ChannelTurnLifecycle | void>;
20
- export declare function augmentContext(turn: ChannelTurn, ctx: ChannelContext): Promise<{
21
- recentHistory?: string[];
22
- channelContext?: JsonObject;
23
- } | void>;
24
30
  export declare function send(delivery: ChannelDelivery, ctx: ChannelContext): Promise<JsonObject>;
25
31
  /**
26
32
  * Resolve a Slack turn attachment into an authorized download request: direct
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAoF,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAkB,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvN,OAAO,EAML,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EAG1B,MAAM,8BAA8B,CAAC;AAEtC,eAAO,MAAM,kBAAkB,sDAAuD,CAAC;AACvF,eAAO,MAAM,kBAAkB,2DAA4D,CAAC;AAC5F,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,EAAE,MAAM,EAAE,EAA+B,CAAC;AAG/E,MAAM,MAAM,sBAAsB,GAAG,0BAA0B,CAAC;AAChE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,yEAEpE;AACD,eAAO,MAAM,kBAAkB,kDAA2D,CAAC;AAE3F,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAUD,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,iBAAiB,CAqBvF;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,cAAc,GAAG,iBAAiB,CAoCjG;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAoB5G;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC;IAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,CAAC,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAAC,CAqC3E;AAED,wBAAsB,IAAI,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAoC9F;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAOlI;AA0KD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kBAAkB,EAC3B,aAAa,EAAE,MAAM,EACrB,UAAU,SAAgC,GACzC,OAAO,CAST"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAyG,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAkB,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAC5O,OAAO,EAML,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAElB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EAC1B,MAAM,8BAA8B,CAAC;AAetC,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACzJ,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,eAAO,MAAM,kBAAkB,sDAAuD,CAAC;AACvF,eAAO,MAAM,kBAAkB,+FAAgG,CAAC;AAChI,eAAO,MAAM,yBAAyB,6GAA8G,CAAC;AACrJ,eAAO,MAAM,yBAAyB,gDAAiD,CAAC;AACxF,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,8BAA8B,2KAWjC,CAAC;AACX,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,EAAE,MAAM,EAAE,EAA+B,CAAC;AAG/E,MAAM,MAAM,sBAAsB,GAAG,0BAA0B,CAAC;AAChE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,yEAEpE;AACD,eAAO,MAAM,kBAAkB,kDAA2D,CAAC;AAE3F,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAClE,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC;CACnE;AAiBD,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,iBAAiB,CA2BvF;AASD,wBAAgB,aAAa,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,cAAc,GAAG,iBAAiB,CAgDjG;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAsC5G;AAED,wBAAsB,IAAI,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAsD9F;AAgDD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAOlI;AA4ND,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kBAAkB,EAC3B,aAAa,EAAE,MAAM,EACrB,UAAU,SAAgC,GACzC,OAAO,CAST"}