@heyhuynhgiabuu/pi-diff 0.6.5 → 0.6.6
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/edit-guard.d.ts +2 -0
- package/dist/edit-guard.d.ts.map +1 -0
- package/dist/edit-guard.js +34 -0
- package/dist/edit-guard.js.map +1 -0
- package/package.json +6 -2
- package/dist/core/resolve-lines.d.ts +0 -45
- package/dist/core/resolve-lines.d.ts.map +0 -1
- package/dist/core/resolve-lines.js +0 -204
- package/dist/core/resolve-lines.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-guard.d.ts","sourceRoot":"","sources":["../src/edit-guard.ts"],"names":[],"mappings":"AAkCA,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAQnD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Block edit tool calls when oldText is not present in the target file.
|
|
3
|
+
// Forces the model to re-read the file before editing instead of guessing
|
|
4
|
+
// stale oldText and getting caught in repeated retry loops.
|
|
5
|
+
import { readFileSync } from "node:fs";
|
|
6
|
+
const guardEditToolCall = async (event, _ctx) => {
|
|
7
|
+
const { path, edits } = event.input;
|
|
8
|
+
if (!edits || !Array.isArray(edits))
|
|
9
|
+
return;
|
|
10
|
+
let fileContent;
|
|
11
|
+
try {
|
|
12
|
+
fileContent = readFileSync(path, "utf8");
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
for (const edit of edits) {
|
|
18
|
+
if (!fileContent.includes(edit.oldText)) {
|
|
19
|
+
return {
|
|
20
|
+
block: true,
|
|
21
|
+
reason: `oldText not found in ${path}. Re-read the file and copy the exact text (edit protocol: VERIFY before EDIT).`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export function registerEditGuard(pi) {
|
|
27
|
+
if (pi == null)
|
|
28
|
+
return;
|
|
29
|
+
const on = pi.on;
|
|
30
|
+
if (typeof on !== "function")
|
|
31
|
+
return;
|
|
32
|
+
pi.on("tool_call", guardEditToolCall);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=edit-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-guard.js","sourceRoot":"","sources":["../src/edit-guard.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,wEAAwE;AACxE,0EAA0E;AAC1E,4DAA4D;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAOvC,MAAM,iBAAiB,GAA6D,KAAK,EACxF,KAAK,EACL,IAAI,EACH,EAAE;IACH,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC;IACpC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO;IAC5C,IAAI,WAAmB,CAAC;IACxB,IAAI,CAAC;QACJ,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACR,OAAO;IACR,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,OAAO;gBACN,KAAK,EAAE,IAAI;gBACX,MAAM,EAAE,wBAAwB,IAAI,iFAAiF;aACrH,CAAC;QACH,CAAC;IACF,CAAC;AACF,CAAC,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,EAAW;IAC5C,IAAI,EAAE,IAAI,IAAI;QAAE,OAAO;IACvB,MAAM,EAAE,GAAI,EAAuB,CAAC,EAAE,CAAC;IACvC,IAAI,OAAO,EAAE,KAAK,UAAU;QAAE,OAAO;IACpC,EAAyE,CAAC,EAAE,CAC5E,WAAW,EACX,iBAAiB,CACjB,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heyhuynhgiabuu/pi-diff",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.6",
|
|
4
4
|
"description": "Shiki-powered terminal diff renderer for pi — syntax-highlighted, word-level diffs in split and unified views.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"diff",
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"dist/index.d.ts.map",
|
|
27
27
|
"dist/index.js",
|
|
28
28
|
"dist/index.js.map",
|
|
29
|
+
"dist/edit-guard.d.ts",
|
|
30
|
+
"dist/edit-guard.d.ts.map",
|
|
31
|
+
"dist/edit-guard.js",
|
|
32
|
+
"dist/edit-guard.js.map",
|
|
29
33
|
"dist/core/config.d.ts",
|
|
30
34
|
"dist/core/config.d.ts.map",
|
|
31
35
|
"dist/core/config.js",
|
|
@@ -70,7 +74,7 @@
|
|
|
70
74
|
"dependencies": {
|
|
71
75
|
"@earendil-works/pi-coding-agent": "^0.79.0",
|
|
72
76
|
"@earendil-works/pi-tui": "^0.79.0",
|
|
73
|
-
"@heyhuynhgiabuu/pi-diff": "0.6.
|
|
77
|
+
"@heyhuynhgiabuu/pi-diff": "0.6.6",
|
|
74
78
|
"@shikijs/cli": "^4.0.2",
|
|
75
79
|
"diff": "^7.0.0"
|
|
76
80
|
},
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* resolve-lines.ts — Hunk-based line number resolution
|
|
3
|
-
*
|
|
4
|
-
* Matches an `existing_code` snippet from an LLM review comment against
|
|
5
|
-
* parsed diff hunks to backfill `startLine`/`endLine`. Ported from
|
|
6
|
-
* alibaba/open-code-review's internal/diff/resolver.go three-tier approach.
|
|
7
|
-
*
|
|
8
|
-
* Tiers:
|
|
9
|
-
* 1. New-side match (context + added lines with new-file line numbers)
|
|
10
|
-
* 2. Old-side match (context + deleted lines with old-file line numbers)
|
|
11
|
-
* 3. File-content scan (consecutive match in full new-file content)
|
|
12
|
-
*/
|
|
13
|
-
import type { ParsedDiff } from "./diff.js";
|
|
14
|
-
export interface ResolvedLines {
|
|
15
|
-
startLine: number;
|
|
16
|
-
endLine: number;
|
|
17
|
-
}
|
|
18
|
-
export interface Unresolved {
|
|
19
|
-
unresolved: true;
|
|
20
|
-
}
|
|
21
|
-
export type LinesResult = ResolvedLines | Unresolved;
|
|
22
|
-
/**
|
|
23
|
-
* Resolve line numbers for an `existing_code` snippet against a parsed diff.
|
|
24
|
-
*
|
|
25
|
-
* Tries three tiers:
|
|
26
|
-
* 1. New-side hunk match (context + added lines)
|
|
27
|
-
* 2. Old-side hunk match (context + deleted lines)
|
|
28
|
-
* 3. Full file-content scan (if `fileContent` is provided)
|
|
29
|
-
*
|
|
30
|
-
* @param existingCode - The code snippet from the LLM comment
|
|
31
|
-
* @param parsedDiff - Parsed diff for the file (from parsePatchFiles or parseDiff)
|
|
32
|
-
* @param fileContent - Optional full new-file content for fallback scan
|
|
33
|
-
* @returns Resolved line numbers or Unresolved
|
|
34
|
-
*/
|
|
35
|
-
export declare function resolveLines(existingCode: string, parsedDiff: ParsedDiff, fileContent?: string): LinesResult;
|
|
36
|
-
/**
|
|
37
|
-
* Convenience wrapper: resolve from a raw unified diff string instead of
|
|
38
|
-
* a pre-parsed ParsedDiff. Parses the diff internally.
|
|
39
|
-
*
|
|
40
|
-
* @param existingCode - The code snippet from the LLM comment
|
|
41
|
-
* @param unifiedDiff - Raw unified diff text (single file)
|
|
42
|
-
* @param fileContent - Optional full new-file content for fallback scan
|
|
43
|
-
*/
|
|
44
|
-
export declare function resolveLinesFromPatch(existingCode: string, unifiedDiff: string, fileContent?: string): LinesResult;
|
|
45
|
-
//# sourceMappingURL=resolve-lines.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-lines.d.ts","sourceRoot":"","sources":["../../src/core/resolve-lines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAY,UAAU,EAAE,MAAM,WAAW,CAAC;AAOtD,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IAC1B,UAAU,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;AAoKrD;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAC3B,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,UAAU,EACtB,WAAW,CAAC,EAAE,MAAM,GAClB,WAAW,CAkCb;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GAClB,WAAW,CASb"}
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* resolve-lines.ts — Hunk-based line number resolution
|
|
3
|
-
*
|
|
4
|
-
* Matches an `existing_code` snippet from an LLM review comment against
|
|
5
|
-
* parsed diff hunks to backfill `startLine`/`endLine`. Ported from
|
|
6
|
-
* alibaba/open-code-review's internal/diff/resolver.go three-tier approach.
|
|
7
|
-
*
|
|
8
|
-
* Tiers:
|
|
9
|
-
* 1. New-side match (context + added lines with new-file line numbers)
|
|
10
|
-
* 2. Old-side match (context + deleted lines with old-file line numbers)
|
|
11
|
-
* 3. File-content scan (consecutive match in full new-file content)
|
|
12
|
-
*/
|
|
13
|
-
import { parsePatchFiles } from "./diff.js";
|
|
14
|
-
// ---------------------------------------------------------------------------
|
|
15
|
-
// Normalization
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
17
|
-
/**
|
|
18
|
-
* Normalize a single code line for comparison.
|
|
19
|
-
* - Trims leading/trailing whitespace
|
|
20
|
-
* - Strips leading `+` or `-` diff markers
|
|
21
|
-
* - Re-trims after stripping
|
|
22
|
-
*/
|
|
23
|
-
function normalizeLine(s) {
|
|
24
|
-
s = s.trim();
|
|
25
|
-
s = s.startsWith("+") || s.startsWith("-") ? s.slice(1).trim() : s.trim();
|
|
26
|
-
return s;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Split `existing_code` into normalized non-empty lines.
|
|
30
|
-
* Empty lines after normalization are dropped (mirrors OCR behavior).
|
|
31
|
-
*/
|
|
32
|
-
function splitAndNormalize(code) {
|
|
33
|
-
const raw = code.split("\n");
|
|
34
|
-
const result = [];
|
|
35
|
-
for (const line of raw) {
|
|
36
|
-
const n = normalizeLine(line);
|
|
37
|
-
if (n === "")
|
|
38
|
-
continue;
|
|
39
|
-
result.push(n);
|
|
40
|
-
}
|
|
41
|
-
return result;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Reconstruct hunks from a flat ParsedDiff.
|
|
45
|
-
* Each `sep` marker with HunkMeta starts a new hunk. Context lines
|
|
46
|
-
* appear on both sides; `add` lines on new-side only; `del` lines on
|
|
47
|
-
* old-side only.
|
|
48
|
-
*/
|
|
49
|
-
function reconstructHunks(parsed) {
|
|
50
|
-
const hunks = [];
|
|
51
|
-
let currentHunk = null;
|
|
52
|
-
let oldNum = 0;
|
|
53
|
-
let newNum = 0;
|
|
54
|
-
for (const line of parsed.lines) {
|
|
55
|
-
if (line.type === "sep" && line.hunkMeta) {
|
|
56
|
-
// Start a new hunk (or the first one)
|
|
57
|
-
currentHunk = { newSide: [], oldSide: [] };
|
|
58
|
-
hunks.push(currentHunk);
|
|
59
|
-
oldNum = line.hunkMeta.oldStart;
|
|
60
|
-
newNum = line.hunkMeta.newStart;
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (!currentHunk)
|
|
64
|
-
continue; // lines before first sep — shouldn't happen
|
|
65
|
-
switch (line.type) {
|
|
66
|
-
case "ctx":
|
|
67
|
-
currentHunk.newSide.push({ lineNum: newNum++, content: normalizeLine(line.content) });
|
|
68
|
-
currentHunk.oldSide.push({ lineNum: oldNum++, content: normalizeLine(line.content) });
|
|
69
|
-
break;
|
|
70
|
-
case "add":
|
|
71
|
-
currentHunk.newSide.push({ lineNum: newNum++, content: normalizeLine(line.content) });
|
|
72
|
-
break;
|
|
73
|
-
case "del":
|
|
74
|
-
currentHunk.oldSide.push({ lineNum: oldNum++, content: normalizeLine(line.content) });
|
|
75
|
-
break;
|
|
76
|
-
// "sep" without hunkMeta (e.g., multi-edit separators) — skip
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return hunks;
|
|
80
|
-
}
|
|
81
|
-
// ---------------------------------------------------------------------------
|
|
82
|
-
// Sliding-window match
|
|
83
|
-
// ---------------------------------------------------------------------------
|
|
84
|
-
/**
|
|
85
|
-
* Scan `sideLines` for a consecutive run matching all `targetLines`.
|
|
86
|
-
* Returns the matching file line range, or undefined.
|
|
87
|
-
*/
|
|
88
|
-
function matchConsecutive(sideLines, targetLines) {
|
|
89
|
-
if (targetLines.length === 0 || sideLines.length < targetLines.length)
|
|
90
|
-
return undefined;
|
|
91
|
-
for (let i = 0; i <= sideLines.length - targetLines.length; i++) {
|
|
92
|
-
let matched = true;
|
|
93
|
-
for (let j = 0; j < targetLines.length; j++) {
|
|
94
|
-
if (sideLines[i + j].content !== targetLines[j]) {
|
|
95
|
-
matched = false;
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (matched) {
|
|
100
|
-
return {
|
|
101
|
-
startLine: sideLines[i].lineNum,
|
|
102
|
-
endLine: sideLines[i + targetLines.length - 1].lineNum,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return undefined;
|
|
107
|
-
}
|
|
108
|
-
// ---------------------------------------------------------------------------
|
|
109
|
-
// File-content fallback
|
|
110
|
-
// ---------------------------------------------------------------------------
|
|
111
|
-
/**
|
|
112
|
-
* Scan full file content line-by-line for a consecutive match of target lines.
|
|
113
|
-
* Returns 1-based line numbers.
|
|
114
|
-
*/
|
|
115
|
-
function matchInFileContent(fileContent, targetLines) {
|
|
116
|
-
if (!fileContent || targetLines.length === 0)
|
|
117
|
-
return undefined;
|
|
118
|
-
const fileLines = fileContent.split("\n");
|
|
119
|
-
if (fileLines.length < targetLines.length)
|
|
120
|
-
return undefined;
|
|
121
|
-
for (let i = 0; i <= fileLines.length - targetLines.length; i++) {
|
|
122
|
-
let matched = true;
|
|
123
|
-
for (let j = 0; j < targetLines.length; j++) {
|
|
124
|
-
const fileLine = fileLines[i + j].replace(/\r$/, "").trim();
|
|
125
|
-
if (fileLine !== targetLines[j]) {
|
|
126
|
-
matched = false;
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
if (matched) {
|
|
131
|
-
return { startLine: i + 1, endLine: i + targetLines.length };
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
// ---------------------------------------------------------------------------
|
|
137
|
-
// Public API
|
|
138
|
-
// ---------------------------------------------------------------------------
|
|
139
|
-
/**
|
|
140
|
-
* Resolve line numbers for an `existing_code` snippet against a parsed diff.
|
|
141
|
-
*
|
|
142
|
-
* Tries three tiers:
|
|
143
|
-
* 1. New-side hunk match (context + added lines)
|
|
144
|
-
* 2. Old-side hunk match (context + deleted lines)
|
|
145
|
-
* 3. Full file-content scan (if `fileContent` is provided)
|
|
146
|
-
*
|
|
147
|
-
* @param existingCode - The code snippet from the LLM comment
|
|
148
|
-
* @param parsedDiff - Parsed diff for the file (from parsePatchFiles or parseDiff)
|
|
149
|
-
* @param fileContent - Optional full new-file content for fallback scan
|
|
150
|
-
* @returns Resolved line numbers or Unresolved
|
|
151
|
-
*/
|
|
152
|
-
export function resolveLines(existingCode, parsedDiff, fileContent) {
|
|
153
|
-
if (!existingCode || !parsedDiff || parsedDiff.lines.length === 0) {
|
|
154
|
-
return { unresolved: true };
|
|
155
|
-
}
|
|
156
|
-
const targetLines = splitAndNormalize(existingCode);
|
|
157
|
-
if (targetLines.length === 0) {
|
|
158
|
-
return { unresolved: true };
|
|
159
|
-
}
|
|
160
|
-
const hunks = reconstructHunks(parsedDiff);
|
|
161
|
-
if (hunks.length === 0) {
|
|
162
|
-
return { unresolved: true };
|
|
163
|
-
}
|
|
164
|
-
// Tier 1: New-side match (context + added → new-file line numbers)
|
|
165
|
-
for (const hunk of hunks) {
|
|
166
|
-
const result = matchConsecutive(hunk.newSide, targetLines);
|
|
167
|
-
if (result)
|
|
168
|
-
return result;
|
|
169
|
-
}
|
|
170
|
-
// Tier 2: Old-side match (context + deleted → old-file line numbers)
|
|
171
|
-
for (const hunk of hunks) {
|
|
172
|
-
const result = matchConsecutive(hunk.oldSide, targetLines);
|
|
173
|
-
if (result)
|
|
174
|
-
return result;
|
|
175
|
-
}
|
|
176
|
-
// Tier 3: File-content fallback
|
|
177
|
-
if (fileContent) {
|
|
178
|
-
const result = matchInFileContent(fileContent, targetLines);
|
|
179
|
-
if (result)
|
|
180
|
-
return result;
|
|
181
|
-
}
|
|
182
|
-
return { unresolved: true };
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Convenience wrapper: resolve from a raw unified diff string instead of
|
|
186
|
-
* a pre-parsed ParsedDiff. Parses the diff internally.
|
|
187
|
-
*
|
|
188
|
-
* @param existingCode - The code snippet from the LLM comment
|
|
189
|
-
* @param unifiedDiff - Raw unified diff text (single file)
|
|
190
|
-
* @param fileContent - Optional full new-file content for fallback scan
|
|
191
|
-
*/
|
|
192
|
-
export function resolveLinesFromPatch(existingCode, unifiedDiff, fileContent) {
|
|
193
|
-
const parsed = parsePatchFiles(unifiedDiff);
|
|
194
|
-
if (parsed.length === 0)
|
|
195
|
-
return { unresolved: true };
|
|
196
|
-
// For multi-file patches, try each file's diff
|
|
197
|
-
for (const pd of parsed) {
|
|
198
|
-
const result = resolveLines(existingCode, pd, fileContent);
|
|
199
|
-
if (!("unresolved" in result))
|
|
200
|
-
return result;
|
|
201
|
-
}
|
|
202
|
-
return { unresolved: true };
|
|
203
|
-
}
|
|
204
|
-
//# sourceMappingURL=resolve-lines.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-lines.js","sourceRoot":"","sources":["../../src/core/resolve-lines.ts"],"names":[],"mappings":"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"}
|