@inkeep/agents-work-apps 0.49.0 → 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/auth.d.ts +2 -2
- package/dist/github/mcp/index.d.ts +2 -2
- package/dist/github/mcp/index.js +154 -2
- package/dist/github/mcp/schemas.d.ts +59 -1
- 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/services/events/utils.d.ts +1 -1
- 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,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as hono0 from "hono";
|
|
2
2
|
|
|
3
3
|
//#region src/github/mcp/auth.d.ts
|
|
4
|
-
declare const githubMcpAuth: () =>
|
|
4
|
+
declare const githubMcpAuth: () => hono0.MiddlewareHandler<{
|
|
5
5
|
Variables: {
|
|
6
6
|
toolId: string;
|
|
7
7
|
};
|
|
@@ -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;
|
|
@@ -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 };
|
|
@@ -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;
|
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",
|