diffprism 0.19.0 → 0.20.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 +199 -1
- package/dist/mcp-server.js +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -427,6 +427,201 @@ function isGlobalSetupDone() {
|
|
|
427
427
|
return toolNames.every((t) => allow.includes(t));
|
|
428
428
|
}
|
|
429
429
|
|
|
430
|
+
// cli/src/commands/teardown.ts
|
|
431
|
+
import fs2 from "fs";
|
|
432
|
+
import path2 from "path";
|
|
433
|
+
import os2 from "os";
|
|
434
|
+
function teardownMcpJson(gitRoot) {
|
|
435
|
+
const filePath = path2.join(gitRoot, ".mcp.json");
|
|
436
|
+
if (!fs2.existsSync(filePath)) {
|
|
437
|
+
return { action: "skipped", filePath };
|
|
438
|
+
}
|
|
439
|
+
const existing = readJsonFile(filePath);
|
|
440
|
+
const servers = existing.mcpServers ?? {};
|
|
441
|
+
if (!servers.diffprism) {
|
|
442
|
+
return { action: "skipped", filePath };
|
|
443
|
+
}
|
|
444
|
+
delete servers.diffprism;
|
|
445
|
+
if (Object.keys(servers).length === 0) {
|
|
446
|
+
const { mcpServers: _, ...rest } = existing;
|
|
447
|
+
if (Object.keys(rest).length === 0) {
|
|
448
|
+
fs2.unlinkSync(filePath);
|
|
449
|
+
} else {
|
|
450
|
+
writeJsonFile(filePath, rest);
|
|
451
|
+
}
|
|
452
|
+
} else {
|
|
453
|
+
writeJsonFile(filePath, { ...existing, mcpServers: servers });
|
|
454
|
+
}
|
|
455
|
+
return { action: "removed", filePath };
|
|
456
|
+
}
|
|
457
|
+
function teardownClaudePermissions(baseDir) {
|
|
458
|
+
const filePath = path2.join(baseDir, ".claude", "settings.json");
|
|
459
|
+
if (!fs2.existsSync(filePath)) {
|
|
460
|
+
return { action: "skipped", filePath };
|
|
461
|
+
}
|
|
462
|
+
const existing = readJsonFile(filePath);
|
|
463
|
+
const permissions = existing.permissions ?? {};
|
|
464
|
+
const allow = permissions.allow ?? [];
|
|
465
|
+
const toolNames = [
|
|
466
|
+
"mcp__diffprism__open_review",
|
|
467
|
+
"mcp__diffprism__update_review_context",
|
|
468
|
+
"mcp__diffprism__get_review_result"
|
|
469
|
+
];
|
|
470
|
+
const filtered = allow.filter((t) => !toolNames.includes(t));
|
|
471
|
+
if (filtered.length === allow.length) {
|
|
472
|
+
return { action: "skipped", filePath };
|
|
473
|
+
}
|
|
474
|
+
if (filtered.length > 0) {
|
|
475
|
+
permissions.allow = filtered;
|
|
476
|
+
} else {
|
|
477
|
+
delete permissions.allow;
|
|
478
|
+
}
|
|
479
|
+
if (Object.keys(permissions).length === 0) {
|
|
480
|
+
delete existing.permissions;
|
|
481
|
+
} else {
|
|
482
|
+
existing.permissions = permissions;
|
|
483
|
+
}
|
|
484
|
+
writeJsonFile(filePath, existing);
|
|
485
|
+
return { action: "removed", filePath };
|
|
486
|
+
}
|
|
487
|
+
function teardownHooks(gitRoot) {
|
|
488
|
+
const filePath = path2.join(gitRoot, ".claude", "settings.json");
|
|
489
|
+
const result = cleanDiffprismHooks(gitRoot);
|
|
490
|
+
if (result.removed > 0) {
|
|
491
|
+
const existing = readJsonFile(filePath);
|
|
492
|
+
const hooks = existing.hooks;
|
|
493
|
+
if (hooks && Object.keys(hooks).length === 0) {
|
|
494
|
+
delete existing.hooks;
|
|
495
|
+
writeJsonFile(filePath, existing);
|
|
496
|
+
}
|
|
497
|
+
return { action: "removed", filePath: filePath + " (hooks)" };
|
|
498
|
+
}
|
|
499
|
+
return { action: "skipped", filePath: filePath + " (hooks)" };
|
|
500
|
+
}
|
|
501
|
+
function cleanupSettingsFile(baseDir) {
|
|
502
|
+
const filePath = path2.join(baseDir, ".claude", "settings.json");
|
|
503
|
+
if (!fs2.existsSync(filePath)) return;
|
|
504
|
+
const existing = readJsonFile(filePath);
|
|
505
|
+
if (Object.keys(existing).length === 0) {
|
|
506
|
+
fs2.unlinkSync(filePath);
|
|
507
|
+
tryRmdir(path2.join(baseDir, ".claude"));
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function tryRmdir(dirPath) {
|
|
511
|
+
try {
|
|
512
|
+
const entries = fs2.readdirSync(dirPath);
|
|
513
|
+
if (entries.length === 0) {
|
|
514
|
+
fs2.rmdirSync(dirPath);
|
|
515
|
+
}
|
|
516
|
+
} catch {
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
function teardownSkill(baseDir, global) {
|
|
520
|
+
const skillDir = global ? path2.join(os2.homedir(), ".claude", "skills", "review") : path2.join(baseDir, ".claude", "skills", "review");
|
|
521
|
+
const filePath = path2.join(skillDir, "SKILL.md");
|
|
522
|
+
if (!fs2.existsSync(filePath)) {
|
|
523
|
+
return { action: "skipped", filePath };
|
|
524
|
+
}
|
|
525
|
+
fs2.unlinkSync(filePath);
|
|
526
|
+
tryRmdir(skillDir);
|
|
527
|
+
tryRmdir(path2.dirname(skillDir));
|
|
528
|
+
return { action: "removed", filePath };
|
|
529
|
+
}
|
|
530
|
+
function teardownGitignore(gitRoot) {
|
|
531
|
+
const filePath = path2.join(gitRoot, ".gitignore");
|
|
532
|
+
if (!fs2.existsSync(filePath)) {
|
|
533
|
+
return { action: "skipped", filePath };
|
|
534
|
+
}
|
|
535
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
536
|
+
const lines = content.split("\n");
|
|
537
|
+
const filtered = lines.filter((l) => l.trim() !== ".diffprism");
|
|
538
|
+
if (filtered.length === lines.length) {
|
|
539
|
+
return { action: "skipped", filePath };
|
|
540
|
+
}
|
|
541
|
+
const newContent = filtered.join("\n");
|
|
542
|
+
if (newContent.trim() === "") {
|
|
543
|
+
fs2.unlinkSync(filePath);
|
|
544
|
+
} else {
|
|
545
|
+
fs2.writeFileSync(filePath, newContent);
|
|
546
|
+
}
|
|
547
|
+
return { action: "removed", filePath };
|
|
548
|
+
}
|
|
549
|
+
function teardownDiffprismDir(gitRoot) {
|
|
550
|
+
const dirPath = path2.join(gitRoot, ".diffprism");
|
|
551
|
+
if (!fs2.existsSync(dirPath)) {
|
|
552
|
+
return { action: "skipped", filePath: dirPath };
|
|
553
|
+
}
|
|
554
|
+
fs2.rmSync(dirPath, { recursive: true });
|
|
555
|
+
return { action: "removed", filePath: dirPath };
|
|
556
|
+
}
|
|
557
|
+
async function teardown(flags) {
|
|
558
|
+
const global = flags.global ?? false;
|
|
559
|
+
const quiet = flags.quiet ?? false;
|
|
560
|
+
const home = os2.homedir();
|
|
561
|
+
const result = { removed: [], skipped: [] };
|
|
562
|
+
if (global) {
|
|
563
|
+
if (!quiet) {
|
|
564
|
+
console.log("Tearing down DiffPrism global configuration...\n");
|
|
565
|
+
}
|
|
566
|
+
const skill2 = teardownSkill("", true);
|
|
567
|
+
result[skill2.action].push(skill2.filePath);
|
|
568
|
+
const perms2 = teardownClaudePermissions(home);
|
|
569
|
+
result[perms2.action].push(perms2.filePath);
|
|
570
|
+
cleanupSettingsFile(home);
|
|
571
|
+
if (!quiet) {
|
|
572
|
+
printTeardownSummary(result, home);
|
|
573
|
+
console.log("\n\u2713 DiffPrism global configuration removed.");
|
|
574
|
+
}
|
|
575
|
+
return result;
|
|
576
|
+
}
|
|
577
|
+
const gitRoot = findGitRoot(process.cwd());
|
|
578
|
+
if (!gitRoot) {
|
|
579
|
+
console.error(
|
|
580
|
+
"Error: Not in a git repository. Run this command from inside a git project."
|
|
581
|
+
);
|
|
582
|
+
console.error(
|
|
583
|
+
"Tip: Use `diffprism teardown --global` to remove global DiffPrism configuration."
|
|
584
|
+
);
|
|
585
|
+
process.exit(1);
|
|
586
|
+
return { removed: [], skipped: [] };
|
|
587
|
+
}
|
|
588
|
+
if (!quiet) {
|
|
589
|
+
console.log("Tearing down DiffPrism configuration...\n");
|
|
590
|
+
}
|
|
591
|
+
const mcp = teardownMcpJson(gitRoot);
|
|
592
|
+
result[mcp.action].push(mcp.filePath);
|
|
593
|
+
const perms = teardownClaudePermissions(gitRoot);
|
|
594
|
+
result[perms.action].push(perms.filePath);
|
|
595
|
+
const hooks = teardownHooks(gitRoot);
|
|
596
|
+
result[hooks.action].push(hooks.filePath);
|
|
597
|
+
cleanupSettingsFile(gitRoot);
|
|
598
|
+
const skill = teardownSkill(gitRoot, false);
|
|
599
|
+
result[skill.action].push(skill.filePath);
|
|
600
|
+
const gitignore = teardownGitignore(gitRoot);
|
|
601
|
+
result[gitignore.action].push(gitignore.filePath);
|
|
602
|
+
const diffprismDir = teardownDiffprismDir(gitRoot);
|
|
603
|
+
result[diffprismDir.action].push(diffprismDir.filePath);
|
|
604
|
+
if (!quiet) {
|
|
605
|
+
printTeardownSummary(result, gitRoot);
|
|
606
|
+
console.log("\n\u2713 DiffPrism configuration removed.");
|
|
607
|
+
}
|
|
608
|
+
return result;
|
|
609
|
+
}
|
|
610
|
+
function printTeardownSummary(result, baseDir) {
|
|
611
|
+
if (result.removed.length > 0) {
|
|
612
|
+
console.log("Removed:");
|
|
613
|
+
for (const f of result.removed) {
|
|
614
|
+
console.log(` - ${path2.relative(baseDir, f) || f}`);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
if (result.skipped.length > 0) {
|
|
618
|
+
console.log("Skipped (not found):");
|
|
619
|
+
for (const f of result.skipped) {
|
|
620
|
+
console.log(` . ${path2.relative(baseDir, f) || f}`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
430
625
|
// cli/src/commands/start.ts
|
|
431
626
|
async function start(ref, flags) {
|
|
432
627
|
const outcome = await setup({
|
|
@@ -629,7 +824,7 @@ async function serverStop() {
|
|
|
629
824
|
|
|
630
825
|
// cli/src/index.ts
|
|
631
826
|
var program = new Command();
|
|
632
|
-
program.name("diffprism").description("Local-first code review tool for agent-generated changes").version(true ? "0.
|
|
827
|
+
program.name("diffprism").description("Local-first code review tool for agent-generated changes").version(true ? "0.20.0" : "0.0.0-dev");
|
|
633
828
|
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);
|
|
634
829
|
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);
|
|
635
830
|
program.command("watch [ref]").description("Start a persistent diff watcher with live-updating browser UI").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").action(watch);
|
|
@@ -638,6 +833,9 @@ program.command("serve").description("Start the MCP server for Claude Code integ
|
|
|
638
833
|
program.command("setup").description("Configure DiffPrism for Claude Code integration").option("--global", "Configure globally (skill + permissions, no git repo required)").option("--force", "Overwrite existing configuration files").action((flags) => {
|
|
639
834
|
setup(flags);
|
|
640
835
|
});
|
|
836
|
+
program.command("teardown").description("Remove DiffPrism configuration from the current project").option("--global", "Remove global configuration (skill + permissions at ~/.claude/)").option("-q, --quiet", "Suppress output").action((flags) => {
|
|
837
|
+
teardown(flags);
|
|
838
|
+
});
|
|
641
839
|
var serverCmd = program.command("server").description("Start the global DiffPrism server for multi-session reviews").option("-p, --port <port>", "HTTP API port (default: 24680)").option("--ws-port <port>", "WebSocket port (default: 24681)").option("--dev", "Use Vite dev server with HMR instead of static files").action(server);
|
|
642
840
|
serverCmd.command("status").description("Check if the global server is running and list active sessions").action(serverStatus);
|
|
643
841
|
serverCmd.command("stop").description("Stop the running global server").action(serverStop);
|
package/dist/mcp-server.js
CHANGED
|
@@ -76,7 +76,7 @@ async function reviewViaGlobalServer(serverInfo, diffRef, options) {
|
|
|
76
76
|
async function startMcpServer() {
|
|
77
77
|
const server = new McpServer({
|
|
78
78
|
name: "diffprism",
|
|
79
|
-
version: true ? "0.
|
|
79
|
+
version: true ? "0.20.0" : "0.0.0-dev"
|
|
80
80
|
});
|
|
81
81
|
server.tool(
|
|
82
82
|
"open_review",
|