@inkeep/agents-work-apps 0.48.7 → 0.50.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/github/index.d.ts +3 -3
- package/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/mcp/index.js +154 -2
- package/dist/github/mcp/schemas.d.ts +60 -2
- package/dist/github/mcp/schemas.js +20 -2
- package/dist/github/mcp/utils.d.ts +20 -2
- package/dist/github/mcp/utils.js +152 -30
- package/dist/github/routes/setup.d.ts +2 -2
- package/dist/github/routes/setup.js +1 -1
- package/dist/github/routes/tokenExchange.d.ts +2 -2
- package/dist/github/routes/webhooks.d.ts +2 -2
- package/dist/slack/i18n/strings.d.ts +1 -6
- package/dist/slack/i18n/strings.js +5 -10
- package/dist/slack/services/blocks/index.d.ts +1 -6
- package/dist/slack/services/blocks/index.js +2 -9
- package/dist/slack/services/commands/index.d.ts +1 -3
- package/dist/slack/services/commands/index.js +3 -190
- package/dist/slack/services/events/utils.d.ts +1 -1
- package/dist/slack/services/index.d.ts +3 -3
- package/dist/slack/services/index.js +3 -3
- package/package.json +2 -2
package/dist/github/index.d.ts
CHANGED
|
@@ -4,10 +4,10 @@ import "./routes/setup.js";
|
|
|
4
4
|
import "./routes/tokenExchange.js";
|
|
5
5
|
import { WebhookVerificationResult, verifyWebhookSignature } from "./routes/webhooks.js";
|
|
6
6
|
import { Hono } from "hono";
|
|
7
|
-
import * as
|
|
7
|
+
import * as hono_types0 from "hono/types";
|
|
8
8
|
|
|
9
9
|
//#region src/github/index.d.ts
|
|
10
|
-
declare function createGithubRoutes(): Hono<
|
|
11
|
-
declare const githubRoutes: Hono<
|
|
10
|
+
declare function createGithubRoutes(): Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
|
|
11
|
+
declare const githubRoutes: Hono<hono_types0.BlankEnv, hono_types0.BlankSchema, "/">;
|
|
12
12
|
//#endregion
|
|
13
13
|
export { GenerateInstallationAccessTokenResult, GenerateTokenError, GenerateTokenResult, GitHubAppConfig, InstallationAccessToken, InstallationInfo, LookupInstallationError, LookupInstallationForRepoResult, LookupInstallationResult, WebhookVerificationResult, clearConfigCache, createAppJwt, createGithubRoutes, determineStatus, fetchInstallationDetails, fetchInstallationRepositories, generateInstallationAccessToken, getGitHubAppConfig, getGitHubAppName, getStateSigningSecret, getWebhookSecret, githubRoutes, isGitHubAppConfigured, isGitHubAppNameConfigured, isStateSigningConfigured, isWebhookConfigured, lookupInstallationForRepo, validateGitHubAppConfigOnStartup, validateGitHubInstallFlowConfigOnStartup, validateGitHubWebhookConfigOnStartup, verifyWebhookSignature };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types7 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/mcp/index.d.ts
|
|
5
5
|
declare const app: Hono<{
|
|
6
6
|
Variables: {
|
|
7
7
|
toolId: string;
|
|
8
8
|
};
|
|
9
|
-
},
|
|
9
|
+
}, hono_types7.BlankSchema, "/">;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { app as default };
|
package/dist/github/mcp/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import runDbClient_default from "../../db/runDbClient.js";
|
|
2
2
|
import { githubMcpAuth } from "./auth.js";
|
|
3
|
-
import {
|
|
3
|
+
import { ReactionContentSchema } from "./schemas.js";
|
|
4
|
+
import { commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchComments, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, visualizeUpdateOperations } from "./utils.js";
|
|
5
|
+
import { z } from "@hono/zod-openapi";
|
|
4
6
|
import { getMcpToolRepositoryAccessWithDetails } from "@inkeep/agents-core";
|
|
5
7
|
import { Hono } from "hono";
|
|
6
8
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
9
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
8
10
|
import { toFetchResponse, toReqRes } from "fetch-to-node";
|
|
9
|
-
import { z } from "zod/v3";
|
|
10
11
|
|
|
11
12
|
//#region src/github/mcp/index.ts
|
|
12
13
|
const updateOperationSchema = z.object({
|
|
@@ -606,6 +607,157 @@ const getServer = async (toolId) => {
|
|
|
606
607
|
};
|
|
607
608
|
}
|
|
608
609
|
});
|
|
610
|
+
server.tool("add-comment-reaction", `Add a reaction to a comment on a pull request. Supports general pull request comments and inline PR review comments. ${getAvailableRepositoryString(repositoryAccess)}`, {
|
|
611
|
+
owner: z.string().describe("Repository owner name"),
|
|
612
|
+
repo: z.string().describe("Repository name"),
|
|
613
|
+
comment_id: z.number().describe("The ID of the comment to react to"),
|
|
614
|
+
comment_type: z.enum(["issue_comment", "review_comment"]).describe("The type of comment: \"issue_comment\" for general pull request comments, \"review_comment\" for inline PR review comments"),
|
|
615
|
+
reaction: ReactionContentSchema.describe("The reaction emoji to add: +1, -1, laugh, hooray, confused, heart, rocket, or eyes")
|
|
616
|
+
}, async ({ owner, repo, comment_id, comment_type, reaction }) => {
|
|
617
|
+
try {
|
|
618
|
+
let githubClient;
|
|
619
|
+
try {
|
|
620
|
+
githubClient = getGitHubClientFromRepo(owner, repo, installationIdMap);
|
|
621
|
+
} catch (error) {
|
|
622
|
+
return {
|
|
623
|
+
content: [{
|
|
624
|
+
type: "text",
|
|
625
|
+
text: `Error accessing GitHub: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
626
|
+
}],
|
|
627
|
+
isError: true
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
return { content: [{
|
|
631
|
+
type: "text",
|
|
632
|
+
text: `Successfully added ${reaction} reaction to ${comment_type} comment ${comment_id} in ${owner}/${repo}\n\nReaction ID: ${(comment_type === "issue_comment" ? await createIssueCommentReaction(githubClient, owner, repo, comment_id, reaction) : await createPullRequestReviewCommentReaction(githubClient, owner, repo, comment_id, reaction)).id}`
|
|
633
|
+
}] };
|
|
634
|
+
} catch (error) {
|
|
635
|
+
if (error instanceof Error && "status" in error) {
|
|
636
|
+
const apiError = error;
|
|
637
|
+
if (apiError.status === 404) return {
|
|
638
|
+
content: [{
|
|
639
|
+
type: "text",
|
|
640
|
+
text: `Comment ${comment_id} not found in ${owner}/${repo}.`
|
|
641
|
+
}],
|
|
642
|
+
isError: true
|
|
643
|
+
};
|
|
644
|
+
if (apiError.status === 422) return {
|
|
645
|
+
content: [{
|
|
646
|
+
type: "text",
|
|
647
|
+
text: `Invalid reaction. Ensure the reaction type is valid and the comment exists.`
|
|
648
|
+
}],
|
|
649
|
+
isError: true
|
|
650
|
+
};
|
|
651
|
+
if (apiError.status === 403) return {
|
|
652
|
+
content: [{
|
|
653
|
+
type: "text",
|
|
654
|
+
text: `Access denied when adding reaction to comment ${comment_id} in ${owner}/${repo}. Your GitHub App may not have sufficient permissions to create reactions.`
|
|
655
|
+
}],
|
|
656
|
+
isError: true
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
return {
|
|
660
|
+
content: [{
|
|
661
|
+
type: "text",
|
|
662
|
+
text: `Error adding reaction: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
663
|
+
}],
|
|
664
|
+
isError: true
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
});
|
|
668
|
+
server.tool("remove-comment-reaction", `Remove a reaction from a comment on a pull request. Requires the reaction ID (returned when adding a reaction or available from comment data). ${getAvailableRepositoryString(repositoryAccess)}`, {
|
|
669
|
+
owner: z.string().describe("Repository owner name"),
|
|
670
|
+
repo: z.string().describe("Repository name"),
|
|
671
|
+
comment_id: z.number().describe("The ID of the comment the reaction belongs to"),
|
|
672
|
+
comment_type: z.enum(["issue_comment", "review_comment"]).describe("The type of comment: \"issue_comment\" for general pull request comments, \"review_comment\" for inline PR review comments"),
|
|
673
|
+
reaction_id: z.number().describe("The ID of the reaction to remove")
|
|
674
|
+
}, async ({ owner, repo, comment_id, comment_type, reaction_id }) => {
|
|
675
|
+
try {
|
|
676
|
+
let githubClient;
|
|
677
|
+
try {
|
|
678
|
+
githubClient = getGitHubClientFromRepo(owner, repo, installationIdMap);
|
|
679
|
+
} catch (error) {
|
|
680
|
+
return {
|
|
681
|
+
content: [{
|
|
682
|
+
type: "text",
|
|
683
|
+
text: `Error accessing GitHub: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
684
|
+
}],
|
|
685
|
+
isError: true
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
if (comment_type === "issue_comment") await deleteIssueCommentReaction(githubClient, owner, repo, comment_id, reaction_id);
|
|
689
|
+
else await deletePullRequestReviewCommentReaction(githubClient, owner, repo, comment_id, reaction_id);
|
|
690
|
+
return { content: [{
|
|
691
|
+
type: "text",
|
|
692
|
+
text: `Successfully removed reaction ${reaction_id} from ${comment_type} comment ${comment_id} in ${owner}/${repo}`
|
|
693
|
+
}] };
|
|
694
|
+
} catch (error) {
|
|
695
|
+
if (error instanceof Error && "status" in error) {
|
|
696
|
+
if (error.status === 404) return {
|
|
697
|
+
content: [{
|
|
698
|
+
type: "text",
|
|
699
|
+
text: `Comment ${comment_id} or reaction ${reaction_id} not found in ${owner}/${repo}.`
|
|
700
|
+
}],
|
|
701
|
+
isError: true
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
return {
|
|
705
|
+
content: [{
|
|
706
|
+
type: "text",
|
|
707
|
+
text: `Error removing reaction: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
708
|
+
}],
|
|
709
|
+
isError: true
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
server.tool("list-comment-reactions", `List all reactions on a comment, including each reaction's ID (needed for removal). Supports both general issue/PR comments and inline PR review comments. ${getAvailableRepositoryString(repositoryAccess)}`, {
|
|
714
|
+
owner: z.string().describe("Repository owner name"),
|
|
715
|
+
repo: z.string().describe("Repository name"),
|
|
716
|
+
comment_id: z.number().describe("The ID of the comment to list reactions for"),
|
|
717
|
+
comment_type: z.enum(["issue_comment", "review_comment"]).describe("The type of comment: \"issue_comment\" for general pull request comments, \"review_comment\" for inline PR review comments")
|
|
718
|
+
}, async ({ owner, repo, comment_id, comment_type }) => {
|
|
719
|
+
try {
|
|
720
|
+
let githubClient;
|
|
721
|
+
try {
|
|
722
|
+
githubClient = getGitHubClientFromRepo(owner, repo, installationIdMap);
|
|
723
|
+
} catch (error) {
|
|
724
|
+
return {
|
|
725
|
+
content: [{
|
|
726
|
+
type: "text",
|
|
727
|
+
text: `Error accessing GitHub: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
728
|
+
}],
|
|
729
|
+
isError: true
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
const reactions = comment_type === "issue_comment" ? await listIssueCommentReactions(githubClient, owner, repo, comment_id) : await listPullRequestReviewCommentReactions(githubClient, owner, repo, comment_id);
|
|
733
|
+
if (reactions.length === 0) return { content: [{
|
|
734
|
+
type: "text",
|
|
735
|
+
text: `No reactions found on ${comment_type} comment ${comment_id} in ${owner}/${repo}.`
|
|
736
|
+
}] };
|
|
737
|
+
const formatted = reactions.map((r) => `• ${r.content} by @${r.user} (reaction_id: ${r.id})`).join("\n");
|
|
738
|
+
return { content: [{
|
|
739
|
+
type: "text",
|
|
740
|
+
text: `Found ${reactions.length} reaction(s) on ${comment_type} comment ${comment_id} in ${owner}/${repo}:\n\n${formatted}`
|
|
741
|
+
}] };
|
|
742
|
+
} catch (error) {
|
|
743
|
+
if (error instanceof Error && "status" in error) {
|
|
744
|
+
if (error.status === 404) return {
|
|
745
|
+
content: [{
|
|
746
|
+
type: "text",
|
|
747
|
+
text: `Comment ${comment_id} not found in ${owner}/${repo}.`
|
|
748
|
+
}],
|
|
749
|
+
isError: true
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
return {
|
|
753
|
+
content: [{
|
|
754
|
+
type: "text",
|
|
755
|
+
text: `Error listing reactions: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
756
|
+
}],
|
|
757
|
+
isError: true
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
});
|
|
609
761
|
server.tool("visualize-update-operations", `Apply a list of operations to a piece of documentation and return a mapping of line number to line content. ${getAvailableRepositoryString(repositoryAccess)}`, {
|
|
610
762
|
owner: z.string().describe("Repository owner name"),
|
|
611
763
|
repo: z.string().describe("Repository name"),
|
|
@@ -11,6 +11,46 @@ declare const RepositorySchema: z.ZodObject<{
|
|
|
11
11
|
url: z.ZodString;
|
|
12
12
|
defaultBranch: z.ZodString;
|
|
13
13
|
}, z.core.$strip>;
|
|
14
|
+
declare const ReactionContentSchema: z.ZodEnum<{
|
|
15
|
+
"+1": "+1";
|
|
16
|
+
[-1]: "-1";
|
|
17
|
+
laugh: "laugh";
|
|
18
|
+
hooray: "hooray";
|
|
19
|
+
confused: "confused";
|
|
20
|
+
heart: "heart";
|
|
21
|
+
rocket: "rocket";
|
|
22
|
+
eyes: "eyes";
|
|
23
|
+
}>;
|
|
24
|
+
declare const ReactionSchema: z.ZodObject<{
|
|
25
|
+
id: z.ZodNumber;
|
|
26
|
+
user: z.ZodString;
|
|
27
|
+
content: z.ZodEnum<{
|
|
28
|
+
"+1": "+1";
|
|
29
|
+
[-1]: "-1";
|
|
30
|
+
laugh: "laugh";
|
|
31
|
+
hooray: "hooray";
|
|
32
|
+
confused: "confused";
|
|
33
|
+
heart: "heart";
|
|
34
|
+
rocket: "rocket";
|
|
35
|
+
eyes: "eyes";
|
|
36
|
+
}>;
|
|
37
|
+
createdAt: z.ZodString;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
declare const ReactionsSchema: z.ZodArray<z.ZodObject<{
|
|
40
|
+
id: z.ZodNumber;
|
|
41
|
+
user: z.ZodString;
|
|
42
|
+
content: z.ZodEnum<{
|
|
43
|
+
"+1": "+1";
|
|
44
|
+
[-1]: "-1";
|
|
45
|
+
laugh: "laugh";
|
|
46
|
+
hooray: "hooray";
|
|
47
|
+
confused: "confused";
|
|
48
|
+
heart: "heart";
|
|
49
|
+
rocket: "rocket";
|
|
50
|
+
eyes: "eyes";
|
|
51
|
+
}>;
|
|
52
|
+
createdAt: z.ZodString;
|
|
53
|
+
}, z.core.$strip>>;
|
|
14
54
|
declare const PullRequestSchema: z.ZodObject<{
|
|
15
55
|
number: z.ZodNumber;
|
|
16
56
|
title: z.ZodString;
|
|
@@ -36,8 +76,8 @@ declare const ChangedFileSchema: z.ZodObject<{
|
|
|
36
76
|
path: z.ZodString;
|
|
37
77
|
status: z.ZodEnum<{
|
|
38
78
|
added: "added";
|
|
39
|
-
modified: "modified";
|
|
40
79
|
removed: "removed";
|
|
80
|
+
modified: "modified";
|
|
41
81
|
renamed: "renamed";
|
|
42
82
|
copied: "copied";
|
|
43
83
|
changed: "changed";
|
|
@@ -73,6 +113,21 @@ declare const CommentSchema: z.ZodObject<{
|
|
|
73
113
|
DISMISSED: "DISMISSED";
|
|
74
114
|
PENDING: "PENDING";
|
|
75
115
|
}>>;
|
|
116
|
+
reactions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
117
|
+
id: z.ZodNumber;
|
|
118
|
+
user: z.ZodString;
|
|
119
|
+
content: z.ZodEnum<{
|
|
120
|
+
"+1": "+1";
|
|
121
|
+
[-1]: "-1";
|
|
122
|
+
laugh: "laugh";
|
|
123
|
+
hooray: "hooray";
|
|
124
|
+
confused: "confused";
|
|
125
|
+
heart: "heart";
|
|
126
|
+
rocket: "rocket";
|
|
127
|
+
eyes: "eyes";
|
|
128
|
+
}>;
|
|
129
|
+
createdAt: z.ZodString;
|
|
130
|
+
}, z.core.$strip>>>;
|
|
76
131
|
}, z.core.$strip>;
|
|
77
132
|
declare const GitHubEventSchema: z.ZodObject<{
|
|
78
133
|
type: z.ZodString;
|
|
@@ -83,6 +138,9 @@ type Repository = z.infer<typeof RepositorySchema>;
|
|
|
83
138
|
type PullRequest = z.infer<typeof PullRequestSchema>;
|
|
84
139
|
type ChangedFile = z.infer<typeof ChangedFileSchema>;
|
|
85
140
|
type Comment = z.infer<typeof CommentSchema>;
|
|
141
|
+
type Reaction = z.infer<typeof ReactionSchema>;
|
|
142
|
+
type Reactions = z.infer<typeof ReactionsSchema>;
|
|
86
143
|
type GitHubEvent = z.infer<typeof GitHubEventSchema>;
|
|
144
|
+
type ReactionContent = z.infer<typeof ReactionContentSchema>;
|
|
87
145
|
//#endregion
|
|
88
|
-
export { ChangedFile, ChangedFileSchema, Comment, CommentSchema, GitHubEvent, GitHubEventSchema, GitHubUser, GitHubUserSchema, PullRequest, PullRequestSchema, Repository, RepositorySchema };
|
|
146
|
+
export { ChangedFile, ChangedFileSchema, Comment, CommentSchema, GitHubEvent, GitHubEventSchema, GitHubUser, GitHubUserSchema, PullRequest, PullRequestSchema, Reaction, ReactionContent, ReactionContentSchema, ReactionSchema, Reactions, ReactionsSchema, Repository, RepositorySchema };
|
|
@@ -9,6 +9,23 @@ const RepositorySchema = z.object({
|
|
|
9
9
|
url: z.string().url(),
|
|
10
10
|
defaultBranch: z.string()
|
|
11
11
|
});
|
|
12
|
+
const ReactionContentSchema = z.enum([
|
|
13
|
+
"+1",
|
|
14
|
+
"-1",
|
|
15
|
+
"laugh",
|
|
16
|
+
"hooray",
|
|
17
|
+
"confused",
|
|
18
|
+
"heart",
|
|
19
|
+
"rocket",
|
|
20
|
+
"eyes"
|
|
21
|
+
]);
|
|
22
|
+
const ReactionSchema = z.object({
|
|
23
|
+
id: z.number(),
|
|
24
|
+
user: z.string(),
|
|
25
|
+
content: ReactionContentSchema,
|
|
26
|
+
createdAt: z.string()
|
|
27
|
+
});
|
|
28
|
+
const ReactionsSchema = z.array(ReactionSchema);
|
|
12
29
|
const PullRequestSchema = z.object({
|
|
13
30
|
number: z.number(),
|
|
14
31
|
title: z.string(),
|
|
@@ -66,7 +83,8 @@ const CommentSchema = z.object({
|
|
|
66
83
|
"COMMENTED",
|
|
67
84
|
"DISMISSED",
|
|
68
85
|
"PENDING"
|
|
69
|
-
]).optional()
|
|
86
|
+
]).optional(),
|
|
87
|
+
reactions: ReactionsSchema.optional()
|
|
70
88
|
});
|
|
71
89
|
const GitHubEventSchema = z.object({
|
|
72
90
|
type: z.string(),
|
|
@@ -74,4 +92,4 @@ const GitHubEventSchema = z.object({
|
|
|
74
92
|
});
|
|
75
93
|
|
|
76
94
|
//#endregion
|
|
77
|
-
export { ChangedFileSchema, CommentSchema, GitHubEventSchema, GitHubUserSchema, PullRequestSchema, RepositorySchema };
|
|
95
|
+
export { ChangedFileSchema, CommentSchema, GitHubEventSchema, GitHubUserSchema, PullRequestSchema, ReactionContentSchema, ReactionSchema, ReactionsSchema, RepositorySchema };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChangedFile, Comment, PullRequest } from "./schemas.js";
|
|
1
|
+
import { ChangedFile, Comment, PullRequest, ReactionContent } from "./schemas.js";
|
|
2
2
|
import { Octokit } from "@octokit/rest";
|
|
3
3
|
|
|
4
4
|
//#region src/github/mcp/utils.d.ts
|
|
@@ -227,6 +227,24 @@ declare function commitNewFile({
|
|
|
227
227
|
content: string;
|
|
228
228
|
commitMessage: string;
|
|
229
229
|
}): Promise<string>;
|
|
230
|
+
declare function createIssueCommentReaction(octokit: Octokit, owner: string, repo: string, commentId: number, content: ReactionContent): Promise<{
|
|
231
|
+
id: number;
|
|
232
|
+
content: string;
|
|
233
|
+
}>;
|
|
234
|
+
declare function deleteIssueCommentReaction(octokit: Octokit, owner: string, repo: string, commentId: number, reactionId: number): Promise<void>;
|
|
235
|
+
declare function createPullRequestReviewCommentReaction(octokit: Octokit, owner: string, repo: string, commentId: number, content: ReactionContent): Promise<{
|
|
236
|
+
id: number;
|
|
237
|
+
content: string;
|
|
238
|
+
}>;
|
|
239
|
+
declare function deletePullRequestReviewCommentReaction(octokit: Octokit, owner: string, repo: string, commentId: number, reactionId: number): Promise<void>;
|
|
240
|
+
interface ReactionDetail {
|
|
241
|
+
id: number;
|
|
242
|
+
content: ReactionContent;
|
|
243
|
+
user: string;
|
|
244
|
+
createdAt: string;
|
|
245
|
+
}
|
|
246
|
+
declare function listIssueCommentReactions(octokit: Octokit, owner: string, repo: string, commentId: number): Promise<ReactionDetail[]>;
|
|
247
|
+
declare function listPullRequestReviewCommentReactions(octokit: Octokit, owner: string, repo: string, commentId: number): Promise<ReactionDetail[]>;
|
|
230
248
|
declare function formatFileDiff(pullRequestNumber: number, files: ChangedFile[], includeContents?: boolean): Promise<string>;
|
|
231
249
|
//#endregion
|
|
232
|
-
export { CommitData, LLMUpdateOperation, PullCommit, applyOperation, applyOperations, commitFileChanges, commitNewFile, fetchComments, fetchCommitDetails, fetchPrCommits, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getFilePathsInRepo, getGitHubClientFromInstallationId, getGitHubClientFromRepo, validateLineNumbers, visualizeUpdateOperations };
|
|
250
|
+
export { CommitData, LLMUpdateOperation, PullCommit, ReactionDetail, applyOperation, applyOperations, commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchComments, fetchCommitDetails, fetchPrCommits, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getFilePathsInRepo, getGitHubClientFromInstallationId, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, validateLineNumbers, visualizeUpdateOperations };
|
package/dist/github/mcp/utils.js
CHANGED
|
@@ -39,6 +39,42 @@ function mapUser(user) {
|
|
|
39
39
|
return { login: user.login };
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
+
* Fetch detailed reactions for an issue comment (with user attribution)
|
|
43
|
+
*/
|
|
44
|
+
async function fetchIssueCommentReactions(octokit, owner, repo, commentId) {
|
|
45
|
+
const reactions = [];
|
|
46
|
+
for await (const response of octokit.paginate.iterator(octokit.rest.reactions.listForIssueComment, {
|
|
47
|
+
owner,
|
|
48
|
+
repo,
|
|
49
|
+
comment_id: commentId,
|
|
50
|
+
per_page: 100
|
|
51
|
+
})) for (const reaction of response.data) reactions.push({
|
|
52
|
+
id: reaction.id,
|
|
53
|
+
user: reaction.user?.login ?? "[deleted]",
|
|
54
|
+
content: reaction.content,
|
|
55
|
+
createdAt: reaction.created_at
|
|
56
|
+
});
|
|
57
|
+
return reactions;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Fetch detailed reactions for a pull request review comment (with user attribution)
|
|
61
|
+
*/
|
|
62
|
+
async function fetchReviewCommentReactions(octokit, owner, repo, commentId) {
|
|
63
|
+
const reactions = [];
|
|
64
|
+
for await (const response of octokit.paginate.iterator(octokit.rest.reactions.listForPullRequestReviewComment, {
|
|
65
|
+
owner,
|
|
66
|
+
repo,
|
|
67
|
+
comment_id: commentId,
|
|
68
|
+
per_page: 100
|
|
69
|
+
})) for (const reaction of response.data) reactions.push({
|
|
70
|
+
id: reaction.id,
|
|
71
|
+
user: reaction.user?.login ?? "[deleted]",
|
|
72
|
+
content: reaction.content,
|
|
73
|
+
createdAt: reaction.created_at
|
|
74
|
+
});
|
|
75
|
+
return reactions;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
42
78
|
* Fetch pull request details
|
|
43
79
|
*/
|
|
44
80
|
async function fetchPrInfo(octokit, owner, repo, prNumber) {
|
|
@@ -241,6 +277,18 @@ async function fetchComments(octokit, owner, repo, prNumber) {
|
|
|
241
277
|
issue_number: prNumber,
|
|
242
278
|
per_page: 100
|
|
243
279
|
})) for (const comment of response.data) {
|
|
280
|
+
let reactions;
|
|
281
|
+
if (comment.reactions && comment.reactions.total_count > 0) try {
|
|
282
|
+
reactions = await fetchIssueCommentReactions(octokit, owner, repo, comment.id);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
logger.warn({
|
|
285
|
+
owner,
|
|
286
|
+
repo,
|
|
287
|
+
prNumber,
|
|
288
|
+
commentId: comment.id
|
|
289
|
+
}, `Failed to fetch issue comment reactions: ${error}`);
|
|
290
|
+
reactions = void 0;
|
|
291
|
+
}
|
|
244
292
|
if (!comment.user) continue;
|
|
245
293
|
results.push({
|
|
246
294
|
id: comment.id,
|
|
@@ -248,7 +296,8 @@ async function fetchComments(octokit, owner, repo, prNumber) {
|
|
|
248
296
|
author: mapUser(comment.user),
|
|
249
297
|
createdAt: comment.created_at,
|
|
250
298
|
updatedAt: comment.updated_at,
|
|
251
|
-
type: "issue"
|
|
299
|
+
type: "issue",
|
|
300
|
+
reactions
|
|
252
301
|
});
|
|
253
302
|
}
|
|
254
303
|
return results;
|
|
@@ -262,6 +311,18 @@ async function fetchComments(octokit, owner, repo, prNumber) {
|
|
|
262
311
|
per_page: 100
|
|
263
312
|
})) for (const comment of response.data) {
|
|
264
313
|
const isSuggestion = /```suggestion\b/.test(comment.body);
|
|
314
|
+
let reactions;
|
|
315
|
+
if (comment.reactions && comment.reactions.total_count > 0) try {
|
|
316
|
+
reactions = await fetchReviewCommentReactions(octokit, owner, repo, comment.id);
|
|
317
|
+
} catch (error) {
|
|
318
|
+
logger.warn({
|
|
319
|
+
owner,
|
|
320
|
+
repo,
|
|
321
|
+
prNumber,
|
|
322
|
+
commentId: comment.id
|
|
323
|
+
}, `Failed to fetch review comment reactions: ${error}`);
|
|
324
|
+
reactions = void 0;
|
|
325
|
+
}
|
|
265
326
|
results.push({
|
|
266
327
|
id: comment.id,
|
|
267
328
|
body: comment.body,
|
|
@@ -272,7 +333,8 @@ async function fetchComments(octokit, owner, repo, prNumber) {
|
|
|
272
333
|
path: comment.path,
|
|
273
334
|
line: comment.line || comment.original_line,
|
|
274
335
|
diffHunk: comment.diff_hunk,
|
|
275
|
-
isSuggestion
|
|
336
|
+
isSuggestion,
|
|
337
|
+
reactions
|
|
276
338
|
});
|
|
277
339
|
}
|
|
278
340
|
return results;
|
|
@@ -331,34 +393,24 @@ function generatePrMarkdown(pr, fileDiffs, comments, owner, repo) {
|
|
|
331
393
|
markdown += "</files>\n\n";
|
|
332
394
|
if (comments.length > 0) {
|
|
333
395
|
markdown += "<comments>\n";
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
markdown += `[
|
|
339
|
-
if (
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
markdown +=
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
const existing = commentsByFile.get(path) || [];
|
|
351
|
-
existing.push(comment);
|
|
352
|
-
commentsByFile.set(path, existing);
|
|
353
|
-
}
|
|
354
|
-
for (const [path, fileComments] of commentsByFile) {
|
|
355
|
-
markdown += `${path}:\n`;
|
|
356
|
-
for (const comment of fileComments) {
|
|
357
|
-
const lineInfo = comment.line ? ` line ${comment.line}` : "";
|
|
358
|
-
markdown += ` @${comment.author.login}${lineInfo} (${new Date(comment.createdAt).toLocaleDateString()})\n`;
|
|
359
|
-
markdown += ` ${comment.body}\n\n`;
|
|
360
|
-
}
|
|
396
|
+
const sorted = [...comments].sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
397
|
+
for (const comment of sorted) {
|
|
398
|
+
const date = new Date(comment.createdAt).toLocaleDateString();
|
|
399
|
+
const author = comment.author.login;
|
|
400
|
+
if (comment.type === "review_summary") markdown += `[review_summary] user:${author} comment_id:${comment.id} (${date})\n`;
|
|
401
|
+
else if (comment.type === "review") {
|
|
402
|
+
const lineInfo = comment.line ? `:${comment.line}` : "";
|
|
403
|
+
markdown += `[review_comment] user:${author} on ${comment.path}${lineInfo} comment_id:${comment.id} (${date})\n`;
|
|
404
|
+
} else markdown += `[issue_comment] user:${author} comment_id:${comment.id} (${date})\n`;
|
|
405
|
+
markdown += `${comment.body}\n`;
|
|
406
|
+
if (comment.reactions && comment.reactions.length > 0) {
|
|
407
|
+
const reactionCounts = /* @__PURE__ */ new Map();
|
|
408
|
+
for (const r of comment.reactions) reactionCounts.set(r.content, (reactionCounts.get(r.content) || 0) + 1);
|
|
409
|
+
const parts = [];
|
|
410
|
+
for (const [emoji, count] of reactionCounts) parts.push(count > 1 ? `${emoji} x${count}` : emoji);
|
|
411
|
+
markdown += `reactions: ${parts.join(", ")}\n`;
|
|
361
412
|
}
|
|
413
|
+
markdown += "\n";
|
|
362
414
|
}
|
|
363
415
|
markdown += "</comments>\n";
|
|
364
416
|
}
|
|
@@ -550,6 +602,76 @@ async function commitNewFile({ githubClient, owner, repo, filePath, branchName,
|
|
|
550
602
|
throw new Error(`Failed to commit new file: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
551
603
|
}
|
|
552
604
|
}
|
|
605
|
+
async function createIssueCommentReaction(octokit, owner, repo, commentId, content) {
|
|
606
|
+
const { data } = await octokit.rest.reactions.createForIssueComment({
|
|
607
|
+
owner,
|
|
608
|
+
repo,
|
|
609
|
+
comment_id: commentId,
|
|
610
|
+
content
|
|
611
|
+
});
|
|
612
|
+
return {
|
|
613
|
+
id: data.id,
|
|
614
|
+
content: data.content
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
async function deleteIssueCommentReaction(octokit, owner, repo, commentId, reactionId) {
|
|
618
|
+
await octokit.rest.reactions.deleteForIssueComment({
|
|
619
|
+
owner,
|
|
620
|
+
repo,
|
|
621
|
+
comment_id: commentId,
|
|
622
|
+
reaction_id: reactionId
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
async function createPullRequestReviewCommentReaction(octokit, owner, repo, commentId, content) {
|
|
626
|
+
const { data } = await octokit.rest.reactions.createForPullRequestReviewComment({
|
|
627
|
+
owner,
|
|
628
|
+
repo,
|
|
629
|
+
comment_id: commentId,
|
|
630
|
+
content
|
|
631
|
+
});
|
|
632
|
+
return {
|
|
633
|
+
id: data.id,
|
|
634
|
+
content: data.content
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
async function deletePullRequestReviewCommentReaction(octokit, owner, repo, commentId, reactionId) {
|
|
638
|
+
await octokit.rest.reactions.deleteForPullRequestComment({
|
|
639
|
+
owner,
|
|
640
|
+
repo,
|
|
641
|
+
comment_id: commentId,
|
|
642
|
+
reaction_id: reactionId
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
async function listIssueCommentReactions(octokit, owner, repo, commentId) {
|
|
646
|
+
const reactions = [];
|
|
647
|
+
for await (const response of octokit.paginate.iterator(octokit.rest.reactions.listForIssueComment, {
|
|
648
|
+
owner,
|
|
649
|
+
repo,
|
|
650
|
+
comment_id: commentId,
|
|
651
|
+
per_page: 100
|
|
652
|
+
})) for (const r of response.data) reactions.push({
|
|
653
|
+
id: r.id,
|
|
654
|
+
content: r.content,
|
|
655
|
+
user: r.user?.login ?? "unknown",
|
|
656
|
+
createdAt: r.created_at
|
|
657
|
+
});
|
|
658
|
+
return reactions;
|
|
659
|
+
}
|
|
660
|
+
async function listPullRequestReviewCommentReactions(octokit, owner, repo, commentId) {
|
|
661
|
+
const reactions = [];
|
|
662
|
+
for await (const response of octokit.paginate.iterator(octokit.rest.reactions.listForPullRequestReviewComment, {
|
|
663
|
+
owner,
|
|
664
|
+
repo,
|
|
665
|
+
comment_id: commentId,
|
|
666
|
+
per_page: 100
|
|
667
|
+
})) for (const r of response.data) reactions.push({
|
|
668
|
+
id: r.id,
|
|
669
|
+
content: r.content,
|
|
670
|
+
user: r.user?.login ?? "unknown",
|
|
671
|
+
createdAt: r.created_at
|
|
672
|
+
});
|
|
673
|
+
return reactions;
|
|
674
|
+
}
|
|
553
675
|
async function formatFileDiff(pullRequestNumber, files, includeContents = false) {
|
|
554
676
|
let output = `## File Patches for PR #${pullRequestNumber}\n\n`;
|
|
555
677
|
output += `Found ${files.length} file(s) matching the requested paths.\n\n`;
|
|
@@ -572,4 +694,4 @@ async function formatFileDiff(pullRequestNumber, files, includeContents = false)
|
|
|
572
694
|
}
|
|
573
695
|
|
|
574
696
|
//#endregion
|
|
575
|
-
export { applyOperation, applyOperations, commitFileChanges, commitNewFile, fetchComments, fetchCommitDetails, fetchPrCommits, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getFilePathsInRepo, getGitHubClientFromInstallationId, getGitHubClientFromRepo, validateLineNumbers, visualizeUpdateOperations };
|
|
697
|
+
export { applyOperation, applyOperations, commitFileChanges, commitNewFile, createIssueCommentReaction, createPullRequestReviewCommentReaction, deleteIssueCommentReaction, deletePullRequestReviewCommentReaction, fetchComments, fetchCommitDetails, fetchPrCommits, fetchPrFileDiffs, fetchPrFiles, fetchPrInfo, formatFileDiff, generatePrMarkdown, getFilePathsInRepo, getGitHubClientFromInstallationId, getGitHubClientFromRepo, listIssueCommentReactions, listPullRequestReviewCommentReactions, validateLineNumbers, visualizeUpdateOperations };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types3 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/setup.d.ts
|
|
5
|
-
declare const app: Hono<
|
|
5
|
+
declare const app: Hono<hono_types3.BlankEnv, hono_types3.BlankSchema, "/">;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { app as default };
|
|
@@ -5,8 +5,8 @@ import { getStateSigningSecret, isStateSigningConfigured } from "../config.js";
|
|
|
5
5
|
import { createAppJwt, determineStatus, fetchInstallationDetails, fetchInstallationRepositories } from "../installation.js";
|
|
6
6
|
import { createInstallation, generateId, getInstallationByGitHubId, listProjectsMetadata, setProjectAccessMode, syncRepositories, updateInstallationStatusByGitHubId } from "@inkeep/agents-core";
|
|
7
7
|
import { Hono } from "hono";
|
|
8
|
-
import { jwtVerify } from "jose";
|
|
9
8
|
import { z } from "zod";
|
|
9
|
+
import { jwtVerify } from "jose";
|
|
10
10
|
|
|
11
11
|
//#region src/github/routes/setup.ts
|
|
12
12
|
const logger = getLogger("github-setup");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types8 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/tokenExchange.d.ts
|
|
5
|
-
declare const app: Hono<
|
|
5
|
+
declare const app: Hono<hono_types8.BlankEnv, hono_types8.BlankSchema, "/">;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { app as default };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import * as
|
|
2
|
+
import * as hono_types5 from "hono/types";
|
|
3
3
|
|
|
4
4
|
//#region src/github/routes/webhooks.d.ts
|
|
5
5
|
interface WebhookVerificationResult {
|
|
@@ -7,6 +7,6 @@ interface WebhookVerificationResult {
|
|
|
7
7
|
error?: string;
|
|
8
8
|
}
|
|
9
9
|
declare function verifyWebhookSignature(payload: string, signature: string | undefined, secret: string): WebhookVerificationResult;
|
|
10
|
-
declare const app: Hono<
|
|
10
|
+
declare const app: Hono<hono_types5.BlankEnv, hono_types5.BlankSchema, "/">;
|
|
11
11
|
//#endregion
|
|
12
12
|
export { WebhookVerificationResult, app as default, verifyWebhookSignature };
|
|
@@ -57,12 +57,7 @@ declare const SlackStrings: {
|
|
|
57
57
|
readonly publicSection: string;
|
|
58
58
|
readonly privateSection: string;
|
|
59
59
|
readonly otherCommands: string;
|
|
60
|
-
|
|
61
|
-
readonly agentList: {
|
|
62
|
-
readonly title: "🤖 Available Agents";
|
|
63
|
-
readonly usage: "Usage:";
|
|
64
|
-
readonly runUsage: "`/inkeep run \"agent name\" question` - Run a specific agent";
|
|
65
|
-
readonly andMore: (count: number) => string;
|
|
60
|
+
readonly docsLink: "📖 <https://docs.inkeep.com/talk-to-your-agents/slack/overview|Learn more>";
|
|
66
61
|
};
|
|
67
62
|
readonly messageContext: {
|
|
68
63
|
readonly label: "Message:";
|
|
@@ -38,7 +38,7 @@ const SlackStrings = {
|
|
|
38
38
|
poweredBy: (agentName) => `Powered by *${agentName}* via Inkeep`,
|
|
39
39
|
privateResponse: "_Private response_"
|
|
40
40
|
},
|
|
41
|
-
usage: { mentionEmpty: "*To use your Inkeep agent, include a message:*\n\n• `@Inkeep <message>` — Send a message to
|
|
41
|
+
usage: { mentionEmpty: "*To use your Inkeep agent, include a message:*\n\n• `@Inkeep <message>` — Send a message to the default agent for the channel (reply appears in a thread)\n• `@Inkeep <message>` in a thread — Includes the thread as context for your agent\n• `@Inkeep` in a thread — Triggers your agent using the full thread as context\n\n💡 Use `/inkeep help` for all available commands." },
|
|
42
42
|
status: {
|
|
43
43
|
thinking: (agentName) => `_${agentName} is thinking..._`,
|
|
44
44
|
noAgentsAvailable: "No agents available",
|
|
@@ -50,15 +50,10 @@ const SlackStrings = {
|
|
|
50
50
|
},
|
|
51
51
|
help: {
|
|
52
52
|
title: "Inkeep — How to Use",
|
|
53
|
-
publicSection: "🔊 *Public* — everyone in the channel can see the response\n\n• `@Inkeep <message>` —
|
|
54
|
-
privateSection: "🔒 *Private* — only you can see the response\n\n• `/inkeep <message>` —
|
|
55
|
-
otherCommands: "⚙️ *Other Commands*\n\n• `/inkeep
|
|
56
|
-
|
|
57
|
-
agentList: {
|
|
58
|
-
title: "🤖 Available Agents",
|
|
59
|
-
usage: "Usage:",
|
|
60
|
-
runUsage: "`/inkeep run \"agent name\" question` - Run a specific agent",
|
|
61
|
-
andMore: (count) => `...and ${count} more`
|
|
53
|
+
publicSection: "🔊 *Public* — everyone in the channel can see the response\n\n• `@Inkeep <message>` — message the default agent in this channel\n• `@Inkeep <message>` in a thread — Includes thread as context\n• `@Inkeep` in a thread — Uses the full thread as context",
|
|
54
|
+
privateSection: "🔒 *Private* — only you can see the response\n\n• `/inkeep <message>` — message the default agent in this channel\n• `/inkeep` — Open the agent picker to choose an agent and write a prompt",
|
|
55
|
+
otherCommands: "⚙️ *Other Commands*\n\n• `/inkeep status` — Check your connection and agent config\n• `/inkeep link` / `/inkeep unlink` — Manage account connection\n• `/inkeep help` — Show this message",
|
|
56
|
+
docsLink: "📖 <https://docs.inkeep.com/talk-to-your-agents/slack/overview|Learn more>"
|
|
62
57
|
},
|
|
63
58
|
messageContext: { label: "Message:" }
|
|
64
59
|
};
|
|
@@ -43,11 +43,6 @@ declare function buildConversationResponseBlocks(params: {
|
|
|
43
43
|
isError: boolean;
|
|
44
44
|
followUpParams: FollowUpButtonParams;
|
|
45
45
|
}): any[];
|
|
46
|
-
declare function createAgentListMessage(agents: Array<{
|
|
47
|
-
id: string;
|
|
48
|
-
name: string | null;
|
|
49
|
-
projectName: string | null;
|
|
50
|
-
}>, dashboardUrl: string): Readonly<slack_block_builder0.SlackMessageDto>;
|
|
51
46
|
declare function createUpdatedHelpMessage(): Readonly<slack_block_builder0.SlackMessageDto>;
|
|
52
47
|
declare function createAlreadyLinkedMessage(email: string, linkedAt: string, dashboardUrl: string): Readonly<slack_block_builder0.SlackMessageDto>;
|
|
53
48
|
declare function createUnlinkSuccessMessage(): Readonly<slack_block_builder0.SlackMessageDto>;
|
|
@@ -70,4 +65,4 @@ interface AgentConfigSources {
|
|
|
70
65
|
declare function createStatusMessage(email: string, linkedAt: string, dashboardUrl: string, agentConfigs: AgentConfigSources): Readonly<slack_block_builder0.SlackMessageDto>;
|
|
71
66
|
declare function createJwtLinkMessage(linkUrl: string, expiresInMinutes: number): Readonly<slack_block_builder0.SlackMessageDto>;
|
|
72
67
|
//#endregion
|
|
73
|
-
export { AgentConfigSources, ContextBlockParams, FollowUpButtonParams, buildConversationResponseBlocks, buildFollowUpButton,
|
|
68
|
+
export { AgentConfigSources, ContextBlockParams, FollowUpButtonParams, buildConversationResponseBlocks, buildFollowUpButton, createAlreadyLinkedMessage, createContextBlock, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage };
|
|
@@ -65,15 +65,8 @@ function buildConversationResponseBlocks(params) {
|
|
|
65
65
|
}
|
|
66
66
|
return blocks;
|
|
67
67
|
}
|
|
68
|
-
function createAgentListMessage(agents, dashboardUrl) {
|
|
69
|
-
const agentList = agents.slice(0, 15).map((a) => `• ${Md.bold(a.name || a.id)} ${a.projectName ? `(${Md.italic(a.projectName)})` : ""}`).join("\n");
|
|
70
|
-
const moreText = agents.length > 15 ? `\n\n${SlackStrings.agentList.andMore(agents.length - 15)}` : "";
|
|
71
|
-
return Message().blocks(Blocks.Section().text(`${Md.bold(SlackStrings.agentList.title)}\n\n` + agentList + moreText + `
|
|
72
|
-
|
|
73
|
-
${Md.bold(SlackStrings.agentList.usage)}\n• ${SlackStrings.agentList.runUsage}`), Blocks.Actions().elements(Elements.Button().text(SlackStrings.buttons.openDashboard).url(dashboardUrl).actionId("view_agents"))).buildToObject();
|
|
74
|
-
}
|
|
75
68
|
function createUpdatedHelpMessage() {
|
|
76
|
-
return Message().blocks(Blocks.Section().text(`${Md.bold(SlackStrings.help.title)}`), Blocks.Section().text(SlackStrings.help.publicSection), Blocks.Divider(), Blocks.Section().text(SlackStrings.help.privateSection), Blocks.Divider(), Blocks.Section().text(SlackStrings.help.otherCommands)).buildToObject();
|
|
69
|
+
return Message().blocks(Blocks.Section().text(`${Md.bold(SlackStrings.help.title)}`), Blocks.Section().text(SlackStrings.help.publicSection), Blocks.Divider(), Blocks.Section().text(SlackStrings.help.privateSection), Blocks.Divider(), Blocks.Section().text(SlackStrings.help.otherCommands), Blocks.Divider(), Blocks.Section().text(SlackStrings.help.docsLink)).buildToObject();
|
|
77
70
|
}
|
|
78
71
|
function createAlreadyLinkedMessage(email, linkedAt, dashboardUrl) {
|
|
79
72
|
return Message().blocks(Blocks.Section().text(Md.bold("✅ Already Linked!") + "\n\nYour Slack account is already connected to Inkeep.\n\n" + Md.bold("Inkeep Account:") + ` ${email}\n` + Md.bold("Linked:") + ` ${new Date(linkedAt).toLocaleDateString()}\n\nTo switch accounts, first run \`/inkeep unlink\``), Blocks.Actions().elements(Elements.Button().text(SlackStrings.buttons.openDashboard).url(dashboardUrl).actionId("open_dashboard"))).buildToObject();
|
|
@@ -100,4 +93,4 @@ function createJwtLinkMessage(linkUrl, expiresInMinutes) {
|
|
|
100
93
|
}
|
|
101
94
|
|
|
102
95
|
//#endregion
|
|
103
|
-
export { buildConversationResponseBlocks, buildFollowUpButton,
|
|
96
|
+
export { buildConversationResponseBlocks, buildFollowUpButton, createAlreadyLinkedMessage, createContextBlock, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage };
|
|
@@ -12,8 +12,6 @@ declare function handleHelpCommand(): Promise<SlackCommandResponse>;
|
|
|
12
12
|
*/
|
|
13
13
|
declare function handleAgentPickerCommand(payload: SlackCommandPayload, tenantId: string, workspaceConnection?: SlackWorkspaceConnection | null): Promise<SlackCommandResponse>;
|
|
14
14
|
declare function handleQuestionCommand(payload: SlackCommandPayload, question: string, _dashboardUrl: string, tenantId: string): Promise<SlackCommandResponse>;
|
|
15
|
-
declare function handleRunCommand(payload: SlackCommandPayload, agentIdentifier: string, question: string, _dashboardUrl: string, tenantId: string): Promise<SlackCommandResponse>;
|
|
16
|
-
declare function handleAgentListCommand(payload: SlackCommandPayload, dashboardUrl: string, _tenantId: string): Promise<SlackCommandResponse>;
|
|
17
15
|
declare function handleCommand(payload: SlackCommandPayload): Promise<SlackCommandResponse>;
|
|
18
16
|
//#endregion
|
|
19
|
-
export {
|
|
17
|
+
export { handleAgentPickerCommand, handleCommand, handleHelpCommand, handleLinkCommand, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand };
|
|
@@ -4,115 +4,16 @@ import runDbClient_default from "../../../db/runDbClient.js";
|
|
|
4
4
|
import { findWorkspaceConnectionByTeamId } from "../nango.js";
|
|
5
5
|
import { resolveEffectiveAgent } from "../agent-resolution.js";
|
|
6
6
|
import { SlackStrings } from "../../i18n/strings.js";
|
|
7
|
-
import {
|
|
7
|
+
import { createAlreadyLinkedMessage, createContextBlock, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage } from "../blocks/index.js";
|
|
8
8
|
import { getSlackClient } from "../client.js";
|
|
9
9
|
import { fetchAgentsForProject, fetchProjectsForTenant, getChannelAgentConfig, sendResponseUrlMessage } from "../events/utils.js";
|
|
10
10
|
import { buildAgentSelectorModal } from "../modals.js";
|
|
11
11
|
import { deleteWorkAppSlackUserMapping, findWorkAppSlackUserMapping, findWorkAppSlackUserMappingBySlackUser, flushTraces, getWaitUntil, signSlackLinkToken, signSlackUserToken } from "@inkeep/agents-core";
|
|
12
12
|
|
|
13
13
|
//#region src/slack/services/commands/index.ts
|
|
14
|
-
/**
|
|
15
|
-
* Fetch all agents from the manage API.
|
|
16
|
-
* This uses the proper ref-middleware and Dolt branch resolution.
|
|
17
|
-
* Requires an auth token to access the manage API.
|
|
18
|
-
*/
|
|
19
|
-
const INTERNAL_FETCH_TIMEOUT_MS = 1e4;
|
|
20
|
-
async function fetchAgentsFromManageApi(tenantId, authToken) {
|
|
21
|
-
const apiBaseUrl = env.INKEEP_AGENTS_API_URL || "http://localhost:3002";
|
|
22
|
-
const controller = new AbortController();
|
|
23
|
-
const timeout = setTimeout(() => controller.abort(), INTERNAL_FETCH_TIMEOUT_MS);
|
|
24
|
-
try {
|
|
25
|
-
const projectsResponse = await fetch(`${apiBaseUrl}/manage/tenants/${tenantId}/projects`, {
|
|
26
|
-
method: "GET",
|
|
27
|
-
headers: {
|
|
28
|
-
"Content-Type": "application/json",
|
|
29
|
-
Authorization: `Bearer ${authToken}`
|
|
30
|
-
},
|
|
31
|
-
signal: controller.signal
|
|
32
|
-
});
|
|
33
|
-
if (!projectsResponse.ok) {
|
|
34
|
-
logger.error({
|
|
35
|
-
status: projectsResponse.status,
|
|
36
|
-
tenantId
|
|
37
|
-
}, "Failed to fetch projects from manage API");
|
|
38
|
-
return [];
|
|
39
|
-
}
|
|
40
|
-
const projectsData = await projectsResponse.json();
|
|
41
|
-
const projects = projectsData.data || projectsData || [];
|
|
42
|
-
logger.info({
|
|
43
|
-
projectCount: projects.length,
|
|
44
|
-
tenantId
|
|
45
|
-
}, "Fetched projects from manage API");
|
|
46
|
-
return (await Promise.all(projects.map(async (project) => {
|
|
47
|
-
try {
|
|
48
|
-
const agentsResponse = await fetch(`${apiBaseUrl}/manage/tenants/${tenantId}/projects/${project.id}/agents`, {
|
|
49
|
-
method: "GET",
|
|
50
|
-
headers: {
|
|
51
|
-
"Content-Type": "application/json",
|
|
52
|
-
Authorization: `Bearer ${authToken}`
|
|
53
|
-
},
|
|
54
|
-
signal: controller.signal
|
|
55
|
-
});
|
|
56
|
-
if (agentsResponse.ok) {
|
|
57
|
-
const agentsData = await agentsResponse.json();
|
|
58
|
-
return (agentsData.data || agentsData || []).map((agent) => ({
|
|
59
|
-
id: agent.id,
|
|
60
|
-
name: agent.name,
|
|
61
|
-
projectId: project.id,
|
|
62
|
-
projectName: project.name
|
|
63
|
-
}));
|
|
64
|
-
}
|
|
65
|
-
logger.warn({
|
|
66
|
-
status: agentsResponse.status,
|
|
67
|
-
projectId: project.id
|
|
68
|
-
}, "Failed to fetch agents for project");
|
|
69
|
-
return [];
|
|
70
|
-
} catch (error) {
|
|
71
|
-
logger.error({
|
|
72
|
-
error,
|
|
73
|
-
projectId: project.id
|
|
74
|
-
}, "Failed to fetch agents for project");
|
|
75
|
-
return [];
|
|
76
|
-
}
|
|
77
|
-
}))).flat();
|
|
78
|
-
} catch (error) {
|
|
79
|
-
logger.error({
|
|
80
|
-
error,
|
|
81
|
-
tenantId
|
|
82
|
-
}, "Failed to fetch agents from manage API");
|
|
83
|
-
return [];
|
|
84
|
-
} finally {
|
|
85
|
-
clearTimeout(timeout);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Find an agent by name or ID from the manage API.
|
|
90
|
-
*/
|
|
91
|
-
async function findAgentByIdentifier(tenantId, identifier, authToken) {
|
|
92
|
-
return (await fetchAgentsFromManageApi(tenantId, authToken)).find((a) => a.id === identifier || a.name?.toLowerCase() === identifier.toLowerCase()) || null;
|
|
93
|
-
}
|
|
94
14
|
const DEFAULT_CLIENT_ID = "work-apps-slack";
|
|
95
15
|
const LINK_CODE_TTL_MINUTES = 10;
|
|
96
16
|
const logger = getLogger("slack-commands");
|
|
97
|
-
/**
|
|
98
|
-
* Parse agent name and question from command text.
|
|
99
|
-
* Agent name must be in quotes: "agent name" question
|
|
100
|
-
*/
|
|
101
|
-
function parseAgentAndQuestion(text) {
|
|
102
|
-
if (!text.trim()) return {
|
|
103
|
-
agentName: null,
|
|
104
|
-
question: null
|
|
105
|
-
};
|
|
106
|
-
const quotedMatch = text.match(/^["']([^"']+)["']\s+(.+)$/);
|
|
107
|
-
if (quotedMatch) return {
|
|
108
|
-
agentName: quotedMatch[1].trim(),
|
|
109
|
-
question: quotedMatch[2].trim()
|
|
110
|
-
};
|
|
111
|
-
return {
|
|
112
|
-
agentName: null,
|
|
113
|
-
question: null
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
17
|
async function handleLinkCommand(payload, dashboardUrl, tenantId) {
|
|
117
18
|
const existingLink = await findWorkAppSlackUserMapping(runDbClient_default)(tenantId, payload.userId, payload.teamId, DEFAULT_CLIENT_ID);
|
|
118
19
|
if (existingLink) return {
|
|
@@ -325,7 +226,7 @@ async function handleQuestionCommand(payload, question, _dashboardUrl, tenantId)
|
|
|
325
226
|
});
|
|
326
227
|
if (!resolvedAgent) return {
|
|
327
228
|
response_type: "ephemeral",
|
|
328
|
-
...createErrorMessage("No default agent configured. Ask your admin to set a workspace default in the dashboard
|
|
229
|
+
...createErrorMessage("No default agent configured. Ask your admin to set a workspace default in the dashboard.")
|
|
329
230
|
};
|
|
330
231
|
const questionWork = executeAgentInBackground(payload, existingLink, {
|
|
331
232
|
id: resolvedAgent.agentId,
|
|
@@ -431,85 +332,6 @@ async function executeAgentInBackground(payload, existingLink, targetAgent, ques
|
|
|
431
332
|
});
|
|
432
333
|
}
|
|
433
334
|
}
|
|
434
|
-
async function handleRunCommand(payload, agentIdentifier, question, _dashboardUrl, tenantId) {
|
|
435
|
-
const existingLink = await findWorkAppSlackUserMappingBySlackUser(runDbClient_default)(payload.userId, payload.teamId, DEFAULT_CLIENT_ID);
|
|
436
|
-
if (!existingLink) return generateLinkCodeWithIntent(payload, tenantId);
|
|
437
|
-
const userTenantId = existingLink.tenantId;
|
|
438
|
-
try {
|
|
439
|
-
const targetAgent = await findAgentByIdentifier(userTenantId, agentIdentifier, await signSlackUserToken({
|
|
440
|
-
inkeepUserId: existingLink.inkeepUserId,
|
|
441
|
-
tenantId: userTenantId,
|
|
442
|
-
slackTeamId: payload.teamId,
|
|
443
|
-
slackUserId: payload.userId,
|
|
444
|
-
slackEnterpriseId: payload.enterpriseId
|
|
445
|
-
}));
|
|
446
|
-
if (!targetAgent) return {
|
|
447
|
-
response_type: "ephemeral",
|
|
448
|
-
...createErrorMessage(`Agent "${agentIdentifier}" not found. Use \`/inkeep list\` to see available agents.`)
|
|
449
|
-
};
|
|
450
|
-
const runWork = executeAgentInBackground(payload, existingLink, targetAgent, question, userTenantId).catch((error) => {
|
|
451
|
-
logger.error({ error }, "Background execution promise rejected");
|
|
452
|
-
}).finally(() => flushTraces());
|
|
453
|
-
const waitUntil = await getWaitUntil();
|
|
454
|
-
if (waitUntil) waitUntil(runWork);
|
|
455
|
-
return {};
|
|
456
|
-
} catch (error) {
|
|
457
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
458
|
-
logger.error({
|
|
459
|
-
error: errorMessage,
|
|
460
|
-
tenantId: userTenantId
|
|
461
|
-
}, "Failed to run agent");
|
|
462
|
-
return {
|
|
463
|
-
response_type: "ephemeral",
|
|
464
|
-
...createErrorMessage("Failed to run agent. Please try again or visit the dashboard.")
|
|
465
|
-
};
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
async function handleAgentListCommand(payload, dashboardUrl, _tenantId) {
|
|
469
|
-
const existingLink = await findWorkAppSlackUserMappingBySlackUser(runDbClient_default)(payload.userId, payload.teamId, DEFAULT_CLIENT_ID);
|
|
470
|
-
if (!existingLink) return {
|
|
471
|
-
response_type: "ephemeral",
|
|
472
|
-
...createNotLinkedMessage()
|
|
473
|
-
};
|
|
474
|
-
const userTenantId = existingLink.tenantId;
|
|
475
|
-
logger.info({
|
|
476
|
-
slackUserId: payload.userId,
|
|
477
|
-
existingLinkTenantId: existingLink.tenantId,
|
|
478
|
-
existingLinkInkeepUserId: existingLink.inkeepUserId
|
|
479
|
-
}, "Found user mapping for list command");
|
|
480
|
-
try {
|
|
481
|
-
const allAgents = await fetchAgentsFromManageApi(userTenantId, await signSlackUserToken({
|
|
482
|
-
inkeepUserId: existingLink.inkeepUserId,
|
|
483
|
-
tenantId: userTenantId,
|
|
484
|
-
slackTeamId: payload.teamId,
|
|
485
|
-
slackUserId: payload.userId,
|
|
486
|
-
slackEnterpriseId: payload.enterpriseId
|
|
487
|
-
}));
|
|
488
|
-
logger.info({
|
|
489
|
-
slackUserId: payload.userId,
|
|
490
|
-
tenantId: userTenantId,
|
|
491
|
-
agentCount: allAgents.length
|
|
492
|
-
}, "Listed agents for linked Slack user");
|
|
493
|
-
if (allAgents.length === 0) return {
|
|
494
|
-
response_type: "ephemeral",
|
|
495
|
-
...createErrorMessage("No agents found. Create an agent in the Inkeep dashboard first.")
|
|
496
|
-
};
|
|
497
|
-
return {
|
|
498
|
-
response_type: "ephemeral",
|
|
499
|
-
...createAgentListMessage(allAgents, dashboardUrl.replace("/work-apps/slack", ""))
|
|
500
|
-
};
|
|
501
|
-
} catch (error) {
|
|
502
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
503
|
-
logger.error({
|
|
504
|
-
error: errorMessage,
|
|
505
|
-
tenantId: userTenantId
|
|
506
|
-
}, "Failed to list agents");
|
|
507
|
-
return {
|
|
508
|
-
response_type: "ephemeral",
|
|
509
|
-
...createErrorMessage("Failed to list agents. Please try again or visit the dashboard.")
|
|
510
|
-
};
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
335
|
async function handleCommand(payload) {
|
|
514
336
|
const text = payload.text.trim();
|
|
515
337
|
const subcommand = text.split(/\s+/)[0]?.toLowerCase() || "";
|
|
@@ -538,15 +360,6 @@ async function handleCommand(payload) {
|
|
|
538
360
|
case "unlink":
|
|
539
361
|
case "logout":
|
|
540
362
|
case "disconnect": return handleUnlinkCommand(payload, tenantId);
|
|
541
|
-
case "list": return handleAgentListCommand(payload, dashboardUrl, tenantId);
|
|
542
|
-
case "run": {
|
|
543
|
-
const parsed = parseAgentAndQuestion(text.slice(4).trim());
|
|
544
|
-
if (!parsed.agentName || !parsed.question) return {
|
|
545
|
-
response_type: "ephemeral",
|
|
546
|
-
...createErrorMessage("Usage: `/inkeep run \"agent name\" [question]`\n\nExample: `/inkeep run \"my agent\" What is the weather?`\n\nAgent name must be in quotes.")
|
|
547
|
-
};
|
|
548
|
-
return handleRunCommand(payload, parsed.agentName, parsed.question, dashboardUrl, tenantId);
|
|
549
|
-
}
|
|
550
363
|
case "help": return handleHelpCommand();
|
|
551
364
|
case "": return handleAgentPickerCommand(payload, tenantId, workspaceConnection);
|
|
552
365
|
default: return handleQuestionCommand(payload, text, dashboardUrl, tenantId);
|
|
@@ -554,4 +367,4 @@ async function handleCommand(payload) {
|
|
|
554
367
|
}
|
|
555
368
|
|
|
556
369
|
//#endregion
|
|
557
|
-
export {
|
|
370
|
+
export { handleAgentPickerCommand, handleCommand, handleHelpCommand, handleLinkCommand, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand };
|
|
@@ -8,9 +8,9 @@ import { AgentOption } from "../modals.js";
|
|
|
8
8
|
* Called on every @mention and /inkeep command — caching avoids redundant DB queries.
|
|
9
9
|
*/
|
|
10
10
|
declare function findCachedUserMapping(tenantId: string, slackUserId: string, teamId: string, clientId?: string): Promise<{
|
|
11
|
+
id: string;
|
|
11
12
|
createdAt: string;
|
|
12
13
|
updatedAt: string;
|
|
13
|
-
id: string;
|
|
14
14
|
tenantId: string;
|
|
15
15
|
clientId: string;
|
|
16
16
|
slackUserId: string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AgentResolutionParams, ResolvedAgentConfig, getAgentConfigSources, resolveEffectiveAgent } from "./agent-resolution.js";
|
|
2
|
-
import { AgentConfigSources, ContextBlockParams, FollowUpButtonParams, buildConversationResponseBlocks, buildFollowUpButton,
|
|
2
|
+
import { AgentConfigSources, ContextBlockParams, FollowUpButtonParams, buildConversationResponseBlocks, buildFollowUpButton, createAlreadyLinkedMessage, createContextBlock, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage } from "./blocks/index.js";
|
|
3
3
|
import { checkUserIsChannelMember, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackTeamInfo, getSlackUserInfo, postMessage, postMessageInThread, revokeSlackToken } from "./client.js";
|
|
4
4
|
import { DefaultAgentConfig, SlackWorkspaceConnection, WorkspaceInstallData, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setWorkspaceDefaultAgent, storeWorkspaceInstallation, updateConnectionMetadata } from "./nango.js";
|
|
5
5
|
import { SlackCommandPayload, SlackCommandResponse } from "./types.js";
|
|
6
|
-
import {
|
|
6
|
+
import { handleAgentPickerCommand, handleCommand, handleHelpCommand, handleLinkCommand, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand } from "./commands/index.js";
|
|
7
7
|
import { InlineSelectorMetadata, handleAppMention } from "./events/app-mention.js";
|
|
8
8
|
import { handleMessageShortcut, handleOpenAgentSelectorModal, handleOpenFollowUpModal } from "./events/block-actions.js";
|
|
9
9
|
import { handleFollowUpSubmission, handleModalSubmission } from "./events/modal-submission.js";
|
|
@@ -13,4 +13,4 @@ import { StreamResult, streamAgentResponse } from "./events/streaming.js";
|
|
|
13
13
|
import "./events/index.js";
|
|
14
14
|
import { parseSlackCommandBody, parseSlackEventBody, verifySlackRequest } from "./security.js";
|
|
15
15
|
import { getBotTokenForTeam, setBotTokenForTeam } from "./workspace-tokens.js";
|
|
16
|
-
export { AgentConfigSources, AgentOption, AgentResolutionParams, BuildAgentSelectorModalParams, BuildMessageShortcutModalParams, ContextBlockParams, DefaultAgentConfig, FollowUpButtonParams, FollowUpModalMetadata, InlineSelectorMetadata, ModalMetadata, ResolvedAgentConfig, SlackCommandPayload, SlackCommandResponse, SlackErrorType, SlackWorkspaceConnection, StreamResult, WorkspaceInstallData, buildAgentSelectorModal, buildConversationResponseBlocks, buildFollowUpButton, buildFollowUpModal, buildMessageShortcutModal, checkIfBotThread, checkUserIsChannelMember, classifyError, clearWorkspaceConnectionCache, computeWorkspaceConnectionId,
|
|
16
|
+
export { AgentConfigSources, AgentOption, AgentResolutionParams, BuildAgentSelectorModalParams, BuildMessageShortcutModalParams, ContextBlockParams, DefaultAgentConfig, FollowUpButtonParams, FollowUpModalMetadata, InlineSelectorMetadata, ModalMetadata, ResolvedAgentConfig, SlackCommandPayload, SlackCommandResponse, SlackErrorType, SlackWorkspaceConnection, StreamResult, WorkspaceInstallData, buildAgentSelectorModal, buildConversationResponseBlocks, buildFollowUpButton, buildFollowUpModal, buildMessageShortcutModal, checkIfBotThread, checkUserIsChannelMember, classifyError, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createAlreadyLinkedMessage, createConnectSession, createContextBlock, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage, deleteWorkspaceInstallation, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, findWorkspaceConnectionByTeamId, generateSlackConversationId, getAgentConfigSources, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackIntegrationId, getSlackNango, getSlackTeamInfo, getSlackUserInfo, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, handleAgentPickerCommand, handleAppMention, handleCommand, handleFollowUpSubmission, handleHelpCommand, handleLinkCommand, handleMessageShortcut, handleModalSubmission, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand, listWorkspaceInstallations, markdownToMrkdwn, parseSlackCommandBody, parseSlackEventBody, postMessage, postMessageInThread, resolveEffectiveAgent, revokeSlackToken, sendResponseUrlMessage, setBotTokenForTeam, setWorkspaceDefaultAgent, storeWorkspaceInstallation, streamAgentResponse, updateConnectionMetadata, verifySlackRequest };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createConnectSession, deleteWorkspaceInstallation, findWorkspaceConnectionByTeamId, getConnectionAccessToken, getSlackIntegrationId, getSlackNango, getWorkspaceDefaultAgentFromNango, listWorkspaceInstallations, setWorkspaceDefaultAgent, storeWorkspaceInstallation, updateConnectionMetadata } from "./nango.js";
|
|
2
2
|
import { getAgentConfigSources, resolveEffectiveAgent } from "./agent-resolution.js";
|
|
3
|
-
import { buildConversationResponseBlocks, buildFollowUpButton,
|
|
3
|
+
import { buildConversationResponseBlocks, buildFollowUpButton, createAlreadyLinkedMessage, createContextBlock, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage } from "./blocks/index.js";
|
|
4
4
|
import { checkUserIsChannelMember, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackTeamInfo, getSlackUserInfo, postMessage, postMessageInThread, revokeSlackToken } from "./client.js";
|
|
5
5
|
import { SlackErrorType, checkIfBotThread, classifyError, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, generateSlackConversationId, getChannelAgentConfig, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, markdownToMrkdwn, sendResponseUrlMessage } from "./events/utils.js";
|
|
6
6
|
import { buildAgentSelectorModal, buildFollowUpModal, buildMessageShortcutModal } from "./modals.js";
|
|
7
|
-
import {
|
|
7
|
+
import { handleAgentPickerCommand, handleCommand, handleHelpCommand, handleLinkCommand, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand } from "./commands/index.js";
|
|
8
8
|
import { getBotTokenForTeam, setBotTokenForTeam } from "./workspace-tokens.js";
|
|
9
9
|
import { streamAgentResponse } from "./events/streaming.js";
|
|
10
10
|
import { handleAppMention } from "./events/app-mention.js";
|
|
@@ -13,4 +13,4 @@ import { handleFollowUpSubmission, handleModalSubmission } from "./events/modal-
|
|
|
13
13
|
import "./events/index.js";
|
|
14
14
|
import { parseSlackCommandBody, parseSlackEventBody, verifySlackRequest } from "./security.js";
|
|
15
15
|
|
|
16
|
-
export { SlackErrorType, buildAgentSelectorModal, buildConversationResponseBlocks, buildFollowUpButton, buildFollowUpModal, buildMessageShortcutModal, checkIfBotThread, checkUserIsChannelMember, classifyError, clearWorkspaceConnectionCache, computeWorkspaceConnectionId,
|
|
16
|
+
export { SlackErrorType, buildAgentSelectorModal, buildConversationResponseBlocks, buildFollowUpButton, buildFollowUpModal, buildMessageShortcutModal, checkIfBotThread, checkUserIsChannelMember, classifyError, clearWorkspaceConnectionCache, computeWorkspaceConnectionId, createAlreadyLinkedMessage, createConnectSession, createContextBlock, createErrorMessage, createJwtLinkMessage, createNotLinkedMessage, createStatusMessage, createUnlinkSuccessMessage, createUpdatedHelpMessage, deleteWorkspaceInstallation, fetchAgentsForProject, fetchProjectsForTenant, findCachedUserMapping, findWorkspaceConnectionByTeamId, generateSlackConversationId, getAgentConfigSources, getBotTokenForTeam, getChannelAgentConfig, getConnectionAccessToken, getSlackChannelInfo, getSlackChannels, getSlackClient, getSlackIntegrationId, getSlackNango, getSlackTeamInfo, getSlackUserInfo, getThreadContext, getUserFriendlyErrorMessage, getWorkspaceDefaultAgent, getWorkspaceDefaultAgentFromNango, handleAgentPickerCommand, handleAppMention, handleCommand, handleFollowUpSubmission, handleHelpCommand, handleLinkCommand, handleMessageShortcut, handleModalSubmission, handleOpenAgentSelectorModal, handleOpenFollowUpModal, handleQuestionCommand, handleStatusCommand, handleUnlinkCommand, listWorkspaceInstallations, markdownToMrkdwn, parseSlackCommandBody, parseSlackEventBody, postMessage, postMessageInThread, resolveEffectiveAgent, revokeSlackToken, sendResponseUrlMessage, setBotTokenForTeam, setWorkspaceDefaultAgent, storeWorkspaceInstallation, streamAgentResponse, updateConnectionMetadata, verifySlackRequest };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inkeep/agents-work-apps",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.0",
|
|
4
4
|
"description": "First party integrations for Inkeep Agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"jose": "^6.1.0",
|
|
34
34
|
"minimatch": "^10.1.1",
|
|
35
35
|
"slack-block-builder": "^2.8.0",
|
|
36
|
-
"@inkeep/agents-core": "0.
|
|
36
|
+
"@inkeep/agents-core": "0.50.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@hono/zod-openapi": "^1.1.5",
|