diffprism 0.47.0 → 0.48.0
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
CHANGED
|
@@ -5,14 +5,16 @@ import {
|
|
|
5
5
|
} from "./chunk-24B33UN6.js";
|
|
6
6
|
import {
|
|
7
7
|
demo
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SWSRPUXO.js";
|
|
9
9
|
import {
|
|
10
|
+
describeVersion,
|
|
10
11
|
ensureServer,
|
|
12
|
+
getBuildInfo,
|
|
11
13
|
isServerAlive,
|
|
12
14
|
readServerFile,
|
|
13
15
|
startGlobalServer,
|
|
14
16
|
submitReviewToServer
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-AJGESVAM.js";
|
|
16
18
|
import {
|
|
17
19
|
getDiff
|
|
18
20
|
} from "./chunk-QGWYCEJN.js";
|
|
@@ -377,7 +379,7 @@ async function setupInteractive(flags) {
|
|
|
377
379
|
}
|
|
378
380
|
async function runDemo(dev) {
|
|
379
381
|
console.log("");
|
|
380
|
-
const { demo: demo2 } = await import("./demo-
|
|
382
|
+
const { demo: demo2 } = await import("./demo-7GBBKPPB.js");
|
|
381
383
|
await demo2({ dev });
|
|
382
384
|
}
|
|
383
385
|
async function setupBatch(flags) {
|
|
@@ -771,6 +773,10 @@ async function serverStatus() {
|
|
|
771
773
|
console.log(` PID: ${status.pid}`);
|
|
772
774
|
console.log(` Sessions: ${status.sessions}`);
|
|
773
775
|
console.log(` Uptime: ${Math.floor(status.uptime)}s`);
|
|
776
|
+
const build = getBuildInfo();
|
|
777
|
+
if (build.dev) {
|
|
778
|
+
console.log(` Build: dev \u2014 ${build.root}`);
|
|
779
|
+
}
|
|
774
780
|
if (status.sessions > 0) {
|
|
775
781
|
const sessionsResponse = await fetch(
|
|
776
782
|
`http://localhost:${info.httpPort}/api/reviews`,
|
|
@@ -820,7 +826,7 @@ async function fetchStatus(httpPort) {
|
|
|
820
826
|
return await response.json();
|
|
821
827
|
}
|
|
822
828
|
function printStatus(status, httpPort) {
|
|
823
|
-
const version = true ? "0.
|
|
829
|
+
const version = true ? "0.48.0" : "0.0.0-dev";
|
|
824
830
|
console.log(`
|
|
825
831
|
DiffPrism v${version}
|
|
826
832
|
`);
|
|
@@ -1042,7 +1048,11 @@ function fail(text) {
|
|
|
1042
1048
|
|
|
1043
1049
|
// cli/src/index.ts
|
|
1044
1050
|
var program = new Command();
|
|
1045
|
-
program.name("diffprism").description("Local-first code review tool for agent-generated changes").version(
|
|
1051
|
+
program.name("diffprism").description("Local-first code review tool for agent-generated changes").version(
|
|
1052
|
+
describeVersion(
|
|
1053
|
+
true ? "0.48.0" : "0.0.0-dev"
|
|
1054
|
+
)
|
|
1055
|
+
);
|
|
1046
1056
|
program.action(defaultAction);
|
|
1047
1057
|
program.command("demo").description("Open a sample review to see DiffPrism in action").option("--dev", "Use Vite dev server").action(demo);
|
|
1048
1058
|
program.command("review [ref]").description("Open a browser-based diff review (local git ref or GitHub PR ref like owner/repo#123)").option("--staged", "Review staged changes").option("--unstaged", "Review unstaged changes").option("-t, --title <title>", "Review title").option("--reasoning <text>", "Agent reasoning about the changes").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(review);
|
|
@@ -266,6 +266,27 @@ async function submitReviewToServer(serverInfo, diffRef, options = {}) {
|
|
|
266
266
|
throw new Error("Review timed out waiting for submission.");
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
// packages/core/src/build-info.ts
|
|
270
|
+
import fs3 from "fs";
|
|
271
|
+
import path3 from "path";
|
|
272
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
273
|
+
function getBuildInfo() {
|
|
274
|
+
let dir = path3.dirname(fileURLToPath2(import.meta.url));
|
|
275
|
+
while (dir !== path3.dirname(dir)) {
|
|
276
|
+
if (fs3.existsSync(path3.join(dir, "package.json"))) {
|
|
277
|
+
if (fs3.existsSync(path3.join(dir, ".git"))) {
|
|
278
|
+
return { dev: true, root: dir };
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
dir = path3.dirname(dir);
|
|
282
|
+
}
|
|
283
|
+
return { dev: false, root: null };
|
|
284
|
+
}
|
|
285
|
+
function describeVersion(version) {
|
|
286
|
+
const info = getBuildInfo();
|
|
287
|
+
return info.dev ? `${version} (dev build \u2014 ${info.root})` : version;
|
|
288
|
+
}
|
|
289
|
+
|
|
269
290
|
// packages/core/src/diff-utils.ts
|
|
270
291
|
import { createHash } from "crypto";
|
|
271
292
|
function hashDiff(rawDiff) {
|
|
@@ -370,13 +391,13 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
370
391
|
import getPort from "get-port";
|
|
371
392
|
import open from "open";
|
|
372
393
|
import { WebSocketServer, WebSocket } from "ws";
|
|
373
|
-
import
|
|
394
|
+
import fs6 from "fs";
|
|
374
395
|
|
|
375
396
|
// packages/core/src/ui-server.ts
|
|
376
397
|
import http from "http";
|
|
377
|
-
import
|
|
378
|
-
import
|
|
379
|
-
import { fileURLToPath as
|
|
398
|
+
import fs4 from "fs";
|
|
399
|
+
import path4 from "path";
|
|
400
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
380
401
|
var MIME_TYPES = {
|
|
381
402
|
".html": "text/html",
|
|
382
403
|
".js": "application/javascript",
|
|
@@ -389,15 +410,15 @@ var MIME_TYPES = {
|
|
|
389
410
|
".woff2": "font/woff2"
|
|
390
411
|
};
|
|
391
412
|
function resolveUiDist() {
|
|
392
|
-
const thisFile =
|
|
393
|
-
const thisDir =
|
|
394
|
-
const publishedUiDist =
|
|
395
|
-
if (
|
|
413
|
+
const thisFile = fileURLToPath3(import.meta.url);
|
|
414
|
+
const thisDir = path4.dirname(thisFile);
|
|
415
|
+
const publishedUiDist = path4.resolve(thisDir, "..", "ui-dist");
|
|
416
|
+
if (fs4.existsSync(path4.join(publishedUiDist, "index.html"))) {
|
|
396
417
|
return publishedUiDist;
|
|
397
418
|
}
|
|
398
|
-
const workspaceRoot =
|
|
399
|
-
const devUiDist =
|
|
400
|
-
if (
|
|
419
|
+
const workspaceRoot = path4.resolve(thisDir, "..", "..", "..");
|
|
420
|
+
const devUiDist = path4.join(workspaceRoot, "packages", "ui", "dist");
|
|
421
|
+
if (fs4.existsSync(path4.join(devUiDist, "index.html"))) {
|
|
401
422
|
return devUiDist;
|
|
402
423
|
}
|
|
403
424
|
throw new Error(
|
|
@@ -405,11 +426,11 @@ function resolveUiDist() {
|
|
|
405
426
|
);
|
|
406
427
|
}
|
|
407
428
|
function resolveUiRoot() {
|
|
408
|
-
const thisFile =
|
|
409
|
-
const thisDir =
|
|
410
|
-
const workspaceRoot =
|
|
411
|
-
const uiRoot =
|
|
412
|
-
if (
|
|
429
|
+
const thisFile = fileURLToPath3(import.meta.url);
|
|
430
|
+
const thisDir = path4.dirname(thisFile);
|
|
431
|
+
const workspaceRoot = path4.resolve(thisDir, "..", "..", "..");
|
|
432
|
+
const uiRoot = path4.join(workspaceRoot, "packages", "ui");
|
|
433
|
+
if (fs4.existsSync(path4.join(uiRoot, "index.html"))) {
|
|
413
434
|
return uiRoot;
|
|
414
435
|
}
|
|
415
436
|
throw new Error(
|
|
@@ -429,14 +450,14 @@ async function startViteDevServer(uiRoot, port, silent) {
|
|
|
429
450
|
function createStaticServer(distPath, port) {
|
|
430
451
|
const server = http.createServer((req, res) => {
|
|
431
452
|
const urlPath = req.url?.split("?")[0] ?? "/";
|
|
432
|
-
let filePath =
|
|
433
|
-
if (!
|
|
434
|
-
filePath =
|
|
453
|
+
let filePath = path4.join(distPath, urlPath === "/" ? "index.html" : urlPath);
|
|
454
|
+
if (!fs4.existsSync(filePath)) {
|
|
455
|
+
filePath = path4.join(distPath, "index.html");
|
|
435
456
|
}
|
|
436
|
-
const ext =
|
|
457
|
+
const ext = path4.extname(filePath);
|
|
437
458
|
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
438
459
|
try {
|
|
439
|
-
const content =
|
|
460
|
+
const content = fs4.readFileSync(filePath);
|
|
440
461
|
res.writeHead(200, { "Content-Type": contentType });
|
|
441
462
|
res.end(content);
|
|
442
463
|
} catch {
|
|
@@ -451,22 +472,22 @@ function createStaticServer(distPath, port) {
|
|
|
451
472
|
}
|
|
452
473
|
|
|
453
474
|
// packages/core/src/review-history.ts
|
|
454
|
-
import
|
|
455
|
-
import
|
|
475
|
+
import fs5 from "fs";
|
|
476
|
+
import path5 from "path";
|
|
456
477
|
import { randomUUID } from "crypto";
|
|
457
478
|
function generateEntryId() {
|
|
458
479
|
return randomUUID();
|
|
459
480
|
}
|
|
460
481
|
function getHistoryPath(projectDir) {
|
|
461
|
-
return
|
|
482
|
+
return path5.join(projectDir, ".diffprism", "history", "reviews.json");
|
|
462
483
|
}
|
|
463
484
|
function readHistory(projectDir) {
|
|
464
485
|
const filePath = getHistoryPath(projectDir);
|
|
465
|
-
if (!
|
|
486
|
+
if (!fs5.existsSync(filePath)) {
|
|
466
487
|
return { version: 1, entries: [] };
|
|
467
488
|
}
|
|
468
489
|
try {
|
|
469
|
-
const raw =
|
|
490
|
+
const raw = fs5.readFileSync(filePath, "utf-8");
|
|
470
491
|
const parsed = JSON.parse(raw);
|
|
471
492
|
return parsed;
|
|
472
493
|
} catch {
|
|
@@ -475,14 +496,14 @@ function readHistory(projectDir) {
|
|
|
475
496
|
}
|
|
476
497
|
function appendHistory(projectDir, entry) {
|
|
477
498
|
const filePath = getHistoryPath(projectDir);
|
|
478
|
-
const dir =
|
|
479
|
-
if (!
|
|
480
|
-
|
|
499
|
+
const dir = path5.dirname(filePath);
|
|
500
|
+
if (!fs5.existsSync(dir)) {
|
|
501
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
481
502
|
}
|
|
482
503
|
const history = readHistory(projectDir);
|
|
483
504
|
history.entries.push(entry);
|
|
484
505
|
history.entries.sort((a, b) => a.timestamp - b.timestamp);
|
|
485
|
-
|
|
506
|
+
fs5.writeFileSync(filePath, JSON.stringify(history, null, 2) + "\n");
|
|
486
507
|
}
|
|
487
508
|
function getRecentHistory(projectDir, limit = 50) {
|
|
488
509
|
const history = readHistory(projectDir);
|
|
@@ -686,12 +707,12 @@ function recordReviewHistory(session, result) {
|
|
|
686
707
|
function isInsideGitRepo(dirPath) {
|
|
687
708
|
let current = dirPath;
|
|
688
709
|
while (current !== "/") {
|
|
689
|
-
if (
|
|
710
|
+
if (fs6.existsSync(`${current}/.git`)) return true;
|
|
690
711
|
const parent = current.replace(/\/[^/]+$/, "") || "/";
|
|
691
712
|
if (parent === current) break;
|
|
692
713
|
current = parent;
|
|
693
714
|
}
|
|
694
|
-
return
|
|
715
|
+
return fs6.existsSync(`${current}/.git`);
|
|
695
716
|
}
|
|
696
717
|
async function handleApiRequest(req, res) {
|
|
697
718
|
const method = req.method ?? "GET";
|
|
@@ -802,7 +823,7 @@ async function handleApiRequest(req, res) {
|
|
|
802
823
|
return true;
|
|
803
824
|
}
|
|
804
825
|
try {
|
|
805
|
-
const stat =
|
|
826
|
+
const stat = fs6.statSync(projectPath);
|
|
806
827
|
if (!stat.isDirectory()) {
|
|
807
828
|
jsonResponse(res, 400, { error: "Path is not a directory" });
|
|
808
829
|
return true;
|
|
@@ -961,7 +982,7 @@ async function handleApiRequest(req, res) {
|
|
|
961
982
|
if (parsedUrl.pathname === "/api/fs/list") {
|
|
962
983
|
const dirPath = parsedUrl.searchParams.get("path") || process.cwd();
|
|
963
984
|
try {
|
|
964
|
-
const stat =
|
|
985
|
+
const stat = fs6.statSync(dirPath);
|
|
965
986
|
if (!stat.isDirectory()) {
|
|
966
987
|
jsonResponse(res, 400, { error: "Not a directory" });
|
|
967
988
|
return true;
|
|
@@ -971,13 +992,13 @@ async function handleApiRequest(req, res) {
|
|
|
971
992
|
return true;
|
|
972
993
|
}
|
|
973
994
|
try {
|
|
974
|
-
const entries =
|
|
995
|
+
const entries = fs6.readdirSync(dirPath, { withFileTypes: true });
|
|
975
996
|
const dirs = [];
|
|
976
997
|
for (const entry of entries) {
|
|
977
998
|
if (!entry.isDirectory()) continue;
|
|
978
999
|
if (entry.name.startsWith(".")) continue;
|
|
979
1000
|
const fullPath = `${dirPath}/${entry.name}`;
|
|
980
|
-
const isGitRepo2 =
|
|
1001
|
+
const isGitRepo2 = fs6.existsSync(`${fullPath}/.git`);
|
|
981
1002
|
dirs.push({ name: entry.name, path: fullPath, isGitRepo: isGitRepo2 });
|
|
982
1003
|
}
|
|
983
1004
|
dirs.sort((a, b) => {
|
|
@@ -1565,5 +1586,7 @@ export {
|
|
|
1565
1586
|
isServerAlive,
|
|
1566
1587
|
startGlobalServer,
|
|
1567
1588
|
ensureServer,
|
|
1568
|
-
submitReviewToServer
|
|
1589
|
+
submitReviewToServer,
|
|
1590
|
+
getBuildInfo,
|
|
1591
|
+
describeVersion
|
|
1569
1592
|
};
|
package/dist/mcp-server.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
ensureServer,
|
|
7
7
|
isServerAlive,
|
|
8
8
|
submitReviewToServer
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-AJGESVAM.js";
|
|
10
10
|
import {
|
|
11
11
|
getDiff
|
|
12
12
|
} from "./chunk-QGWYCEJN.js";
|
|
@@ -144,7 +144,7 @@ async function handlePrReview(pr, options) {
|
|
|
144
144
|
async function startMcpServer() {
|
|
145
145
|
const server = new McpServer({
|
|
146
146
|
name: "diffprism",
|
|
147
|
-
version: true ? "0.
|
|
147
|
+
version: true ? "0.48.0" : "0.0.0-dev"
|
|
148
148
|
});
|
|
149
149
|
server.tool(
|
|
150
150
|
"open_review",
|