@heyhuynhgiabuu/pi-diff 0.6.4 → 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.
Files changed (54) hide show
  1. package/README.md +37 -181
  2. package/dist/edit-guard.d.ts +2 -0
  3. package/dist/edit-guard.d.ts.map +1 -0
  4. package/dist/edit-guard.js +34 -0
  5. package/dist/edit-guard.js.map +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +49 -160
  8. package/dist/index.js.map +1 -1
  9. package/package.json +7 -49
  10. package/dist/cli.d.ts +0 -3
  11. package/dist/cli.d.ts.map +0 -1
  12. package/dist/cli.js +0 -53
  13. package/dist/cli.js.map +0 -1
  14. package/dist/core/resolve-lines.d.ts +0 -45
  15. package/dist/core/resolve-lines.d.ts.map +0 -1
  16. package/dist/core/resolve-lines.js +0 -204
  17. package/dist/core/resolve-lines.js.map +0 -1
  18. package/dist/review/command.d.ts +0 -3
  19. package/dist/review/command.d.ts.map +0 -1
  20. package/dist/review/command.js +0 -492
  21. package/dist/review/command.js.map +0 -1
  22. package/dist/review/export.d.ts +0 -7
  23. package/dist/review/export.d.ts.map +0 -1
  24. package/dist/review/export.js +0 -74
  25. package/dist/review/export.js.map +0 -1
  26. package/dist/review/file-preview.d.ts +0 -9
  27. package/dist/review/file-preview.d.ts.map +0 -1
  28. package/dist/review/file-preview.js +0 -225
  29. package/dist/review/file-preview.js.map +0 -1
  30. package/dist/review/hunk-bridge.d.ts +0 -54
  31. package/dist/review/hunk-bridge.d.ts.map +0 -1
  32. package/dist/review/hunk-bridge.js +0 -105
  33. package/dist/review/hunk-bridge.js.map +0 -1
  34. package/dist/review/interactive.d.ts +0 -27
  35. package/dist/review/interactive.d.ts.map +0 -1
  36. package/dist/review/interactive.js +0 -137
  37. package/dist/review/interactive.js.map +0 -1
  38. package/dist/review/model.d.ts +0 -33
  39. package/dist/review/model.d.ts.map +0 -1
  40. package/dist/review/model.js +0 -197
  41. package/dist/review/model.js.map +0 -1
  42. package/dist/review/prompt.d.ts +0 -4
  43. package/dist/review/prompt.d.ts.map +0 -1
  44. package/dist/review/prompt.js +0 -40
  45. package/dist/review/prompt.js.map +0 -1
  46. package/dist/review/session.d.ts +0 -69
  47. package/dist/review/session.d.ts.map +0 -1
  48. package/dist/review/session.js +0 -168
  49. package/dist/review/session.js.map +0 -1
  50. package/dist/review/tui.d.ts +0 -57
  51. package/dist/review/tui.d.ts.map +0 -1
  52. package/dist/review/tui.js +0 -482
  53. package/dist/review/tui.js.map +0 -1
  54. package/prompts/review-diff-agent.md +0 -19
@@ -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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"}
@@ -1,3 +0,0 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- export declare function registerReviewDiffCommand(pi: ExtensionAPI, cwd: string): void;
3
- //# sourceMappingURL=command.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/review/command.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAA4J,MAAM,iCAAiC,CAAC;AAmH9N,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAmF7E"}