diffprism 0.47.0 → 0.48.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
CHANGED
|
@@ -5,14 +5,16 @@ import {
|
|
|
5
5
|
} from "./chunk-24B33UN6.js";
|
|
6
6
|
import {
|
|
7
7
|
demo
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-7UQM4WBZ.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-EPUCA2N5.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-VPKUCZT3.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.1" : "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.1" : "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,34 @@ 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
|
+
const manifest = path3.join(dir, "package.json");
|
|
277
|
+
if (fs3.existsSync(manifest) && isOwnManifest(manifest)) {
|
|
278
|
+
return fs3.existsSync(path3.join(dir, ".git")) ? { dev: true, root: dir } : { dev: false, root: null };
|
|
279
|
+
}
|
|
280
|
+
dir = path3.dirname(dir);
|
|
281
|
+
}
|
|
282
|
+
return { dev: false, root: null };
|
|
283
|
+
}
|
|
284
|
+
function isOwnManifest(manifestPath) {
|
|
285
|
+
try {
|
|
286
|
+
const manifest = JSON.parse(fs3.readFileSync(manifestPath, "utf8"));
|
|
287
|
+
return manifest.name === "diffprism";
|
|
288
|
+
} catch {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function describeVersion(version) {
|
|
293
|
+
const info = getBuildInfo();
|
|
294
|
+
return info.dev ? `${version} (dev build \u2014 ${info.root})` : version;
|
|
295
|
+
}
|
|
296
|
+
|
|
269
297
|
// packages/core/src/diff-utils.ts
|
|
270
298
|
import { createHash } from "crypto";
|
|
271
299
|
function hashDiff(rawDiff) {
|
|
@@ -370,13 +398,13 @@ import { randomUUID as randomUUID2 } from "crypto";
|
|
|
370
398
|
import getPort from "get-port";
|
|
371
399
|
import open from "open";
|
|
372
400
|
import { WebSocketServer, WebSocket } from "ws";
|
|
373
|
-
import
|
|
401
|
+
import fs6 from "fs";
|
|
374
402
|
|
|
375
403
|
// packages/core/src/ui-server.ts
|
|
376
404
|
import http from "http";
|
|
377
|
-
import
|
|
378
|
-
import
|
|
379
|
-
import { fileURLToPath as
|
|
405
|
+
import fs4 from "fs";
|
|
406
|
+
import path4 from "path";
|
|
407
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
380
408
|
var MIME_TYPES = {
|
|
381
409
|
".html": "text/html",
|
|
382
410
|
".js": "application/javascript",
|
|
@@ -389,15 +417,15 @@ var MIME_TYPES = {
|
|
|
389
417
|
".woff2": "font/woff2"
|
|
390
418
|
};
|
|
391
419
|
function resolveUiDist() {
|
|
392
|
-
const thisFile =
|
|
393
|
-
const thisDir =
|
|
394
|
-
const publishedUiDist =
|
|
395
|
-
if (
|
|
420
|
+
const thisFile = fileURLToPath3(import.meta.url);
|
|
421
|
+
const thisDir = path4.dirname(thisFile);
|
|
422
|
+
const publishedUiDist = path4.resolve(thisDir, "..", "ui-dist");
|
|
423
|
+
if (fs4.existsSync(path4.join(publishedUiDist, "index.html"))) {
|
|
396
424
|
return publishedUiDist;
|
|
397
425
|
}
|
|
398
|
-
const workspaceRoot =
|
|
399
|
-
const devUiDist =
|
|
400
|
-
if (
|
|
426
|
+
const workspaceRoot = path4.resolve(thisDir, "..", "..", "..");
|
|
427
|
+
const devUiDist = path4.join(workspaceRoot, "packages", "ui", "dist");
|
|
428
|
+
if (fs4.existsSync(path4.join(devUiDist, "index.html"))) {
|
|
401
429
|
return devUiDist;
|
|
402
430
|
}
|
|
403
431
|
throw new Error(
|
|
@@ -405,11 +433,11 @@ function resolveUiDist() {
|
|
|
405
433
|
);
|
|
406
434
|
}
|
|
407
435
|
function resolveUiRoot() {
|
|
408
|
-
const thisFile =
|
|
409
|
-
const thisDir =
|
|
410
|
-
const workspaceRoot =
|
|
411
|
-
const uiRoot =
|
|
412
|
-
if (
|
|
436
|
+
const thisFile = fileURLToPath3(import.meta.url);
|
|
437
|
+
const thisDir = path4.dirname(thisFile);
|
|
438
|
+
const workspaceRoot = path4.resolve(thisDir, "..", "..", "..");
|
|
439
|
+
const uiRoot = path4.join(workspaceRoot, "packages", "ui");
|
|
440
|
+
if (fs4.existsSync(path4.join(uiRoot, "index.html"))) {
|
|
413
441
|
return uiRoot;
|
|
414
442
|
}
|
|
415
443
|
throw new Error(
|
|
@@ -429,14 +457,14 @@ async function startViteDevServer(uiRoot, port, silent) {
|
|
|
429
457
|
function createStaticServer(distPath, port) {
|
|
430
458
|
const server = http.createServer((req, res) => {
|
|
431
459
|
const urlPath = req.url?.split("?")[0] ?? "/";
|
|
432
|
-
let filePath =
|
|
433
|
-
if (!
|
|
434
|
-
filePath =
|
|
460
|
+
let filePath = path4.join(distPath, urlPath === "/" ? "index.html" : urlPath);
|
|
461
|
+
if (!fs4.existsSync(filePath)) {
|
|
462
|
+
filePath = path4.join(distPath, "index.html");
|
|
435
463
|
}
|
|
436
|
-
const ext =
|
|
464
|
+
const ext = path4.extname(filePath);
|
|
437
465
|
const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
|
|
438
466
|
try {
|
|
439
|
-
const content =
|
|
467
|
+
const content = fs4.readFileSync(filePath);
|
|
440
468
|
res.writeHead(200, { "Content-Type": contentType });
|
|
441
469
|
res.end(content);
|
|
442
470
|
} catch {
|
|
@@ -451,22 +479,22 @@ function createStaticServer(distPath, port) {
|
|
|
451
479
|
}
|
|
452
480
|
|
|
453
481
|
// packages/core/src/review-history.ts
|
|
454
|
-
import
|
|
455
|
-
import
|
|
482
|
+
import fs5 from "fs";
|
|
483
|
+
import path5 from "path";
|
|
456
484
|
import { randomUUID } from "crypto";
|
|
457
485
|
function generateEntryId() {
|
|
458
486
|
return randomUUID();
|
|
459
487
|
}
|
|
460
488
|
function getHistoryPath(projectDir) {
|
|
461
|
-
return
|
|
489
|
+
return path5.join(projectDir, ".diffprism", "history", "reviews.json");
|
|
462
490
|
}
|
|
463
491
|
function readHistory(projectDir) {
|
|
464
492
|
const filePath = getHistoryPath(projectDir);
|
|
465
|
-
if (!
|
|
493
|
+
if (!fs5.existsSync(filePath)) {
|
|
466
494
|
return { version: 1, entries: [] };
|
|
467
495
|
}
|
|
468
496
|
try {
|
|
469
|
-
const raw =
|
|
497
|
+
const raw = fs5.readFileSync(filePath, "utf-8");
|
|
470
498
|
const parsed = JSON.parse(raw);
|
|
471
499
|
return parsed;
|
|
472
500
|
} catch {
|
|
@@ -475,14 +503,14 @@ function readHistory(projectDir) {
|
|
|
475
503
|
}
|
|
476
504
|
function appendHistory(projectDir, entry) {
|
|
477
505
|
const filePath = getHistoryPath(projectDir);
|
|
478
|
-
const dir =
|
|
479
|
-
if (!
|
|
480
|
-
|
|
506
|
+
const dir = path5.dirname(filePath);
|
|
507
|
+
if (!fs5.existsSync(dir)) {
|
|
508
|
+
fs5.mkdirSync(dir, { recursive: true });
|
|
481
509
|
}
|
|
482
510
|
const history = readHistory(projectDir);
|
|
483
511
|
history.entries.push(entry);
|
|
484
512
|
history.entries.sort((a, b) => a.timestamp - b.timestamp);
|
|
485
|
-
|
|
513
|
+
fs5.writeFileSync(filePath, JSON.stringify(history, null, 2) + "\n");
|
|
486
514
|
}
|
|
487
515
|
function getRecentHistory(projectDir, limit = 50) {
|
|
488
516
|
const history = readHistory(projectDir);
|
|
@@ -686,12 +714,12 @@ function recordReviewHistory(session, result) {
|
|
|
686
714
|
function isInsideGitRepo(dirPath) {
|
|
687
715
|
let current = dirPath;
|
|
688
716
|
while (current !== "/") {
|
|
689
|
-
if (
|
|
717
|
+
if (fs6.existsSync(`${current}/.git`)) return true;
|
|
690
718
|
const parent = current.replace(/\/[^/]+$/, "") || "/";
|
|
691
719
|
if (parent === current) break;
|
|
692
720
|
current = parent;
|
|
693
721
|
}
|
|
694
|
-
return
|
|
722
|
+
return fs6.existsSync(`${current}/.git`);
|
|
695
723
|
}
|
|
696
724
|
async function handleApiRequest(req, res) {
|
|
697
725
|
const method = req.method ?? "GET";
|
|
@@ -802,7 +830,7 @@ async function handleApiRequest(req, res) {
|
|
|
802
830
|
return true;
|
|
803
831
|
}
|
|
804
832
|
try {
|
|
805
|
-
const stat =
|
|
833
|
+
const stat = fs6.statSync(projectPath);
|
|
806
834
|
if (!stat.isDirectory()) {
|
|
807
835
|
jsonResponse(res, 400, { error: "Path is not a directory" });
|
|
808
836
|
return true;
|
|
@@ -961,7 +989,7 @@ async function handleApiRequest(req, res) {
|
|
|
961
989
|
if (parsedUrl.pathname === "/api/fs/list") {
|
|
962
990
|
const dirPath = parsedUrl.searchParams.get("path") || process.cwd();
|
|
963
991
|
try {
|
|
964
|
-
const stat =
|
|
992
|
+
const stat = fs6.statSync(dirPath);
|
|
965
993
|
if (!stat.isDirectory()) {
|
|
966
994
|
jsonResponse(res, 400, { error: "Not a directory" });
|
|
967
995
|
return true;
|
|
@@ -971,13 +999,13 @@ async function handleApiRequest(req, res) {
|
|
|
971
999
|
return true;
|
|
972
1000
|
}
|
|
973
1001
|
try {
|
|
974
|
-
const entries =
|
|
1002
|
+
const entries = fs6.readdirSync(dirPath, { withFileTypes: true });
|
|
975
1003
|
const dirs = [];
|
|
976
1004
|
for (const entry of entries) {
|
|
977
1005
|
if (!entry.isDirectory()) continue;
|
|
978
1006
|
if (entry.name.startsWith(".")) continue;
|
|
979
1007
|
const fullPath = `${dirPath}/${entry.name}`;
|
|
980
|
-
const isGitRepo2 =
|
|
1008
|
+
const isGitRepo2 = fs6.existsSync(`${fullPath}/.git`);
|
|
981
1009
|
dirs.push({ name: entry.name, path: fullPath, isGitRepo: isGitRepo2 });
|
|
982
1010
|
}
|
|
983
1011
|
dirs.sort((a, b) => {
|
|
@@ -1565,5 +1593,7 @@ export {
|
|
|
1565
1593
|
isServerAlive,
|
|
1566
1594
|
startGlobalServer,
|
|
1567
1595
|
ensureServer,
|
|
1568
|
-
submitReviewToServer
|
|
1596
|
+
submitReviewToServer,
|
|
1597
|
+
getBuildInfo,
|
|
1598
|
+
describeVersion
|
|
1569
1599
|
};
|
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-EPUCA2N5.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.1" : "0.0.0-dev"
|
|
148
148
|
});
|
|
149
149
|
server.tool(
|
|
150
150
|
"open_review",
|