From c67b2df6ac32de25cd62d7274e34b665cb2431fb Mon Sep 17 00:00:00 2001 From: Nizar Alrifai Date: Wed, 4 Mar 2026 14:31:57 -0800 Subject: [PATCH 1/2] Batch all review comments into a single submit_review call Instead of posting inline comments individually via create_inline_comment (which creates separate review events for each), batch all comments into the submit_review comments array. This produces a single cohesive review. - Updated submit_review tool schema to support line/side/start_line format - Updated review and validator prompts to batch comments - Removed create_inline_comment from review allowed tools Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .../templates/review-validator-prompt.ts | 5 +- src/mcp/github-pr-server.ts | 47 ++++++++++++++++--- src/tag/commands/review-validator.ts | 1 - 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/create-prompt/templates/review-validator-prompt.ts b/src/create-prompt/templates/review-validator-prompt.ts index db19941..6ba76bb 100644 --- a/src/create-prompt/templates/review-validator-prompt.ts +++ b/src/create-prompt/templates/review-validator-prompt.ts @@ -173,8 +173,9 @@ Tooling note: After writing \`${reviewValidatedPath}\`, post comments ONLY for \`status === "approved"\`: -* For each approved entry, call \`github_inline_comment___create_inline_comment\` with the \`comment\` object. -* If there are approved inline comments, call \`github_pr___submit_review\` to submit them — do **NOT** include a \`body\` parameter. +* Collect all approved comments and submit them as a **single batched review** via \`github_pr___submit_review\`, passing them in the \`comments\` array parameter. +* Do **NOT** post comments individually — batch them all into one \`submit_review\` call. +* do **NOT** include a \`body\` parameter in \`submit_review\`. * Use \`github_comment___update_droid_comment\` to update the tracking comment with the review summary. * Do **NOT** post the summary as a separate comment or as the body of \`submit_review\`. * Do not approve or request changes. diff --git a/src/mcp/github-pr-server.ts b/src/mcp/github-pr-server.ts index 1323b5c..c780343 100644 --- a/src/mcp/github-pr-server.ts +++ b/src/mcp/github-pr-server.ts @@ -181,6 +181,16 @@ export async function listReviewAndIssueComments({ }; } +export type ReviewComment = { + path: string; + body: string; + line?: number; + side?: string; + start_line?: number; + start_side?: string; + position?: number; +}; + export async function submitReviewWithComments({ owner, repo, @@ -193,7 +203,7 @@ export async function submitReviewWithComments({ repo: string; prNumber: number; body?: string; - comments?: Array<{ path: string; position: number; body: string }>; + comments?: ReviewComment[]; octokit: OctokitLike; }): Promise { const response = await octokit.rest.pulls.createReview({ @@ -603,20 +613,45 @@ export function createGitHubPRServer({ server.tool( "submit_review", - "Submit a PR review containing inline comments", + "Submit a PR review with all inline comments batched into a single review. " + + "Use line/side to anchor comments to specific lines in the diff.", { pr_number: z.number().int().describe("PR number to review"), body: z.string().describe("Optional summary body").optional(), comments: z .array( z.object({ - path: z.string(), - position: z.number().int(), - body: z.string().min(1), + path: z + .string() + .describe("The file path to comment on (e.g., 'src/index.js')"), + body: z.string().min(1).describe("The comment text (supports markdown and GitHub code suggestion blocks)"), + line: z + .number() + .int() + .optional() + .describe( + "Line number for single-line comments, or end line for multi-line comments", + ), + side: z + .enum(["LEFT", "RIGHT"]) + .optional() + .default("RIGHT") + .describe( + "Side of the diff: RIGHT for new/modified code, LEFT for removed code", + ), + start_line: z + .number() + .int() + .optional() + .describe("Start line for multi-line comments"), + start_side: z + .enum(["LEFT", "RIGHT"]) + .optional() + .describe("Side for the start line of multi-line comments"), }), ) .max(30) - .describe("List of inline comments to include") + .describe("List of inline comments to include in the review") .optional(), }, async ({ pr_number, body, comments }) => { diff --git a/src/tag/commands/review-validator.ts b/src/tag/commands/review-validator.ts index 96f8ea8..81fa33b 100644 --- a/src/tag/commands/review-validator.ts +++ b/src/tag/commands/review-validator.ts @@ -80,7 +80,6 @@ export async function prepareReviewValidatorMode({ "Create", "Edit", "github_comment___update_droid_comment", - "github_inline_comment___create_inline_comment", ]; const validatorTools = ["github_pr___submit_review"]; From 5fd976da03537cc095cebbe3b8f458613f2fff26 Mon Sep 17 00:00:00 2001 From: factory-nizar Date: Thu, 5 Mar 2026 12:31:08 -0800 Subject: [PATCH 2/2] Update github-pr-server.ts --- src/mcp/github-pr-server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mcp/github-pr-server.ts b/src/mcp/github-pr-server.ts index c780343..5a57268 100644 --- a/src/mcp/github-pr-server.ts +++ b/src/mcp/github-pr-server.ts @@ -181,7 +181,7 @@ export async function listReviewAndIssueComments({ }; } -export type ReviewComment = { +type ReviewComment = { path: string; body: string; line?: number;