@heyhuynhgiabuu/pi-diff 0.4.0 → 0.5.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/README.md +101 -53
- package/dist/cli.js +4 -6
- package/dist/cli.js.map +1 -1
- package/dist/core/diff.js +2 -38
- package/dist/core/diff.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +60 -196
- package/dist/index.js.map +1 -1
- package/dist/review/command.d.ts +2 -1
- package/dist/review/command.d.ts.map +1 -1
- package/dist/review/command.js +252 -174
- package/dist/review/command.js.map +1 -1
- package/dist/review/export.js +1 -4
- package/dist/review/export.js.map +1 -1
- package/dist/review/file-preview.js +7 -10
- package/dist/review/file-preview.js.map +1 -1
- package/dist/review/git.js +14 -22
- package/dist/review/git.js.map +1 -1
- package/dist/review/hunk-bridge.d.ts +54 -0
- package/dist/review/hunk-bridge.d.ts.map +1 -0
- package/dist/review/hunk-bridge.js +105 -0
- package/dist/review/hunk-bridge.js.map +1 -0
- package/dist/review/hunk-preview.d.ts.map +1 -1
- package/dist/review/hunk-preview.js +26 -63
- package/dist/review/hunk-preview.js.map +1 -1
- package/dist/review/interactive.js +3 -8
- package/dist/review/interactive.js.map +1 -1
- package/dist/review/model.js +9 -20
- package/dist/review/model.js.map +1 -1
- package/dist/review/prompt.js +3 -6
- package/dist/review/prompt.js.map +1 -1
- package/dist/review/session.js +22 -44
- package/dist/review/session.js.map +1 -1
- package/dist/review/tui.js +47 -51
- package/dist/review/tui.js.map +1 -1
- package/package.json +11 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-preview.js","sourceRoot":"","sources":["../../src/review/file-preview.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-preview.js","sourceRoot":"","sources":["../../src/review/file-preview.ts"],"names":[],"mappings":"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"}
|
package/dist/review/git.js
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
exports.readChangedFiles = readChangedFiles;
|
|
5
|
-
exports.countReviewHunkLines = countReviewHunkLines;
|
|
6
|
-
exports.countReviewFileLines = countReviewFileLines;
|
|
7
|
-
exports.countReviewDiffLines = countReviewDiffLines;
|
|
8
|
-
exports.parseUnifiedGitDiff = parseUnifiedGitDiff;
|
|
9
|
-
const node_child_process_1 = require("node:child_process");
|
|
10
|
-
const node_fs_1 = require("node:fs");
|
|
11
|
-
const node_path_1 = require("node:path");
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { readFileSync, statSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
12
4
|
const HUNK_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)$/;
|
|
13
|
-
function readGitDiff(cwd, mode = { type: "working-tree" }) {
|
|
5
|
+
export function readGitDiff(cwd, mode = { type: "working-tree" }) {
|
|
14
6
|
const args = mode.type === "branch" ? ["diff", "--no-ext-diff", `${mode.base}...HEAD`] : ["diff", "--no-ext-diff"];
|
|
15
|
-
const trackedRaw =
|
|
7
|
+
const trackedRaw = execFileSync("git", args, {
|
|
16
8
|
cwd,
|
|
17
9
|
encoding: "utf8",
|
|
18
10
|
maxBuffer: 50 * 1024 * 1024,
|
|
@@ -22,16 +14,16 @@ function readGitDiff(cwd, mode = { type: "working-tree" }) {
|
|
|
22
14
|
const raw = [trackedRaw.trimEnd(), untrackedRaw.trimEnd()].filter(Boolean).join("\n");
|
|
23
15
|
return { mode, files: parseUnifiedGitDiff(raw), raw };
|
|
24
16
|
}
|
|
25
|
-
function readChangedFiles(cwd, mode = { type: "working-tree" }) {
|
|
17
|
+
export function readChangedFiles(cwd, mode = { type: "working-tree" }) {
|
|
26
18
|
const args = mode.type === "branch" ? ["diff", "--name-only", `${mode.base}...HEAD`] : ["diff", "--name-only"];
|
|
27
|
-
const raw =
|
|
19
|
+
const raw = execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
28
20
|
const tracked = raw
|
|
29
21
|
.split("\n")
|
|
30
22
|
.map((line) => line.trim())
|
|
31
23
|
.filter(Boolean);
|
|
32
24
|
return mode.type === "working-tree" ? [...tracked, ...readUntrackedFiles(cwd)] : tracked;
|
|
33
25
|
}
|
|
34
|
-
function countReviewHunkLines(hunk) {
|
|
26
|
+
export function countReviewHunkLines(hunk) {
|
|
35
27
|
let insertions = 0;
|
|
36
28
|
let deletions = 0;
|
|
37
29
|
for (const line of hunk.lines) {
|
|
@@ -42,7 +34,7 @@ function countReviewHunkLines(hunk) {
|
|
|
42
34
|
}
|
|
43
35
|
return { insertions, deletions };
|
|
44
36
|
}
|
|
45
|
-
function countReviewFileLines(file) {
|
|
37
|
+
export function countReviewFileLines(file) {
|
|
46
38
|
let insertions = 0;
|
|
47
39
|
let deletions = 0;
|
|
48
40
|
for (const hunk of file.hunks) {
|
|
@@ -52,7 +44,7 @@ function countReviewFileLines(file) {
|
|
|
52
44
|
}
|
|
53
45
|
return { insertions, deletions };
|
|
54
46
|
}
|
|
55
|
-
function countReviewDiffLines(diff) {
|
|
47
|
+
export function countReviewDiffLines(diff) {
|
|
56
48
|
let insertions = 0;
|
|
57
49
|
let deletions = 0;
|
|
58
50
|
for (const file of diff.files) {
|
|
@@ -62,7 +54,7 @@ function countReviewDiffLines(diff) {
|
|
|
62
54
|
}
|
|
63
55
|
return { insertions, deletions };
|
|
64
56
|
}
|
|
65
|
-
function parseUnifiedGitDiff(raw) {
|
|
57
|
+
export function parseUnifiedGitDiff(raw) {
|
|
66
58
|
const files = [];
|
|
67
59
|
let currentFile = null;
|
|
68
60
|
let currentHunk = null;
|
|
@@ -142,7 +134,7 @@ function parseUnifiedGitDiff(raw) {
|
|
|
142
134
|
return files;
|
|
143
135
|
}
|
|
144
136
|
function readUntrackedFiles(cwd) {
|
|
145
|
-
const raw =
|
|
137
|
+
const raw = execFileSync("git", ["ls-files", "--others", "--exclude-standard"], {
|
|
146
138
|
cwd,
|
|
147
139
|
encoding: "utf8",
|
|
148
140
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -153,7 +145,7 @@ function readUntrackedFiles(cwd) {
|
|
|
153
145
|
.filter(Boolean)
|
|
154
146
|
.filter((path) => {
|
|
155
147
|
try {
|
|
156
|
-
return
|
|
148
|
+
return statSync(join(cwd, path)).isFile();
|
|
157
149
|
}
|
|
158
150
|
catch {
|
|
159
151
|
return false;
|
|
@@ -162,7 +154,7 @@ function readUntrackedFiles(cwd) {
|
|
|
162
154
|
}
|
|
163
155
|
function readUntrackedFilesAsDiff(cwd) {
|
|
164
156
|
return readUntrackedFiles(cwd)
|
|
165
|
-
.map((path) => formatNewFileDiff(path,
|
|
157
|
+
.map((path) => formatNewFileDiff(path, readFileSync(join(cwd, path), "utf8")))
|
|
166
158
|
.join("\n");
|
|
167
159
|
}
|
|
168
160
|
function formatNewFileDiff(path, content) {
|
package/dist/review/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/review/git.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/review/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hunk-bridge.ts — Thin subprocess wrapper for the `hunk` CLI.
|
|
3
|
+
*
|
|
4
|
+
* Detects availability of the `hunk` binary, pipes unified diff content to
|
|
5
|
+
* `hunk patch -` for interactive review, and extracts session comments
|
|
6
|
+
* after the review completes.
|
|
7
|
+
*/
|
|
8
|
+
export interface HunkComment {
|
|
9
|
+
filePath: string;
|
|
10
|
+
newLine: number;
|
|
11
|
+
oldLine: number;
|
|
12
|
+
summary: string;
|
|
13
|
+
}
|
|
14
|
+
export interface HunkReviewResult {
|
|
15
|
+
available: boolean;
|
|
16
|
+
comments?: HunkComment[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check whether the `hunk` CLI is available on the current PATH.
|
|
20
|
+
*
|
|
21
|
+
* Runs `hunk --version` with a short timeout and returns `true` if it
|
|
22
|
+
* succeeds, `false` otherwise.
|
|
23
|
+
*/
|
|
24
|
+
export declare function checkHunkAvailable(): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Parse raw JSON output from `hunk session comment list --json` into
|
|
27
|
+
* `HunkComment[]`.
|
|
28
|
+
*
|
|
29
|
+
* Handles both snake_case and camelCase field names emitted by the CLI.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseHunkComments(rawJson: string): HunkComment[];
|
|
32
|
+
/**
|
|
33
|
+
* Run `hunk session comment list --repo <cwd> --json` and return parsed
|
|
34
|
+
* comments. Returns an empty array on any failure (CLI not found,
|
|
35
|
+
* no active session, parse error, etc.).
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractComments(cwd: string): HunkComment[];
|
|
38
|
+
/**
|
|
39
|
+
* Launch an interactive `hunk patch -` review session.
|
|
40
|
+
*
|
|
41
|
+
* If the `hunk` CLI is not available, returns `{ available: false }`
|
|
42
|
+
* immediately without throwing.
|
|
43
|
+
*
|
|
44
|
+
* Otherwise:
|
|
45
|
+
* 1. Spawns `hunk patch -` in the given `cwd` with `diffRaw` piped to
|
|
46
|
+
* stdin while inheriting the parent process TTY (stdout / stderr).
|
|
47
|
+
* 2. Waits for the subprocess to exit.
|
|
48
|
+
* 3. Extracts any session comments left during the review via
|
|
49
|
+
* `hunk session comment list --repo <cwd> --json`.
|
|
50
|
+
*
|
|
51
|
+
* @returns A `HunkReviewResult` with availability flag and any comments.
|
|
52
|
+
*/
|
|
53
|
+
export declare function launchHunkReview(cwd: string, diffRaw: string): Promise<HunkReviewResult>;
|
|
54
|
+
//# sourceMappingURL=hunk-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunk-bridge.d.ts","sourceRoot":"","sources":["../../src/review/hunk-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;CACzB;AAgBD;;;;;GAKG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO3D;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CAahE;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,EAAE,CAY1D;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAyB9F"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hunk-bridge.ts — Thin subprocess wrapper for the `hunk` CLI.
|
|
3
|
+
*
|
|
4
|
+
* Detects availability of the `hunk` binary, pipes unified diff content to
|
|
5
|
+
* `hunk patch -` for interactive review, and extracts session comments
|
|
6
|
+
* after the review completes.
|
|
7
|
+
*/
|
|
8
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
9
|
+
// ─── Availability Check ──────────────────────────────────────────────────────
|
|
10
|
+
/**
|
|
11
|
+
* Check whether the `hunk` CLI is available on the current PATH.
|
|
12
|
+
*
|
|
13
|
+
* Runs `hunk --version` with a short timeout and returns `true` if it
|
|
14
|
+
* succeeds, `false` otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export async function checkHunkAvailable() {
|
|
17
|
+
try {
|
|
18
|
+
execFileSync("hunk", ["--version"], { stdio: "ignore", timeout: 5000 });
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// ─── Comment Parsing ─────────────────────────────────────────────────────────
|
|
26
|
+
/**
|
|
27
|
+
* Parse raw JSON output from `hunk session comment list --json` into
|
|
28
|
+
* `HunkComment[]`.
|
|
29
|
+
*
|
|
30
|
+
* Handles both snake_case and camelCase field names emitted by the CLI.
|
|
31
|
+
*/
|
|
32
|
+
export function parseHunkComments(rawJson) {
|
|
33
|
+
try {
|
|
34
|
+
const parsed = JSON.parse(rawJson);
|
|
35
|
+
if (!Array.isArray(parsed))
|
|
36
|
+
return [];
|
|
37
|
+
return parsed.map((item) => ({
|
|
38
|
+
filePath: String(item.filePath ?? item.file_path ?? item.file ?? ""),
|
|
39
|
+
newLine: Number(item.newLine ?? item.new_line ?? 0),
|
|
40
|
+
oldLine: Number(item.oldLine ?? item.old_line ?? 0),
|
|
41
|
+
summary: String(item.summary ?? item.comment ?? ""),
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// ─── Comment Extraction ──────────────────────────────────────────────────────
|
|
49
|
+
/**
|
|
50
|
+
* Run `hunk session comment list --repo <cwd> --json` and return parsed
|
|
51
|
+
* comments. Returns an empty array on any failure (CLI not found,
|
|
52
|
+
* no active session, parse error, etc.).
|
|
53
|
+
*/
|
|
54
|
+
export function extractComments(cwd) {
|
|
55
|
+
try {
|
|
56
|
+
const stdout = execFileSync("hunk", ["session", "comment", "list", "--repo", cwd, "--json"], {
|
|
57
|
+
cwd,
|
|
58
|
+
encoding: "utf-8",
|
|
59
|
+
timeout: 15_000,
|
|
60
|
+
maxBuffer: 1024 * 1024,
|
|
61
|
+
});
|
|
62
|
+
return parseHunkComments(stdout);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// ─── Main Entry Point ────────────────────────────────────────────────────────
|
|
69
|
+
/**
|
|
70
|
+
* Launch an interactive `hunk patch -` review session.
|
|
71
|
+
*
|
|
72
|
+
* If the `hunk` CLI is not available, returns `{ available: false }`
|
|
73
|
+
* immediately without throwing.
|
|
74
|
+
*
|
|
75
|
+
* Otherwise:
|
|
76
|
+
* 1. Spawns `hunk patch -` in the given `cwd` with `diffRaw` piped to
|
|
77
|
+
* stdin while inheriting the parent process TTY (stdout / stderr).
|
|
78
|
+
* 2. Waits for the subprocess to exit.
|
|
79
|
+
* 3. Extracts any session comments left during the review via
|
|
80
|
+
* `hunk session comment list --repo <cwd> --json`.
|
|
81
|
+
*
|
|
82
|
+
* @returns A `HunkReviewResult` with availability flag and any comments.
|
|
83
|
+
*/
|
|
84
|
+
export async function launchHunkReview(cwd, diffRaw) {
|
|
85
|
+
const available = await checkHunkAvailable();
|
|
86
|
+
if (!available) {
|
|
87
|
+
return { available: false };
|
|
88
|
+
}
|
|
89
|
+
await new Promise((resolve, reject) => {
|
|
90
|
+
const proc = spawn("hunk", ["patch", "-"], {
|
|
91
|
+
cwd,
|
|
92
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
93
|
+
});
|
|
94
|
+
// Pipe the raw diff into the subprocess
|
|
95
|
+
proc.stdin.write(diffRaw);
|
|
96
|
+
proc.stdin.end();
|
|
97
|
+
proc.on("close", resolve);
|
|
98
|
+
proc.on("error", reject);
|
|
99
|
+
});
|
|
100
|
+
// Even when the exit code is non-zero we attempt to harvest comments
|
|
101
|
+
// so the caller can still inspect partial review state.
|
|
102
|
+
const comments = extractComments(cwd);
|
|
103
|
+
return { available: true, comments };
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=hunk-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hunk-bridge.js","sourceRoot":"","sources":["../../src/review/hunk-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hunk-preview.d.ts","sourceRoot":"","sources":["../../src/review/hunk-preview.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,OAAO,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AA2B3F,UAAU,UAAU;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AA6JD,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5F;AA2ID,wBAAgB,gBAAgB,IAAI,IAAI,CAiFvC;AAED,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,MAAM,CA6BjD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,UAAU,CAgCzD;AA8KD,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAElE;
|
|
1
|
+
{"version":3,"file":"hunk-preview.d.ts","sourceRoot":"","sources":["../../src/review/hunk-preview.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,OAAO,CAAC;AAE3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AA2B3F,UAAU,UAAU;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AA6JD,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAO5F;AA2ID,wBAAgB,gBAAgB,IAAI,IAAI,CAiFvC;AAED,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,MAAM,CA6BjD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,UAAU,CAgCzD;AA8KD,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAElE;AAgHD,wBAAsB,aAAa,CAClC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAiHjB;AAED,wBAAsB,WAAW,CAChC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,eAAe,GAAG,SAAS,EACrC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CA+HjB"}
|
|
@@ -1,49 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.renderReviewHunkPreview = renderReviewHunkPreview;
|
|
37
|
-
exports.applyDiffPalette = applyDiffPalette;
|
|
38
|
-
exports.themeCacheKey = themeCacheKey;
|
|
39
|
-
exports.resolveDiffColors = resolveDiffColors;
|
|
40
|
-
exports.lang = lang;
|
|
41
|
-
exports.renderUnified = renderUnified;
|
|
42
|
-
exports.renderSplit = renderSplit;
|
|
43
|
-
const node_fs_1 = require("node:fs");
|
|
44
|
-
const node_path_1 = require("node:path");
|
|
45
|
-
const cli_1 = require("@shikijs/cli");
|
|
46
|
-
const Diff = __importStar(require("diff"));
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { extname } from "node:path";
|
|
3
|
+
import { codeToANSI } from "@shikijs/cli";
|
|
4
|
+
import * as Diff from "diff";
|
|
47
5
|
const DIFF_PRESETS = {
|
|
48
6
|
default: {
|
|
49
7
|
name: "default",
|
|
@@ -192,9 +150,9 @@ const EXT_LANG = {
|
|
|
192
150
|
svelte: "svelte",
|
|
193
151
|
vue: "vue",
|
|
194
152
|
};
|
|
195
|
-
|
|
153
|
+
codeToANSI("", "typescript", THEME).catch(() => { });
|
|
196
154
|
const highlightCache = new Map();
|
|
197
|
-
async function renderReviewHunkPreview(input) {
|
|
155
|
+
export async function renderReviewHunkPreview(input) {
|
|
198
156
|
ensurePalette();
|
|
199
157
|
const diff = createParsedDiffFromReviewHunk(input.hunk);
|
|
200
158
|
const width = Math.max(MIN_RENDER_WIDTH, input.width || DEFAULT_RENDER_WIDTH);
|
|
@@ -325,8 +283,8 @@ function loadDiffConfig() {
|
|
|
325
283
|
const paths = [`${process.cwd()}/.pi/settings.json`, `${process.env.HOME ?? ""}/.pi/settings.json`];
|
|
326
284
|
for (const path of paths) {
|
|
327
285
|
try {
|
|
328
|
-
if (
|
|
329
|
-
const raw = JSON.parse(
|
|
286
|
+
if (existsSync(path)) {
|
|
287
|
+
const raw = JSON.parse(readFileSync(path, "utf-8"));
|
|
330
288
|
if (raw.diffTheme || raw.diffColors) {
|
|
331
289
|
return { diffTheme: raw.diffTheme, diffColors: raw.diffColors };
|
|
332
290
|
}
|
|
@@ -336,7 +294,7 @@ function loadDiffConfig() {
|
|
|
336
294
|
}
|
|
337
295
|
return {};
|
|
338
296
|
}
|
|
339
|
-
function applyDiffPalette() {
|
|
297
|
+
export function applyDiffPalette() {
|
|
340
298
|
const config = loadDiffConfig();
|
|
341
299
|
const preset = config.diffTheme ? DIFF_PRESETS[config.diffTheme] : null;
|
|
342
300
|
if (preset)
|
|
@@ -413,7 +371,7 @@ function applyDiffPalette() {
|
|
|
413
371
|
DEFAULT_DIFF_COLORS = { fgAdd: FG_ADD, fgDel: FG_DEL, fgCtx: FG_DIM };
|
|
414
372
|
_autoDerivePending = !_hasExplicitBgConfig;
|
|
415
373
|
}
|
|
416
|
-
function themeCacheKey(theme) {
|
|
374
|
+
export function themeCacheKey(theme) {
|
|
417
375
|
if (!theme?.fg)
|
|
418
376
|
return "no-theme";
|
|
419
377
|
const fgKeys = [
|
|
@@ -446,7 +404,7 @@ function themeCacheKey(theme) {
|
|
|
446
404
|
}
|
|
447
405
|
return parts.join("|");
|
|
448
406
|
}
|
|
449
|
-
function resolveDiffColors(theme) {
|
|
407
|
+
export function resolveDiffColors(theme) {
|
|
450
408
|
const currentThemeKey = themeCacheKey(theme);
|
|
451
409
|
if (!_hasExplicitBgConfig && _lastResolvedThemeKey && _lastResolvedThemeKey !== currentThemeKey) {
|
|
452
410
|
BG_BASE = BG_DEFAULT;
|
|
@@ -661,8 +619,8 @@ function shouldUseSplit(diff, width, maxRows) {
|
|
|
661
619
|
return false;
|
|
662
620
|
return true;
|
|
663
621
|
}
|
|
664
|
-
function lang(filePath) {
|
|
665
|
-
return EXT_LANG[
|
|
622
|
+
export function lang(filePath) {
|
|
623
|
+
return EXT_LANG[extname(filePath).slice(1).toLowerCase()];
|
|
666
624
|
}
|
|
667
625
|
function touchCache(key, value) {
|
|
668
626
|
highlightCache.delete(key);
|
|
@@ -685,7 +643,7 @@ async function hlBlock(code, language) {
|
|
|
685
643
|
if (cached)
|
|
686
644
|
return touchCache(key, cached);
|
|
687
645
|
try {
|
|
688
|
-
const ansi = normalizeShikiContrast(await
|
|
646
|
+
const ansi = normalizeShikiContrast(await codeToANSI(code, language, THEME));
|
|
689
647
|
const output = (ansi.endsWith("\n") ? ansi.slice(0, -1) : ansi).split("\n");
|
|
690
648
|
return touchCache(key, output);
|
|
691
649
|
}
|
|
@@ -735,8 +693,11 @@ function injectBg(ansiLine, ranges, baseBg, highlightBg) {
|
|
|
735
693
|
if (end !== -1) {
|
|
736
694
|
const sequence = ansiLine.slice(index, end + 1);
|
|
737
695
|
output += sequence;
|
|
738
|
-
|
|
696
|
+
// Re-inject bg after any reset-like sequence (Shiki uses \x1b[39m
|
|
697
|
+
// between tokens; some terminals may treat it as a broader reset).
|
|
698
|
+
if (sequence === "\x1b[0m" || sequence === "\x1b[39m" || sequence === "\x1b[49m") {
|
|
739
699
|
output += inHighlight ? highlightBg : baseBg;
|
|
700
|
+
}
|
|
740
701
|
index = end + 1;
|
|
741
702
|
continue;
|
|
742
703
|
}
|
|
@@ -770,7 +731,7 @@ function plainWordDiff(oldText, newText) {
|
|
|
770
731
|
}
|
|
771
732
|
return { old: oldOutput, new: newOutput };
|
|
772
733
|
}
|
|
773
|
-
async function renderUnified(diff, language, maxLines, colors, width) {
|
|
734
|
+
export async function renderUnified(diff, language, maxLines, colors, width) {
|
|
774
735
|
if (!diff.lines.length)
|
|
775
736
|
return "";
|
|
776
737
|
const visible = diff.lines.slice(0, maxLines);
|
|
@@ -841,14 +802,15 @@ async function renderUnified(diff, language, maxLines, colors, width) {
|
|
|
841
802
|
}
|
|
842
803
|
const isPaired = deletions.length === 1 && additions.length === 1;
|
|
843
804
|
const wordDiff = isPaired ? wordDiffAnalysis(deletions[0].line.content, additions[0].line.content) : null;
|
|
844
|
-
|
|
805
|
+
const wordDiffBalanced = wordDiff && wordDiff.oldRanges.length > 0 && wordDiff.newRanges.length > 0;
|
|
806
|
+
if (isPaired && wordDiffBalanced && wordDiff.similarity >= WORD_DIFF_MIN_SIM && canHighlight) {
|
|
845
807
|
const deletionBody = injectBg(deletions[0].hl, wordDiff.oldRanges, BG_DEL, BG_DEL_W);
|
|
846
808
|
const additionBody = injectBg(additions[0].hl, wordDiff.newRanges, BG_ADD, BG_ADD_W);
|
|
847
809
|
emitRow(deletions[0].line.oldNum, "-", BG_GUTTER_DEL, `${colors.fgDel}${BOLD}`, deletionBody, BG_DEL);
|
|
848
810
|
emitRow(additions[0].line.newNum, "+", BG_GUTTER_ADD, `${colors.fgAdd}${BOLD}`, additionBody, BG_ADD);
|
|
849
811
|
continue;
|
|
850
812
|
}
|
|
851
|
-
if (isPaired &&
|
|
813
|
+
if (isPaired && wordDiffBalanced && wordDiff.similarity >= WORD_DIFF_MIN_SIM && !canHighlight) {
|
|
852
814
|
const plain = plainWordDiff(deletions[0].line.content, additions[0].line.content);
|
|
853
815
|
emitRow(deletions[0].line.oldNum, "-", BG_GUTTER_DEL, `${colors.fgDel}${BOLD}`, `${BG_DEL}${plain.old}`, BG_DEL);
|
|
854
816
|
emitRow(additions[0].line.newNum, "+", BG_GUTTER_ADD, `${colors.fgAdd}${BOLD}`, `${BG_ADD}${plain.new}`, BG_ADD);
|
|
@@ -869,7 +831,7 @@ async function renderUnified(diff, language, maxLines, colors, width) {
|
|
|
869
831
|
}
|
|
870
832
|
return output.join("\n");
|
|
871
833
|
}
|
|
872
|
-
async function renderSplit(diff, language, maxLines, colors, width) {
|
|
834
|
+
export async function renderSplit(diff, language, maxLines, colors, width) {
|
|
873
835
|
if (!shouldUseSplit(diff, width, maxLines))
|
|
874
836
|
return renderUnified(diff, language, maxLines, colors, width);
|
|
875
837
|
if (!diff.lines.length)
|
|
@@ -954,10 +916,11 @@ async function renderSplit(diff, language, maxLines, colors, width) {
|
|
|
954
916
|
for (const row of visible) {
|
|
955
917
|
const isPairedChange = row.left?.type === "del" && row.right?.type === "add";
|
|
956
918
|
const wordDiff = isPairedChange && row.left && row.right ? wordDiffAnalysis(row.left.content, row.right.content) : null;
|
|
919
|
+
const wordDiffBalanced = wordDiff && wordDiff.oldRanges.length > 0 && wordDiff.newRanges.length > 0;
|
|
957
920
|
const leftHighlight = row.left && row.left.type !== "sep" ? (leftHighlights[leftIndex++] ?? row.left.content) : "";
|
|
958
921
|
const rightHighlight = row.right && row.right.type !== "sep" ? (rightHighlights[rightIndex++] ?? row.right.content) : "";
|
|
959
|
-
const leftHalf = buildHalf(row.left, leftHighlight, isPairedChange &&
|
|
960
|
-
const rightHalf = buildHalf(row.right, rightHighlight, isPairedChange &&
|
|
922
|
+
const leftHalf = buildHalf(row.left, leftHighlight, isPairedChange && wordDiffBalanced && wordDiff.similarity >= WORD_DIFF_MIN_SIM ? wordDiff.oldRanges : null, "left");
|
|
923
|
+
const rightHalf = buildHalf(row.right, rightHighlight, isPairedChange && wordDiffBalanced && wordDiff.similarity >= WORD_DIFF_MIN_SIM ? wordDiff.newRanges : null, "right");
|
|
961
924
|
const maxRows = Math.max(leftHalf.bodyRows.length, rightHalf.bodyRows.length);
|
|
962
925
|
for (let rowIndex = 0; rowIndex < maxRows; rowIndex++) {
|
|
963
926
|
const leftBody = leftHalf.bodyRows[rowIndex] ?? emptyBody;
|