import type { ExtensionAPI } from "@jaeswift/jae-coding-agent"; import { Type } from "@sinclair/typebox"; export default function (pi: ExtensionAPI) { async function reviewDiff(diff: string, ctx: any): Promise { if (!diff.trim()) return "No diff content to review."; const lines = diff.split("\n"); const stats = { filesChanged: 0, additions: 0, deletions: 0, files: [] as string[], }; for (const line of lines) { if (line.startsWith("+++ b/")) { stats.filesChanged++; stats.files.push(line.replace("+++ b/", "")); } else if (line.startsWith("+") && !line.startsWith("+++")) { stats.additions++; } else if (line.startsWith("-") && !line.startsWith("---")) { stats.deletions++; } } return [ `## PR Review Summary`, ``, `**Files changed:** ${stats.filesChanged}`, `**Additions:** +${stats.additions}`, `**Deletions:** -${stats.deletions}`, ``, `### Files:`, ...stats.files.map((f) => `- ${f}`), ``, `### Diff Preview (first 200 lines):`, "```diff", lines.slice(0, 200).join("\n"), "```", ``, `> Full review requires LLM analysis. Send this diff as context to JAE for detailed review.`, ].join("\n"); } pi.registerTool({ name: "pr_review", label: "PR Review", description: "Review a pull request or git diff. Provide a branch name, PR URL, or commit range.", parameters: Type.Object({ target: Type.String({ description: "Branch name, PR URL, or commit range (e.g., 'main..feature', 'origin/main')" }), }), execute: async (args, ctx) => { const { target } = args; let diff = ""; // Try as branch comparison const diffResult = await pi.exec( "git", ["diff", target], { cwd: ctx.cwd }, ); if (diffResult.code === 0 && diffResult.stdout.trim()) { diff = diffResult.stdout; } else { // Try as range const rangeResult = await pi.exec( "git", ["diff", `${target}`], { cwd: ctx.cwd }, ); if (rangeResult.code === 0) { diff = rangeResult.stdout; } else { return { error: `Could not get diff for: ${target}. Error: ${diffResult.stderr || rangeResult.stderr}` }; } } const review = await reviewDiff(diff, ctx); return { output: review }; }, }); pi.registerCommand("pr-review", { description: "Review a PR or branch diff: /pr-review ", handler: async (args, ctx) => { const target = args.trim(); if (!target) { ctx.ui.notify("Usage: /pr-review \nExamples:\n /pr-review main..feature\n /pr-review origin/main", "info"); return; } ctx.ui.notify(`\u{1F50D} Fetching diff for: ${target}...`, "info"); const diffResult = await pi.exec("git", ["diff", target], { cwd: ctx.cwd }); if (diffResult.code !== 0) { ctx.ui.notify(`Failed to get diff: ${diffResult.stderr}`, "error"); return; } if (!diffResult.stdout.trim()) { ctx.ui.notify("No differences found.", "info"); return; } const review = await reviewDiff(diffResult.stdout, ctx); ctx.ui.notify(review, "info"); }, }); }