diffprism 0.33.0 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +2 -2
- package/dist/{chunk-ZLIUNVTW.js → chunk-VASCXEMN.js} +156 -37
- package/dist/mcp-server.js +5 -5
- package/package.json +1 -1
- package/ui-dist/assets/index-BfqEajZq.js +325 -0
- package/ui-dist/assets/index-vG-fI3wH.css +1 -0
- package/ui-dist/index.html +2 -2
- package/ui-dist/assets/index-D_thqcUo.js +0 -324
- package/ui-dist/assets/index-w55XbIEb.css +0 -1
package/dist/bin.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
startReview,
|
|
14
14
|
startWatch,
|
|
15
15
|
submitGitHubReview
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-VASCXEMN.js";
|
|
17
17
|
|
|
18
18
|
// cli/src/index.ts
|
|
19
19
|
import { Command } from "commander";
|
|
@@ -1001,7 +1001,7 @@ async function serverStop() {
|
|
|
1001
1001
|
|
|
1002
1002
|
// cli/src/index.ts
|
|
1003
1003
|
var program = new Command();
|
|
1004
|
-
program.name("diffprism").description("Local-first code review tool for agent-generated changes").version(true ? "0.
|
|
1004
|
+
program.name("diffprism").description("Local-first code review tool for agent-generated changes").version(true ? "0.34.1" : "0.0.0-dev");
|
|
1005
1005
|
program.command("review [ref]").description("Open a browser-based diff review").option("--staged", "Review staged changes").option("--unstaged", "Review unstaged changes").option("-t, --title <title>", "Review title").option("--dev", "Use Vite dev server with HMR instead of static files").action(review);
|
|
1006
1006
|
program.command("review-pr <pr>").description("Review a GitHub pull request in DiffPrism").option("-t, --title <title>", "Override review title").option("--reasoning <text>", "Agent reasoning about the PR").option("--dev", "Use Vite dev server with HMR instead of static files").option("--post-to-github", "Automatically post review back to GitHub without prompting").action(reviewPr);
|
|
1007
1007
|
program.command("start [ref]").description("Set up DiffPrism and start watching for changes").option("--staged", "Watch staged changes").option("--unstaged", "Watch unstaged changes").option("-t, --title <title>", "Review title").option("--interval <ms>", "Poll interval in milliseconds (default: 1000)").option("--dev", "Use Vite dev server with HMR instead of static files").option("--global", "Install skill globally (~/.claude/skills/)").option("--force", "Overwrite existing configuration files").action(start);
|
|
@@ -1155,6 +1155,45 @@ function consumeReviewResult(cwd) {
|
|
|
1155
1155
|
import getPort from "get-port";
|
|
1156
1156
|
import open from "open";
|
|
1157
1157
|
|
|
1158
|
+
// packages/core/src/review-history.ts
|
|
1159
|
+
import fs2 from "fs";
|
|
1160
|
+
import path4 from "path";
|
|
1161
|
+
import { randomUUID } from "crypto";
|
|
1162
|
+
function generateEntryId() {
|
|
1163
|
+
return randomUUID();
|
|
1164
|
+
}
|
|
1165
|
+
function getHistoryPath(projectDir) {
|
|
1166
|
+
return path4.join(projectDir, ".diffprism", "history", "reviews.json");
|
|
1167
|
+
}
|
|
1168
|
+
function readHistory(projectDir) {
|
|
1169
|
+
const filePath = getHistoryPath(projectDir);
|
|
1170
|
+
if (!fs2.existsSync(filePath)) {
|
|
1171
|
+
return { version: 1, entries: [] };
|
|
1172
|
+
}
|
|
1173
|
+
try {
|
|
1174
|
+
const raw = fs2.readFileSync(filePath, "utf-8");
|
|
1175
|
+
const parsed = JSON.parse(raw);
|
|
1176
|
+
return parsed;
|
|
1177
|
+
} catch {
|
|
1178
|
+
return { version: 1, entries: [] };
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
function appendHistory(projectDir, entry) {
|
|
1182
|
+
const filePath = getHistoryPath(projectDir);
|
|
1183
|
+
const dir = path4.dirname(filePath);
|
|
1184
|
+
if (!fs2.existsSync(dir)) {
|
|
1185
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
1186
|
+
}
|
|
1187
|
+
const history = readHistory(projectDir);
|
|
1188
|
+
history.entries.push(entry);
|
|
1189
|
+
history.entries.sort((a, b) => a.timestamp - b.timestamp);
|
|
1190
|
+
fs2.writeFileSync(filePath, JSON.stringify(history, null, 2) + "\n");
|
|
1191
|
+
}
|
|
1192
|
+
function getRecentHistory(projectDir, limit = 50) {
|
|
1193
|
+
const history = readHistory(projectDir);
|
|
1194
|
+
return history.entries.slice(-limit);
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1158
1197
|
// packages/core/src/watch-bridge.ts
|
|
1159
1198
|
import http from "http";
|
|
1160
1199
|
import { WebSocketServer, WebSocket } from "ws";
|
|
@@ -1478,8 +1517,8 @@ function updateSession(id, update) {
|
|
|
1478
1517
|
|
|
1479
1518
|
// packages/core/src/ui-server.ts
|
|
1480
1519
|
import http2 from "http";
|
|
1481
|
-
import
|
|
1482
|
-
import
|
|
1520
|
+
import fs3 from "fs";
|
|
1521
|
+
import path5 from "path";
|
|
1483
1522
|
import { fileURLToPath } from "url";
|
|
1484
1523
|
var MIME_TYPES = {
|
|
1485
1524
|
".html": "text/html",
|
|
@@ -1494,14 +1533,14 @@ var MIME_TYPES = {
|
|
|
1494
1533
|
};
|
|
1495
1534
|
function resolveUiDist() {
|
|
1496
1535
|
const thisFile = fileURLToPath(import.meta.url);
|
|
1497
|
-
const thisDir =
|
|
1498
|
-
const publishedUiDist =
|
|
1499
|
-
if (
|
|
1536
|
+
const thisDir = path5.dirname(thisFile);
|
|
1537
|
+
const publishedUiDist = path5.resolve(thisDir, "..", "ui-dist");
|
|
1538
|
+
if (fs3.existsSync(path5.join(publishedUiDist, "index.html"))) {
|
|
1500
1539
|
return publishedUiDist;
|
|
1501
1540
|
}
|
|
1502
|
-
const workspaceRoot =
|
|
1503
|
-
const devUiDist =
|
|
1504
|
-
if (
|
|
1541
|
+
const workspaceRoot = path5.resolve(thisDir, "..", "..", "..");
|
|
1542
|
+
const devUiDist = path5.join(workspaceRoot, "packages", "ui", "dist");
|
|
1543
|
+
if (fs3.existsSync(path5.join(devUiDist, "index.html"))) {
|
|
1505
1544
|
return devUiDist;
|
|
1506
1545
|
}
|
|
1507
1546
|
throw new Error(
|
|
@@ -1510,10 +1549,10 @@ function resolveUiDist() {
|
|
|
1510
1549
|
}
|
|
1511
1550
|
function resolveUiRoot() {
|
|
1512
1551
|
const thisFile = fileURLToPath(import.meta.url);
|
|
1513
|
-
const thisDir =
|
|
1514
|
-
const workspaceRoot =
|
|
1515
|
-
const uiRoot =
|
|
1516
|
-
if (
|
|
1552
|
+
const thisDir = path5.dirname(thisFile);
|
|
1553
|
+
const workspaceRoot = path5.resolve(thisDir, "..", "..", "..");
|
|
1554
|
+
const uiRoot = path5.join(workspaceRoot, "packages", "ui");
|
|
1555
|
+
if (fs3.existsSync(path5.join(uiRoot, "index.html"))) {
|
|
1517
1556
|
return uiRoot;
|
|
1518
1557
|
}
|
|
1519
1558
|
throw new Error(
|
|
@@ -1533,14 +1572,14 @@ async function startViteDevServer(uiRoot, port, silent) {
|
|
|
1533
1572
|
function createStaticServer(distPath, port) {
|
|
1534
1573
|
const server = http2.createServer((req, res) => {
|
|
1535
1574
|
const urlPath = req.url?.split("?")[0] ?? "/";
|
|
1536
|
-
let filePath =
|
|
1537
|
-
if (!
|
|
1538
|
-
filePath =
|
|
1575
|
+
let filePath = path5.join(distPath, urlPath === "/" ? "index.html" : urlPath);
|
|
1576
|
+
if (!fs3.existsSync(filePath)) {
|
|
1577
|
+
filePath = path5.join(distPath, "index.html");
|
|
1539
1578
|
}
|
|
1540
|
-
const ext =
|
|
1579
|
+
const ext = path5.extname(filePath);
|
|
1541
1580
|
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
1542
1581
|
try {
|
|
1543
|
-
const content =
|
|
1582
|
+
const content = fs3.readFileSync(filePath);
|
|
1544
1583
|
res.writeHead(200, { "Content-Type": contentType });
|
|
1545
1584
|
res.end(content);
|
|
1546
1585
|
} catch {
|
|
@@ -1737,6 +1776,24 @@ DiffPrism Review: ${title ?? briefing.summary}`);
|
|
|
1737
1776
|
const result = await bridge.waitForResult();
|
|
1738
1777
|
poller?.stop();
|
|
1739
1778
|
updateSession(session.id, { status: "completed", result });
|
|
1779
|
+
try {
|
|
1780
|
+
const projectDir = cwd ?? process.cwd();
|
|
1781
|
+
const entry = {
|
|
1782
|
+
id: generateEntryId(),
|
|
1783
|
+
timestamp: Date.now(),
|
|
1784
|
+
diffRef,
|
|
1785
|
+
decision: result.decision,
|
|
1786
|
+
filesReviewed: diffSet.files.length,
|
|
1787
|
+
additions: diffSet.files.reduce((sum, f) => sum + f.additions, 0),
|
|
1788
|
+
deletions: diffSet.files.reduce((sum, f) => sum + f.deletions, 0),
|
|
1789
|
+
commentCount: result.comments.length,
|
|
1790
|
+
branch: metadata.currentBranch,
|
|
1791
|
+
title: metadata.title,
|
|
1792
|
+
summary: result.summary ?? briefing.summary
|
|
1793
|
+
};
|
|
1794
|
+
appendHistory(projectDir, entry);
|
|
1795
|
+
} catch {
|
|
1796
|
+
}
|
|
1740
1797
|
return result;
|
|
1741
1798
|
} finally {
|
|
1742
1799
|
poller?.stop();
|
|
@@ -1752,14 +1809,14 @@ DiffPrism Review: ${title ?? briefing.summary}`);
|
|
|
1752
1809
|
}
|
|
1753
1810
|
|
|
1754
1811
|
// packages/core/src/server-file.ts
|
|
1755
|
-
import
|
|
1756
|
-
import
|
|
1812
|
+
import fs4 from "fs";
|
|
1813
|
+
import path6 from "path";
|
|
1757
1814
|
import os from "os";
|
|
1758
1815
|
function serverDir() {
|
|
1759
|
-
return
|
|
1816
|
+
return path6.join(os.homedir(), ".diffprism");
|
|
1760
1817
|
}
|
|
1761
1818
|
function serverFilePath() {
|
|
1762
|
-
return
|
|
1819
|
+
return path6.join(serverDir(), "server.json");
|
|
1763
1820
|
}
|
|
1764
1821
|
function isPidAlive2(pid) {
|
|
1765
1822
|
try {
|
|
@@ -1771,21 +1828,21 @@ function isPidAlive2(pid) {
|
|
|
1771
1828
|
}
|
|
1772
1829
|
function writeServerFile(info) {
|
|
1773
1830
|
const dir = serverDir();
|
|
1774
|
-
if (!
|
|
1775
|
-
|
|
1831
|
+
if (!fs4.existsSync(dir)) {
|
|
1832
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
1776
1833
|
}
|
|
1777
|
-
|
|
1834
|
+
fs4.writeFileSync(serverFilePath(), JSON.stringify(info, null, 2) + "\n");
|
|
1778
1835
|
}
|
|
1779
1836
|
function readServerFile() {
|
|
1780
1837
|
const filePath = serverFilePath();
|
|
1781
|
-
if (!
|
|
1838
|
+
if (!fs4.existsSync(filePath)) {
|
|
1782
1839
|
return null;
|
|
1783
1840
|
}
|
|
1784
1841
|
try {
|
|
1785
|
-
const raw =
|
|
1842
|
+
const raw = fs4.readFileSync(filePath, "utf-8");
|
|
1786
1843
|
const info = JSON.parse(raw);
|
|
1787
1844
|
if (!isPidAlive2(info.pid)) {
|
|
1788
|
-
|
|
1845
|
+
fs4.unlinkSync(filePath);
|
|
1789
1846
|
return null;
|
|
1790
1847
|
}
|
|
1791
1848
|
return info;
|
|
@@ -1796,8 +1853,8 @@ function readServerFile() {
|
|
|
1796
1853
|
function removeServerFile() {
|
|
1797
1854
|
try {
|
|
1798
1855
|
const filePath = serverFilePath();
|
|
1799
|
-
if (
|
|
1800
|
-
|
|
1856
|
+
if (fs4.existsSync(filePath)) {
|
|
1857
|
+
fs4.unlinkSync(filePath);
|
|
1801
1858
|
}
|
|
1802
1859
|
} catch {
|
|
1803
1860
|
}
|
|
@@ -1998,7 +2055,7 @@ Review submitted: ${result.decision}`);
|
|
|
1998
2055
|
|
|
1999
2056
|
// packages/core/src/global-server.ts
|
|
2000
2057
|
import http3 from "http";
|
|
2001
|
-
import { randomUUID } from "crypto";
|
|
2058
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
2002
2059
|
import getPort3 from "get-port";
|
|
2003
2060
|
import open3 from "open";
|
|
2004
2061
|
import { WebSocketServer as WebSocketServer2, WebSocket as WebSocket2 } from "ws";
|
|
@@ -2171,6 +2228,27 @@ function broadcastSessionList() {
|
|
|
2171
2228
|
const summaries = Array.from(sessions2.values()).map(toSummary);
|
|
2172
2229
|
broadcastToAll({ type: "session:list", payload: summaries });
|
|
2173
2230
|
}
|
|
2231
|
+
function recordReviewHistory(session, result) {
|
|
2232
|
+
if (session.projectPath.startsWith("github:")) return;
|
|
2233
|
+
try {
|
|
2234
|
+
const { payload } = session;
|
|
2235
|
+
const entry = {
|
|
2236
|
+
id: generateEntryId(),
|
|
2237
|
+
timestamp: Date.now(),
|
|
2238
|
+
diffRef: session.diffRef ?? "unknown",
|
|
2239
|
+
decision: result.decision,
|
|
2240
|
+
filesReviewed: payload.diffSet.files.length,
|
|
2241
|
+
additions: payload.diffSet.files.reduce((sum, f) => sum + f.additions, 0),
|
|
2242
|
+
deletions: payload.diffSet.files.reduce((sum, f) => sum + f.deletions, 0),
|
|
2243
|
+
commentCount: result.comments.length,
|
|
2244
|
+
branch: payload.metadata.currentBranch,
|
|
2245
|
+
title: payload.metadata.title,
|
|
2246
|
+
summary: result.summary ?? payload.briefing.summary
|
|
2247
|
+
};
|
|
2248
|
+
appendHistory(session.projectPath, entry);
|
|
2249
|
+
} catch {
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2174
2252
|
async function handleApiRequest(req, res) {
|
|
2175
2253
|
const method = req.method ?? "GET";
|
|
2176
2254
|
const url = (req.url ?? "/").split("?")[0];
|
|
@@ -2234,7 +2312,7 @@ async function handleApiRequest(req, res) {
|
|
|
2234
2312
|
reopenBrowserIfNeeded?.();
|
|
2235
2313
|
jsonResponse(res, 200, { sessionId });
|
|
2236
2314
|
} else {
|
|
2237
|
-
const sessionId = `session-${
|
|
2315
|
+
const sessionId = `session-${randomUUID2().slice(0, 8)}`;
|
|
2238
2316
|
payload.reviewId = sessionId;
|
|
2239
2317
|
if (diffRef) {
|
|
2240
2318
|
payload.watchMode = true;
|
|
@@ -2295,6 +2373,7 @@ async function handleApiRequest(req, res) {
|
|
|
2295
2373
|
const result = JSON.parse(body);
|
|
2296
2374
|
session.result = result;
|
|
2297
2375
|
session.status = "submitted";
|
|
2376
|
+
recordReviewHistory(session, result);
|
|
2298
2377
|
if (result.decision === "dismissed") {
|
|
2299
2378
|
broadcastSessionRemoved(postResultParams.id);
|
|
2300
2379
|
} else {
|
|
@@ -2360,7 +2439,7 @@ async function handleApiRequest(req, res) {
|
|
|
2360
2439
|
const body = await readBody(req);
|
|
2361
2440
|
const { file, line, body: annotationBody, type, confidence, category, source } = JSON.parse(body);
|
|
2362
2441
|
const annotation = {
|
|
2363
|
-
id:
|
|
2442
|
+
id: randomUUID2(),
|
|
2364
2443
|
sessionId: session.id,
|
|
2365
2444
|
file,
|
|
2366
2445
|
line,
|
|
@@ -2405,6 +2484,10 @@ async function handleApiRequest(req, res) {
|
|
|
2405
2484
|
return true;
|
|
2406
2485
|
}
|
|
2407
2486
|
annotation.dismissed = true;
|
|
2487
|
+
sendToSessionClients(dismissAnnotationParams.id, {
|
|
2488
|
+
type: "annotation:dismissed",
|
|
2489
|
+
payload: { annotationId: dismissAnnotationParams.annotationId }
|
|
2490
|
+
});
|
|
2408
2491
|
jsonResponse(res, 200, { ok: true });
|
|
2409
2492
|
return true;
|
|
2410
2493
|
}
|
|
@@ -2426,6 +2509,10 @@ async function handleApiRequest(req, res) {
|
|
|
2426
2509
|
jsonResponse(res, 404, { error: "Session not found" });
|
|
2427
2510
|
return true;
|
|
2428
2511
|
}
|
|
2512
|
+
if (session.projectPath.startsWith("github:")) {
|
|
2513
|
+
jsonResponse(res, 400, { error: "Ref listing not available for GitHub PRs" });
|
|
2514
|
+
return true;
|
|
2515
|
+
}
|
|
2429
2516
|
try {
|
|
2430
2517
|
const branches = listBranches({ cwd: session.projectPath });
|
|
2431
2518
|
const commits = listCommits({ cwd: session.projectPath });
|
|
@@ -2443,6 +2530,10 @@ async function handleApiRequest(req, res) {
|
|
|
2443
2530
|
jsonResponse(res, 404, { error: "Session not found" });
|
|
2444
2531
|
return true;
|
|
2445
2532
|
}
|
|
2533
|
+
if (session.projectPath.startsWith("github:")) {
|
|
2534
|
+
jsonResponse(res, 400, { error: "Ref comparison not available for GitHub PRs" });
|
|
2535
|
+
return true;
|
|
2536
|
+
}
|
|
2446
2537
|
try {
|
|
2447
2538
|
const body = await readBody(req);
|
|
2448
2539
|
const { ref } = JSON.parse(body);
|
|
@@ -2484,6 +2575,38 @@ async function handleApiRequest(req, res) {
|
|
|
2484
2575
|
}
|
|
2485
2576
|
return true;
|
|
2486
2577
|
}
|
|
2578
|
+
const getSessionHistoryParams = matchRoute(method, url, "GET", "/api/reviews/:id/history");
|
|
2579
|
+
if (getSessionHistoryParams) {
|
|
2580
|
+
const session = sessions2.get(getSessionHistoryParams.id);
|
|
2581
|
+
if (!session) {
|
|
2582
|
+
jsonResponse(res, 404, { error: "Session not found" });
|
|
2583
|
+
return true;
|
|
2584
|
+
}
|
|
2585
|
+
if (session.projectPath.startsWith("github:")) {
|
|
2586
|
+
jsonResponse(res, 200, { history: [] });
|
|
2587
|
+
return true;
|
|
2588
|
+
}
|
|
2589
|
+
const history = getRecentHistory(session.projectPath);
|
|
2590
|
+
jsonResponse(res, 200, { history });
|
|
2591
|
+
return true;
|
|
2592
|
+
}
|
|
2593
|
+
if (method === "GET" && req.url) {
|
|
2594
|
+
const parsedUrl = new URL(req.url, "http://localhost");
|
|
2595
|
+
if (parsedUrl.pathname === "/api/history") {
|
|
2596
|
+
const projectPath = parsedUrl.searchParams.get("project");
|
|
2597
|
+
if (!projectPath) {
|
|
2598
|
+
jsonResponse(res, 400, { error: "Missing required query parameter: project" });
|
|
2599
|
+
return true;
|
|
2600
|
+
}
|
|
2601
|
+
if (projectPath.startsWith("github:")) {
|
|
2602
|
+
jsonResponse(res, 200, { history: [] });
|
|
2603
|
+
return true;
|
|
2604
|
+
}
|
|
2605
|
+
const history = getRecentHistory(projectPath);
|
|
2606
|
+
jsonResponse(res, 200, { history });
|
|
2607
|
+
return true;
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2487
2610
|
jsonResponse(res, 404, { error: "Not found" });
|
|
2488
2611
|
return true;
|
|
2489
2612
|
}
|
|
@@ -2580,6 +2703,7 @@ async function startGlobalServer(options = {}) {
|
|
|
2580
2703
|
if (session) {
|
|
2581
2704
|
session.result = msg.payload;
|
|
2582
2705
|
session.status = "submitted";
|
|
2706
|
+
recordReviewHistory(session, msg.payload);
|
|
2583
2707
|
if (msg.payload.decision === "dismissed") {
|
|
2584
2708
|
broadcastSessionRemoved(sid);
|
|
2585
2709
|
} else {
|
|
@@ -2738,11 +2862,6 @@ Waiting for reviews...
|
|
|
2738
2862
|
return { httpPort, wsPort, stop };
|
|
2739
2863
|
}
|
|
2740
2864
|
|
|
2741
|
-
// packages/core/src/review-history.ts
|
|
2742
|
-
import fs4 from "fs";
|
|
2743
|
-
import path6 from "path";
|
|
2744
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
2745
|
-
|
|
2746
2865
|
// packages/github/src/auth.ts
|
|
2747
2866
|
import { execSync as execSync3 } from "child_process";
|
|
2748
2867
|
import fs5 from "fs";
|
package/dist/mcp-server.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
resolveGitHubToken,
|
|
16
16
|
startReview,
|
|
17
17
|
submitGitHubReview
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-VASCXEMN.js";
|
|
19
19
|
|
|
20
20
|
// packages/mcp-server/src/index.ts
|
|
21
21
|
import fs from "fs";
|
|
@@ -113,11 +113,11 @@ async function reviewViaGlobalServer(serverInfo, diffRef, options) {
|
|
|
113
113
|
async function startMcpServer() {
|
|
114
114
|
const server = new McpServer({
|
|
115
115
|
name: "diffprism",
|
|
116
|
-
version: true ? "0.
|
|
116
|
+
version: true ? "0.34.1" : "0.0.0-dev"
|
|
117
117
|
});
|
|
118
118
|
server.tool(
|
|
119
119
|
"open_review",
|
|
120
|
-
"Open a browser-based code review for local git changes. Blocks until the engineer submits their review decision.",
|
|
120
|
+
"Open a browser-based code review for local git changes. Blocks until the engineer submits their review decision. The result may include a `postReviewAction` field ('commit' or 'commit_and_pr') if the reviewer requested a post-review action.",
|
|
121
121
|
{
|
|
122
122
|
diff_ref: z.string().describe(
|
|
123
123
|
'Git diff reference: "staged", "unstaged", "working-copy" (staged+unstaged grouped), or a ref range like "HEAD~3..HEAD"'
|
|
@@ -781,7 +781,7 @@ async function startMcpServer() {
|
|
|
781
781
|
);
|
|
782
782
|
server.tool(
|
|
783
783
|
"review_pr",
|
|
784
|
-
"Open a browser-based code review for a GitHub pull request. Fetches the PR diff, runs DiffPrism analysis, and opens the review UI. Blocks until the engineer submits their review decision. Optionally posts the review back to GitHub.",
|
|
784
|
+
"Open a browser-based code review for a GitHub pull request. Fetches the PR diff, runs DiffPrism analysis, and opens the review UI. Blocks until the engineer submits their review decision. Optionally posts the review back to GitHub. The result may include a `postReviewAction` field ('commit' or 'commit_and_pr') if the reviewer requested a post-review action.",
|
|
785
785
|
{
|
|
786
786
|
pr: z.string().describe(
|
|
787
787
|
'GitHub PR reference: "owner/repo#123" or "https://github.com/owner/repo/pull/123"'
|
|
@@ -867,7 +867,7 @@ async function startMcpServer() {
|
|
|
867
867
|
injectedPayload: payload
|
|
868
868
|
});
|
|
869
869
|
}
|
|
870
|
-
if (post_to_github && result.decision !== "dismissed") {
|
|
870
|
+
if ((post_to_github || result.postToGithub) && result.decision !== "dismissed") {
|
|
871
871
|
const posted = await submitGitHubReview(client, owner, repo, number, result);
|
|
872
872
|
if (posted) {
|
|
873
873
|
return {
|