@inkeep/agents-work-apps 0.0.0-dev-20260204182014 → 0.0.0-dev-20260204210021

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/db/index.d.ts +1 -2
  2. package/dist/db/index.js +1 -2
  3. package/dist/db/runDbClient.d.ts +2 -2
  4. package/dist/env.d.ts +2 -24
  5. package/dist/env.js +1 -12
  6. package/dist/github/routes/setup.d.ts +2 -2
  7. package/dist/github/routes/tokenExchange.d.ts +2 -2
  8. package/package.json +2 -10
  9. package/dist/db/manageDbClient.d.ts +0 -7
  10. package/dist/db/manageDbClient.js +0 -16
  11. package/dist/slack/index.d.ts +0 -19
  12. package/dist/slack/index.js +0 -29
  13. package/dist/slack/middleware/permissions.d.ts +0 -16
  14. package/dist/slack/middleware/permissions.js +0 -49
  15. package/dist/slack/routes/events.d.ts +0 -10
  16. package/dist/slack/routes/events.js +0 -319
  17. package/dist/slack/routes/index.d.ts +0 -11
  18. package/dist/slack/routes/index.js +0 -64
  19. package/dist/slack/routes/internal.d.ts +0 -10
  20. package/dist/slack/routes/internal.js +0 -107
  21. package/dist/slack/routes/oauth.d.ts +0 -12
  22. package/dist/slack/routes/oauth.js +0 -218
  23. package/dist/slack/routes/resources.d.ts +0 -10
  24. package/dist/slack/routes/resources.js +0 -163
  25. package/dist/slack/routes/users.d.ts +0 -15
  26. package/dist/slack/routes/users.js +0 -430
  27. package/dist/slack/routes/workspaces.d.ts +0 -10
  28. package/dist/slack/routes/workspaces.js +0 -828
  29. package/dist/slack/routes.d.ts +0 -7
  30. package/dist/slack/routes.js +0 -12
  31. package/dist/slack/services/agent-resolution.d.ts +0 -49
  32. package/dist/slack/services/agent-resolution.js +0 -135
  33. package/dist/slack/services/api-client.d.ts +0 -161
  34. package/dist/slack/services/api-client.js +0 -248
  35. package/dist/slack/services/auth/index.d.ts +0 -61
  36. package/dist/slack/services/auth/index.js +0 -164
  37. package/dist/slack/services/blocks/index.d.ts +0 -60
  38. package/dist/slack/services/blocks/index.js +0 -143
  39. package/dist/slack/services/client.d.ts +0 -78
  40. package/dist/slack/services/client.js +0 -152
  41. package/dist/slack/services/commands/index.d.ts +0 -15
  42. package/dist/slack/services/commands/index.js +0 -556
  43. package/dist/slack/services/events/app-mention.d.ts +0 -41
  44. package/dist/slack/services/events/app-mention.js +0 -212
  45. package/dist/slack/services/events/block-actions.d.ts +0 -47
  46. package/dist/slack/services/events/block-actions.js +0 -287
  47. package/dist/slack/services/events/index.d.ts +0 -6
  48. package/dist/slack/services/events/index.js +0 -7
  49. package/dist/slack/services/events/modal-submission.d.ts +0 -12
  50. package/dist/slack/services/events/modal-submission.js +0 -279
  51. package/dist/slack/services/events/streaming.d.ts +0 -27
  52. package/dist/slack/services/events/streaming.js +0 -285
  53. package/dist/slack/services/events/utils.d.ts +0 -129
  54. package/dist/slack/services/events/utils.js +0 -315
  55. package/dist/slack/services/index.d.ts +0 -18
  56. package/dist/slack/services/index.js +0 -18
  57. package/dist/slack/services/modals.d.ts +0 -67
  58. package/dist/slack/services/modals.js +0 -203
  59. package/dist/slack/services/nango.d.ts +0 -82
  60. package/dist/slack/services/nango.js +0 -326
  61. package/dist/slack/services/security.d.ts +0 -35
  62. package/dist/slack/services/security.js +0 -65
  63. package/dist/slack/services/types.d.ts +0 -26
  64. package/dist/slack/services/types.js +0 -1
  65. package/dist/slack/services/workspace-tokens.d.ts +0 -37
  66. package/dist/slack/services/workspace-tokens.js +0 -39
  67. package/dist/slack/types.d.ts +0 -10
  68. package/dist/slack/types.js +0 -1
@@ -1,430 +0,0 @@
1
- import { getLogger } from "../../logger.js";
2
- import runDbClient_default from "../../db/runDbClient.js";
3
- import { createConnectSession } from "../services/nango.js";
4
- import "../services/index.js";
5
- import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
6
- import { createWorkAppSlackUserMapping, deleteWorkAppSlackUserMapping, findWorkAppSlackUserMapping, findWorkAppSlackUserMappingByInkeepUserId, findWorkAppSlackUserSettings, upsertWorkAppSlackUserSettings, verifySlackLinkToken } from "@inkeep/agents-core";
7
-
8
- //#region src/slack/routes/users.ts
9
- /**
10
- * Slack User Routes
11
- *
12
- * Endpoints for user linking and personal settings:
13
- * - GET /users/me/settings - Get user's personal settings
14
- * - PUT /users/me/settings - Update user's personal default agent
15
- * - GET /link-status - Check link status
16
- * - POST /link/verify-token - Verify JWT link token (primary linking method)
17
- * - POST /connect - Create Nango session
18
- * - POST /disconnect - Disconnect user
19
- */
20
- const logger = getLogger("slack-users");
21
- const app = new OpenAPIHono();
22
- const UserSettingsSchema = z.object({
23
- defaultProjectId: z.string().optional(),
24
- defaultAgentId: z.string().optional(),
25
- defaultAgentName: z.string().optional()
26
- });
27
- const pendingSessionTokens = /* @__PURE__ */ new Map();
28
- setInterval(() => {
29
- const now = Date.now();
30
- const maxAge = 600 * 1e3;
31
- for (const [key, value] of pendingSessionTokens.entries()) if (now - value.createdAt > maxAge) pendingSessionTokens.delete(key);
32
- }, 60 * 1e3);
33
- app.openapi(createRoute({
34
- method: "get",
35
- path: "/me/settings",
36
- summary: "Get User Settings",
37
- description: "Get user's personal Slack settings including default agent",
38
- operationId: "slack-get-user-settings",
39
- tags: [
40
- "Work Apps",
41
- "Slack",
42
- "Users"
43
- ],
44
- request: { query: z.object({
45
- slackUserId: z.string(),
46
- slackTeamId: z.string(),
47
- tenantId: z.string().optional().default("default")
48
- }) },
49
- responses: { 200: {
50
- description: "User settings",
51
- content: { "application/json": { schema: UserSettingsSchema } }
52
- } }
53
- }), async (c) => {
54
- const { slackUserId, slackTeamId, tenantId } = c.req.valid("query");
55
- const settings = await findWorkAppSlackUserSettings(runDbClient_default)(tenantId, slackTeamId, slackUserId);
56
- return c.json({
57
- defaultProjectId: settings?.defaultProjectId || void 0,
58
- defaultAgentId: settings?.defaultAgentId || void 0,
59
- defaultAgentName: settings?.defaultAgentName || void 0
60
- });
61
- });
62
- app.openapi(createRoute({
63
- method: "put",
64
- path: "/me/settings",
65
- summary: "Update User Settings",
66
- description: "Update user's personal default agent",
67
- operationId: "slack-update-user-settings",
68
- tags: [
69
- "Work Apps",
70
- "Slack",
71
- "Users"
72
- ],
73
- request: { body: { content: { "application/json": { schema: z.object({
74
- slackUserId: z.string(),
75
- slackTeamId: z.string(),
76
- tenantId: z.string().optional(),
77
- settings: UserSettingsSchema
78
- }) } } } },
79
- responses: { 200: {
80
- description: "Settings updated",
81
- content: { "application/json": { schema: z.object({ success: z.boolean() }) } }
82
- } }
83
- }), async (c) => {
84
- const body = c.req.valid("json");
85
- const tenantId = body.tenantId || "default";
86
- await upsertWorkAppSlackUserSettings(runDbClient_default)({
87
- tenantId,
88
- slackTeamId: body.slackTeamId,
89
- slackUserId: body.slackUserId,
90
- defaultProjectId: body.settings.defaultProjectId,
91
- defaultAgentId: body.settings.defaultAgentId,
92
- defaultAgentName: body.settings.defaultAgentName
93
- });
94
- logger.info({
95
- slackUserId: body.slackUserId,
96
- agentId: body.settings.defaultAgentId
97
- }, "Updated user settings");
98
- return c.json({ success: true });
99
- });
100
- app.openapi(createRoute({
101
- method: "get",
102
- path: "/link-status",
103
- summary: "Check Link Status",
104
- description: "Check if a Slack user is linked to an Inkeep account",
105
- operationId: "slack-link-status",
106
- tags: [
107
- "Work Apps",
108
- "Slack",
109
- "Users"
110
- ],
111
- request: { query: z.object({
112
- slackUserId: z.string(),
113
- slackTeamId: z.string(),
114
- tenantId: z.string().optional().default("default")
115
- }) },
116
- responses: { 200: {
117
- description: "Link status",
118
- content: { "application/json": { schema: z.object({
119
- linked: z.boolean(),
120
- linkId: z.string().optional(),
121
- linkedAt: z.string().optional(),
122
- slackUsername: z.string().optional()
123
- }) } }
124
- } }
125
- }), async (c) => {
126
- const { slackUserId, slackTeamId, tenantId } = c.req.valid("query");
127
- const link = await findWorkAppSlackUserMapping(runDbClient_default)(tenantId, slackUserId, slackTeamId, "work-apps-slack");
128
- if (link) return c.json({
129
- linked: true,
130
- linkId: link.id,
131
- linkedAt: link.linkedAt,
132
- slackUsername: link.slackUsername || void 0
133
- });
134
- return c.json({ linked: false });
135
- });
136
- app.openapi(createRoute({
137
- method: "post",
138
- path: "/link/verify-token",
139
- summary: "Verify Link Token",
140
- description: "Verify a JWT link token and create user mapping",
141
- operationId: "slack-verify-link-token",
142
- tags: [
143
- "Work Apps",
144
- "Slack",
145
- "Users"
146
- ],
147
- request: { body: { content: { "application/json": { schema: z.object({
148
- token: z.string().min(1),
149
- userId: z.string().min(1),
150
- userEmail: z.string().email().optional()
151
- }) } } } },
152
- responses: {
153
- 200: {
154
- description: "Link successful",
155
- content: { "application/json": { schema: z.object({
156
- success: z.boolean(),
157
- linkId: z.string().optional(),
158
- slackUsername: z.string().optional(),
159
- slackTeamId: z.string().optional(),
160
- tenantId: z.string().optional()
161
- }) } }
162
- },
163
- 400: { description: "Invalid or expired token" },
164
- 409: { description: "Account already linked" }
165
- }
166
- }), async (c) => {
167
- const body = c.req.valid("json");
168
- try {
169
- const verifyResult = await verifySlackLinkToken(body.token);
170
- if (!verifyResult.valid || !verifyResult.payload) {
171
- logger.warn({ error: verifyResult.error }, "Invalid link token");
172
- return c.json({ error: verifyResult.error || "Invalid or expired link token. Please run /inkeep link in Slack to get a new one." }, 400);
173
- }
174
- const { tenantId, slack } = verifyResult.payload;
175
- const { teamId, userId: slackUserId, enterpriseId, username } = slack;
176
- const existingLink = await findWorkAppSlackUserMapping(runDbClient_default)(tenantId, slackUserId, teamId, "work-apps-slack");
177
- if (existingLink && existingLink.inkeepUserId === body.userId) {
178
- logger.info({
179
- slackUserId,
180
- tenantId,
181
- inkeepUserId: body.userId
182
- }, "Slack user already linked to same account");
183
- return c.json({
184
- success: true,
185
- linkId: existingLink.id,
186
- slackUsername: existingLink.slackUsername || void 0,
187
- slackTeamId: teamId,
188
- tenantId
189
- });
190
- }
191
- if (existingLink) logger.info({
192
- slackUserId,
193
- existingUserId: existingLink.inkeepUserId,
194
- newUserId: body.userId,
195
- tenantId
196
- }, "Slack user already linked, updating to new user");
197
- const slackUserMapping = await createWorkAppSlackUserMapping(runDbClient_default)({
198
- tenantId,
199
- clientId: "work-apps-slack",
200
- slackUserId,
201
- slackTeamId: teamId,
202
- slackEnterpriseId: enterpriseId,
203
- slackUsername: username,
204
- slackEmail: body.userEmail,
205
- inkeepUserId: body.userId
206
- });
207
- logger.info({
208
- slackUserId,
209
- slackTeamId: teamId,
210
- tenantId,
211
- inkeepUserId: body.userId,
212
- linkId: slackUserMapping.id
213
- }, "Successfully linked Slack user to Inkeep account via JWT token");
214
- return c.json({
215
- success: true,
216
- linkId: slackUserMapping.id,
217
- slackUsername: username || void 0,
218
- slackTeamId: teamId,
219
- tenantId
220
- });
221
- } catch (error) {
222
- const errorMessage = error instanceof Error ? error.message : String(error);
223
- if (errorMessage.includes("duplicate key") || errorMessage.includes("unique constraint")) {
224
- logger.warn({ userId: body.userId }, "Slack user already linked");
225
- return c.json({ error: "This Slack account is already linked to an Inkeep account." }, 409);
226
- }
227
- logger.error({
228
- error,
229
- userId: body.userId
230
- }, "Failed to verify link token");
231
- return c.json({ error: "Failed to verify link. Please try again." }, 500);
232
- }
233
- });
234
- app.openapi(createRoute({
235
- method: "post",
236
- path: "/connect",
237
- summary: "Create Nango Connect Session",
238
- description: "Create a Nango session for Slack OAuth flow. Used by the dashboard.",
239
- operationId: "slack-user-connect",
240
- tags: [
241
- "Work Apps",
242
- "Slack",
243
- "Users"
244
- ],
245
- request: { body: { content: { "application/json": { schema: z.object({
246
- userId: z.string().describe("Inkeep user ID"),
247
- userEmail: z.string().optional().describe("User email"),
248
- userName: z.string().optional().describe("User display name"),
249
- tenantId: z.string().optional().describe("Tenant ID"),
250
- sessionToken: z.string().optional().describe("Pre-authenticated session token"),
251
- sessionExpiresAt: z.string().optional().describe("Session expiration ISO timestamp")
252
- }) } } } },
253
- responses: {
254
- 200: {
255
- description: "Connect session created",
256
- content: { "application/json": { schema: z.object({
257
- sessionToken: z.string().optional(),
258
- connectUrl: z.string().optional()
259
- }) } }
260
- },
261
- 400: { description: "Missing required userId" },
262
- 500: { description: "Failed to create session" }
263
- }
264
- }), async (c) => {
265
- const { userId, userEmail, userName, tenantId, sessionToken, sessionExpiresAt } = c.req.valid("json");
266
- if (!userId) return c.json({ error: "userId is required" }, 400);
267
- if (sessionToken && sessionExpiresAt) {
268
- pendingSessionTokens.set(userId, {
269
- token: sessionToken,
270
- expiresAt: sessionExpiresAt,
271
- createdAt: Date.now()
272
- });
273
- logger.info({ userId }, "Stored pending session token for Slack connection");
274
- }
275
- logger.debug({
276
- userId,
277
- userEmail,
278
- userName,
279
- hasSessionToken: !!sessionToken
280
- }, "Creating Nango connect session");
281
- const session = await createConnectSession({
282
- userId,
283
- userEmail,
284
- userName,
285
- tenantId: tenantId || "default"
286
- });
287
- if (!session) return c.json({ error: "Failed to create session" }, 500);
288
- return c.json(session);
289
- });
290
- app.openapi(createRoute({
291
- method: "post",
292
- path: "/disconnect",
293
- summary: "Disconnect User",
294
- description: "Unlink a Slack user from their Inkeep account.",
295
- operationId: "slack-user-disconnect",
296
- tags: [
297
- "Work Apps",
298
- "Slack",
299
- "Users"
300
- ],
301
- request: { body: { content: { "application/json": { schema: z.object({
302
- userId: z.string().optional().describe("Inkeep user ID"),
303
- slackUserId: z.string().optional().describe("Slack user ID"),
304
- slackTeamId: z.string().optional().describe("Slack team ID"),
305
- tenantId: z.string().optional().describe("Tenant ID")
306
- }) } } } },
307
- responses: {
308
- 200: {
309
- description: "User disconnected",
310
- content: { "application/json": { schema: z.object({ success: z.boolean() }) } }
311
- },
312
- 400: { description: "Missing required identifiers" },
313
- 404: { description: "No connection found" },
314
- 500: { description: "Failed to disconnect" }
315
- }
316
- }), async (c) => {
317
- const { userId, slackUserId, slackTeamId, tenantId } = c.req.valid("json");
318
- if (!userId && !(slackUserId && slackTeamId)) return c.json({ error: "Either userId or (slackUserId + slackTeamId) is required" }, 400);
319
- try {
320
- const effectiveTenantId = tenantId || "default";
321
- if (slackUserId && slackTeamId) {
322
- if (await deleteWorkAppSlackUserMapping(runDbClient_default)(effectiveTenantId, slackUserId, slackTeamId, "work-apps-slack")) {
323
- logger.info({
324
- slackUserId,
325
- slackTeamId,
326
- tenantId: effectiveTenantId
327
- }, "User unlinked");
328
- return c.json({ success: true });
329
- }
330
- return c.json({ error: "No link found for this user" }, 404);
331
- }
332
- if (userId) {
333
- const userMappings = await findWorkAppSlackUserMappingByInkeepUserId(runDbClient_default)(userId);
334
- if (userMappings.length === 0) return c.json({ error: "No link found for this user" }, 404);
335
- let deletedCount = 0;
336
- for (const mapping of userMappings) if (await deleteWorkAppSlackUserMapping(runDbClient_default)(mapping.tenantId, mapping.slackUserId, mapping.slackTeamId, "work-apps-slack")) deletedCount++;
337
- logger.info({
338
- userId,
339
- deletedCount
340
- }, "User disconnected from Slack");
341
- return c.json({ success: true });
342
- }
343
- return c.json({ error: "No connection found for this user" }, 404);
344
- } catch (error) {
345
- logger.error({
346
- error,
347
- userId,
348
- slackUserId,
349
- slackTeamId
350
- }, "Failed to disconnect from Slack");
351
- return c.json({ error: "Failed to disconnect" }, 500);
352
- }
353
- });
354
- app.openapi(createRoute({
355
- method: "get",
356
- path: "/status",
357
- summary: "Get Connection Status",
358
- description: "Check if an Inkeep user has a linked Slack account.",
359
- operationId: "slack-user-status",
360
- tags: [
361
- "Work Apps",
362
- "Slack",
363
- "Users"
364
- ],
365
- request: { query: z.object({ userId: z.string().describe("Inkeep user ID") }) },
366
- responses: {
367
- 200: {
368
- description: "Connection status",
369
- content: { "application/json": { schema: z.object({
370
- connected: z.boolean(),
371
- connection: z.object({
372
- connectionId: z.string(),
373
- appUserId: z.string(),
374
- appUserEmail: z.string(),
375
- slackDisplayName: z.string(),
376
- linkedAt: z.string(),
377
- tenantId: z.string(),
378
- slackUserId: z.string(),
379
- slackTeamId: z.string()
380
- }).nullable()
381
- }) } }
382
- },
383
- 400: { description: "Missing userId" },
384
- 500: { description: "Failed to get status" }
385
- }
386
- }), async (c) => {
387
- const { userId: appUserId } = c.req.valid("query");
388
- try {
389
- const userMappings = await findWorkAppSlackUserMappingByInkeepUserId(runDbClient_default)(appUserId);
390
- if (userMappings.length === 0) {
391
- logger.debug({
392
- appUserId,
393
- connected: false
394
- }, "Retrieved connection status from DB");
395
- return c.json({
396
- connected: false,
397
- connection: null
398
- });
399
- }
400
- const mostRecent = userMappings.sort((a, b) => new Date(b.linkedAt).getTime() - new Date(a.linkedAt).getTime())[0];
401
- const connection = {
402
- connectionId: mostRecent.id,
403
- appUserId: mostRecent.inkeepUserId,
404
- appUserEmail: mostRecent.slackEmail || "",
405
- slackDisplayName: mostRecent.slackUsername || "",
406
- linkedAt: mostRecent.linkedAt,
407
- tenantId: mostRecent.tenantId,
408
- slackUserId: mostRecent.slackUserId,
409
- slackTeamId: mostRecent.slackTeamId
410
- };
411
- logger.debug({
412
- appUserId,
413
- connected: true
414
- }, "Retrieved connection status from DB");
415
- return c.json({
416
- connected: true,
417
- connection
418
- });
419
- } catch (error) {
420
- logger.error({
421
- error,
422
- appUserId
423
- }, "Failed to get connection status");
424
- return c.json({ error: "Failed to get connection status" }, 500);
425
- }
426
- });
427
- var users_default = app;
428
-
429
- //#endregion
430
- export { users_default as default, pendingSessionTokens };
@@ -1,10 +0,0 @@
1
- import { ManageAppVariables } from "../types.js";
2
- import { OpenAPIHono } from "@hono/zod-openapi";
3
-
4
- //#region src/slack/routes/workspaces.d.ts
5
-
6
- declare const app: OpenAPIHono<{
7
- Variables: ManageAppVariables;
8
- }, {}, "/">;
9
- //#endregion
10
- export { app as default };