import { z } from "zod";
import { batch, run, stmt } from "../../db";
import { randomId } from "../../crypto";
import { badRequest, conflict, forbidden, HttpError, notFoundError } from "../../errors";
import { createPull, getPull, listPulls, mergePull, updatePullBranch } from "../../api/pulls";
import { headBranchConflicts, requireHeadPush, updateHeadBranch } from "../../pull-merge";
import { pullDiff } from "../../pull-files";
import { loadPull, MergeError } from "../../pulls";
import type { PullRow } from "../../pulls";
import { pullUrl } from "../../pull-access";
import { hasPermission, loadRepoById } from "../../repos";
import { scopedRepoPermission } from "../../token-scope";
import { kickMergeAutomation } from "../../merge-automation";
import { emitNotification, emitWebhook } from "../../events/emit";
import { limitHeavy, limitWrite } from "../../limits";
import { markdownBody, title } from "~/lib/validation";
import type { McpCaller } from "../protocol";
import { apiCtx, apiJson, attributionFooter, defineTool, repoArgs, scopedRepo, truncateText } from "./base";
const number = z.number().int().positive();
const MAX_PATCH_CHARS = 48 * 1024;
const MAX_RESOLVED_CHARS = 1024 * 1024;
const HTTP_CONFLICT = 409;
async function pullFor(
caller: McpCaller,
ownerName: string,
repoName: string,
pullNumber: number,
needed: "read" | "write",
) {
const scoped = await scopedRepo(caller, ownerName, repoName, "pulls", needed);
const pull = await loadPull(scoped.repo.id, pullNumber);
if (!pull) throw notFoundError("Pull request not found");
const headRepo = pull.head_repo_id === scoped.repo.id ? scoped.repo : await loadRepoById(pull.head_repo_id);
if (!headRepo) throw notFoundError("Head repository was deleted");
return { ...scoped, pull, headRepo };
}
const listPullsTool = defineTool({