Improve prInfo. Fix prompt duplication
This commit is contained in:
committed by
pullfrog[bot]
parent
01ee59a96c
commit
22704dda35
@@ -121084,32 +121084,57 @@ function CreatePullRequestTool(ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mcp/prInfo.ts
|
// mcp/prInfo.ts
|
||||||
|
var CLOSING_ISSUES_QUERY = `
|
||||||
|
query($owner: String!, $repo: String!, $number: Int!) {
|
||||||
|
repository(owner: $owner, name: $repo) {
|
||||||
|
pullRequest(number: $number) {
|
||||||
|
closingIssuesReferences(first: 10) {
|
||||||
|
nodes { number title }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
var PullRequestInfo = type({
|
var PullRequestInfo = type({
|
||||||
pull_number: type.number.describe("The pull request number to fetch")
|
pull_number: type.number.describe("The pull request number to fetch")
|
||||||
});
|
});
|
||||||
function PullRequestInfoTool(ctx) {
|
function PullRequestInfoTool(ctx) {
|
||||||
return tool({
|
return tool({
|
||||||
name: "get_pull_request",
|
name: "get_pull_request",
|
||||||
description: "Retrieve PR metadata (number, title, state, base/head branches, fork status). To checkout a PR branch locally, use checkout_pr instead.",
|
description: "Retrieve PR metadata (title, body, state, branches, author, labels, linked issues). To checkout a PR branch locally, use checkout_pr instead.",
|
||||||
parameters: PullRequestInfo,
|
parameters: PullRequestInfo,
|
||||||
execute: execute(async ({ pull_number }) => {
|
execute: execute(async ({ pull_number }) => {
|
||||||
const pr = await ctx.octokit.rest.pulls.get({
|
const [restResponse, graphqlResponse] = await Promise.all([
|
||||||
owner: ctx.repo.owner,
|
ctx.octokit.rest.pulls.get({
|
||||||
repo: ctx.repo.name,
|
owner: ctx.repo.owner,
|
||||||
pull_number
|
repo: ctx.repo.name,
|
||||||
});
|
pull_number
|
||||||
const data = pr.data;
|
}),
|
||||||
|
ctx.octokit.graphql(CLOSING_ISSUES_QUERY, {
|
||||||
|
owner: ctx.repo.owner,
|
||||||
|
repo: ctx.repo.name,
|
||||||
|
number: pull_number
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
const data = restResponse.data;
|
||||||
const isFork = data.head.repo?.full_name !== data.base.repo.full_name;
|
const isFork = data.head.repo?.full_name !== data.base.repo.full_name;
|
||||||
|
const closingIssues = graphqlResponse.repository.pullRequest.closingIssuesReferences.nodes;
|
||||||
return {
|
return {
|
||||||
number: data.number,
|
number: data.number,
|
||||||
url: data.html_url,
|
url: data.html_url,
|
||||||
title: data.title,
|
title: data.title,
|
||||||
|
body: data.body,
|
||||||
state: data.state,
|
state: data.state,
|
||||||
draft: data.draft,
|
draft: data.draft,
|
||||||
merged: data.merged,
|
merged: data.merged,
|
||||||
|
maintainerCanModify: data.maintainer_can_modify,
|
||||||
base: data.base.ref,
|
base: data.base.ref,
|
||||||
head: data.head.ref,
|
head: data.head.ref,
|
||||||
isFork
|
isFork,
|
||||||
|
author: data.user?.login,
|
||||||
|
assignees: data.assignees?.map((a) => a.login),
|
||||||
|
labels: data.labels.map((l) => l.name),
|
||||||
|
closingIssues: closingIssues.map((i) => ({ number: i.number, title: i.title }))
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
+6
-6
@@ -138,8 +138,8 @@ interface PullRequestReviewCommentCreatedEvent extends BasePayloadEvent {
|
|||||||
is_pr: true;
|
is_pr: true;
|
||||||
title: string;
|
title: string;
|
||||||
comment_id: number;
|
comment_id: number;
|
||||||
/** comment body is the primary content */
|
/** comment body is the primary content (null if already in prompt) */
|
||||||
body: string;
|
body: string | null;
|
||||||
thread?: any;
|
thread?: any;
|
||||||
branch: string;
|
branch: string;
|
||||||
}
|
}
|
||||||
@@ -168,8 +168,8 @@ interface IssuesLabeledEvent extends BasePayloadEvent {
|
|||||||
interface IssueCommentCreatedEvent extends BasePayloadEvent {
|
interface IssueCommentCreatedEvent extends BasePayloadEvent {
|
||||||
trigger: "issue_comment_created";
|
trigger: "issue_comment_created";
|
||||||
comment_id: number;
|
comment_id: number;
|
||||||
/** comment body is the primary content */
|
/** comment body is the primary content (null if already in prompt) */
|
||||||
body: string;
|
body: string | null;
|
||||||
issue_number: number;
|
issue_number: number;
|
||||||
// PR-specific fields (only present when is_pr is true)
|
// PR-specific fields (only present when is_pr is true)
|
||||||
is_pr?: true;
|
is_pr?: true;
|
||||||
@@ -212,8 +212,8 @@ interface ImplementPlanEvent extends BasePayloadEvent {
|
|||||||
trigger: "implement_plan";
|
trigger: "implement_plan";
|
||||||
issue_number: number;
|
issue_number: number;
|
||||||
plan_comment_id: number;
|
plan_comment_id: number;
|
||||||
/** plan content is the primary content */
|
/** plan content is the primary content (null if already in prompt) */
|
||||||
body: string;
|
body: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UnknownEvent extends BasePayloadEvent {
|
interface UnknownEvent extends BasePayloadEvent {
|
||||||
|
|||||||
+42
-9
@@ -2,6 +2,26 @@ import { type } from "arktype";
|
|||||||
import type { ToolContext } from "./server.ts";
|
import type { ToolContext } from "./server.ts";
|
||||||
import { execute, tool } from "./shared.ts";
|
import { execute, tool } from "./shared.ts";
|
||||||
|
|
||||||
|
const CLOSING_ISSUES_QUERY = `
|
||||||
|
query($owner: String!, $repo: String!, $number: Int!) {
|
||||||
|
repository(owner: $owner, name: $repo) {
|
||||||
|
pullRequest(number: $number) {
|
||||||
|
closingIssuesReferences(first: 10) {
|
||||||
|
nodes { number title }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
type ClosingIssuesResponse = {
|
||||||
|
repository: {
|
||||||
|
pullRequest: {
|
||||||
|
closingIssuesReferences: { nodes: Array<{ number: number; title: string }> };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const PullRequestInfo = type({
|
export const PullRequestInfo = type({
|
||||||
pull_number: type.number.describe("The pull request number to fetch"),
|
pull_number: type.number.describe("The pull request number to fetch"),
|
||||||
});
|
});
|
||||||
@@ -10,30 +30,43 @@ export function PullRequestInfoTool(ctx: ToolContext) {
|
|||||||
return tool({
|
return tool({
|
||||||
name: "get_pull_request",
|
name: "get_pull_request",
|
||||||
description:
|
description:
|
||||||
"Retrieve PR metadata (number, title, state, base/head branches, fork status). To checkout a PR branch locally, use checkout_pr instead.",
|
"Retrieve PR metadata (title, body, state, branches, author, labels, linked issues). To checkout a PR branch locally, use checkout_pr instead.",
|
||||||
parameters: PullRequestInfo,
|
parameters: PullRequestInfo,
|
||||||
execute: execute(async ({ pull_number }) => {
|
execute: execute(async ({ pull_number }) => {
|
||||||
const pr = await ctx.octokit.rest.pulls.get({
|
// fetch REST and GraphQL in parallel
|
||||||
owner: ctx.repo.owner,
|
const [restResponse, graphqlResponse] = await Promise.all([
|
||||||
repo: ctx.repo.name,
|
ctx.octokit.rest.pulls.get({
|
||||||
pull_number,
|
owner: ctx.repo.owner,
|
||||||
});
|
repo: ctx.repo.name,
|
||||||
|
pull_number,
|
||||||
|
}),
|
||||||
|
ctx.octokit.graphql<ClosingIssuesResponse>(CLOSING_ISSUES_QUERY, {
|
||||||
|
owner: ctx.repo.owner,
|
||||||
|
repo: ctx.repo.name,
|
||||||
|
number: pull_number,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
const data = pr.data;
|
const data = restResponse.data;
|
||||||
|
|
||||||
// detect fork PRs - head repo differs from base repo (head.repo can be null if fork was deleted)
|
|
||||||
const isFork = data.head.repo?.full_name !== data.base.repo.full_name;
|
const isFork = data.head.repo?.full_name !== data.base.repo.full_name;
|
||||||
|
const closingIssues = graphqlResponse.repository.pullRequest.closingIssuesReferences.nodes;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
number: data.number,
|
number: data.number,
|
||||||
url: data.html_url,
|
url: data.html_url,
|
||||||
title: data.title,
|
title: data.title,
|
||||||
|
body: data.body,
|
||||||
state: data.state,
|
state: data.state,
|
||||||
draft: data.draft,
|
draft: data.draft,
|
||||||
merged: data.merged,
|
merged: data.merged,
|
||||||
|
maintainerCanModify: data.maintainer_can_modify,
|
||||||
base: data.base.ref,
|
base: data.base.ref,
|
||||||
head: data.head.ref,
|
head: data.head.ref,
|
||||||
isFork,
|
isFork,
|
||||||
|
author: data.user?.login,
|
||||||
|
assignees: data.assignees?.map((a) => a.login),
|
||||||
|
labels: data.labels.map((l) => l.name),
|
||||||
|
closingIssues: closingIssues.map((i) => ({ number: i.number, title: i.title })),
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user