82 lines
3.4 KiB
TypeScript
82 lines
3.4 KiB
TypeScript
import { writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { type } from "arktype";
|
|
import { stripExistingFooter } from "../utils/buildShockbotFooter.ts";
|
|
import { log } from "../utils/log.ts";
|
|
import type { ToolContext } from "./server.ts";
|
|
import { execute, tool } from "./shared.ts";
|
|
|
|
interface GiteaReview { id: number; user?: { login: string }; state?: string; body?: string; submitted_at?: string; commit_id?: string }
|
|
interface GiteaReviewComment { id: number; body?: string; path?: string; diff_hunk?: string; original_position?: number; position?: number; pull_request_review_id?: number; user?: { login: string } }
|
|
|
|
export const GetReviewComments = type({ pull_number: type.number });
|
|
|
|
export function GetReviewCommentsTool(ctx: ToolContext) {
|
|
return tool({
|
|
name: "get_review_comments",
|
|
description: "Get all inline review comments for a pull request. Example: `get_review_comments({ pull_number: 1234 })`.",
|
|
parameters: GetReviewComments,
|
|
execute: execute(async ({ pull_number }) => {
|
|
ctx.toolState.issueNumber = pull_number;
|
|
const reviewsR = await ctx.gitea.request(
|
|
"GET /repos/{owner}/{repo}/pulls/{index}/reviews",
|
|
{ owner: ctx.repo.owner, repo: ctx.repo.name, index: pull_number, limit: 50 }
|
|
);
|
|
const reviews = reviewsR.data as GiteaReview[];
|
|
|
|
const allComments: GiteaReviewComment[] = [];
|
|
for (const review of reviews) {
|
|
if (!review.id) continue;
|
|
try {
|
|
const cr = await ctx.gitea.request(
|
|
"GET /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments",
|
|
{ owner: ctx.repo.owner, repo: ctx.repo.name, index: pull_number, id: review.id }
|
|
);
|
|
allComments.push(...(cr.data as GiteaReviewComment[]));
|
|
} catch { /* best-effort */ }
|
|
}
|
|
|
|
const tempDir = process.env.SHOCKBOT_TEMP_DIR;
|
|
let filePath: string | undefined;
|
|
const rendered = allComments.map((c) => ({
|
|
id: c.id, path: c.path,
|
|
line: c.original_position ?? c.position,
|
|
side: "RIGHT" as const,
|
|
body: stripExistingFooter(c.body ?? ""),
|
|
author: c.user?.login,
|
|
diffHunk: c.diff_hunk,
|
|
reviewId: c.pull_request_review_id,
|
|
}));
|
|
|
|
if (tempDir && rendered.length > 0) {
|
|
filePath = join(tempDir, `pr-${pull_number}-review-comments.json`);
|
|
writeFileSync(filePath, JSON.stringify(rendered, null, 2));
|
|
log.debug(`wrote review comments to ${filePath}`);
|
|
}
|
|
return { pull_number, comments: rendered, count: rendered.length, ...(filePath ? { filePath } : {}) };
|
|
}),
|
|
});
|
|
}
|
|
|
|
export const ListPullRequestReviews = type({ pull_number: type.number });
|
|
|
|
export function ListPullRequestReviewsTool(ctx: ToolContext) {
|
|
return tool({
|
|
name: "list_pull_request_reviews",
|
|
description: "List all reviews submitted on a pull request. Example: `list_pull_request_reviews({ pull_number: 1234 })`.",
|
|
parameters: ListPullRequestReviews,
|
|
execute: execute(async ({ pull_number }) => {
|
|
const r = await ctx.gitea.request(
|
|
"GET /repos/{owner}/{repo}/pulls/{index}/reviews",
|
|
{ owner: ctx.repo.owner, repo: ctx.repo.name, index: pull_number, limit: 50 }
|
|
);
|
|
const reviews = r.data as GiteaReview[];
|
|
return {
|
|
pull_number,
|
|
reviews: reviews.map((r) => ({ id: r.id, user: r.user?.login, state: r.state, body: r.body, submitted_at: r.submitted_at, commit_id: r.commit_id })),
|
|
count: reviews.length,
|
|
};
|
|
}),
|
|
});
|
|
}
|