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-TZ5SGWHP.js";
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-PQWU5NW4.js";
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-H2NAMKCT.js");
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.47.0" : "0.0.0-dev";
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(true ? "0.47.0" : "0.0.0-dev");
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 fs5 from "fs";
394
+ import fs6 from "fs";
374
395
 
375
396
  // packages/core/src/ui-server.ts
376
397
  import http from "http";
377
- import fs3 from "fs";
378
- import path3 from "path";
379
- import { fileURLToPath as fileURLToPath2 } from "url";
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 = fileURLToPath2(import.meta.url);
393
- const thisDir = path3.dirname(thisFile);
394
- const publishedUiDist = path3.resolve(thisDir, "..", "ui-dist");
395
- if (fs3.existsSync(path3.join(publishedUiDist, "index.html"))) {
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 = path3.resolve(thisDir, "..", "..", "..");
399
- const devUiDist = path3.join(workspaceRoot, "packages", "ui", "dist");
400
- if (fs3.existsSync(path3.join(devUiDist, "index.html"))) {
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 = fileURLToPath2(import.meta.url);
409
- const thisDir = path3.dirname(thisFile);
410
- const workspaceRoot = path3.resolve(thisDir, "..", "..", "..");
411
- const uiRoot = path3.join(workspaceRoot, "packages", "ui");
412
- if (fs3.existsSync(path3.join(uiRoot, "index.html"))) {
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 = path3.join(distPath, urlPath === "/" ? "index.html" : urlPath);
433
- if (!fs3.existsSync(filePath)) {
434
- filePath = path3.join(distPath, "index.html");
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 = path3.extname(filePath);
457
+ const ext = path4.extname(filePath);
437
458
  const contentType = MIME_TYPES[ext] ?? "application/octet-stream";
438
459
  try {
439
- const content = fs3.readFileSync(filePath);
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 fs4 from "fs";
455
- import path4 from "path";
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 path4.join(projectDir, ".diffprism", "history", "reviews.json");
482
+ return path5.join(projectDir, ".diffprism", "history", "reviews.json");
462
483
  }
463
484
  function readHistory(projectDir) {
464
485
  const filePath = getHistoryPath(projectDir);
465
- if (!fs4.existsSync(filePath)) {
486
+ if (!fs5.existsSync(filePath)) {
466
487
  return { version: 1, entries: [] };
467
488
  }
468
489
  try {
469
- const raw = fs4.readFileSync(filePath, "utf-8");
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 = path4.dirname(filePath);
479
- if (!fs4.existsSync(dir)) {
480
- fs4.mkdirSync(dir, { recursive: true });
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
- fs4.writeFileSync(filePath, JSON.stringify(history, null, 2) + "\n");
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 (fs5.existsSync(`${current}/.git`)) return true;
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 fs5.existsSync(`${current}/.git`);
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 = fs5.statSync(projectPath);
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 = fs5.statSync(dirPath);
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 = fs5.readdirSync(dirPath, { withFileTypes: true });
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 = fs5.existsSync(`${fullPath}/.git`);
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
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ensureServer,
3
3
  submitReviewToServer
4
- } from "./chunk-PQWU5NW4.js";
4
+ } from "./chunk-AJGESVAM.js";
5
5
  import {
6
6
  parseDiff
7
7
  } from "./chunk-QGWYCEJN.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  demo
3
- } from "./chunk-TZ5SGWHP.js";
4
- import "./chunk-PQWU5NW4.js";
3
+ } from "./chunk-SWSRPUXO.js";
4
+ import "./chunk-AJGESVAM.js";
5
5
  import "./chunk-QGWYCEJN.js";
6
6
  import "./chunk-DHCVZGHE.js";
7
7
  import "./chunk-JSBRDJBE.js";
@@ -6,7 +6,7 @@ import {
6
6
  ensureServer,
7
7
  isServerAlive,
8
8
  submitReviewToServer
9
- } from "./chunk-PQWU5NW4.js";
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.47.0" : "0.0.0-dev"
147
+ version: true ? "0.48.0" : "0.0.0-dev"
148
148
  });
149
149
  server.tool(
150
150
  "open_review",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "diffprism",
3
- "version": "0.47.0",
3
+ "version": "0.48.0",
4
4
  "type": "module",
5
5
  "description": "Local-first code review tool for agent-generated code changes",
6
6
  "bin": {