@shareworker/code-review-mcp 0.1.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/LICENSE +21 -0
- package/README +155 -0
- package/README.md +155 -0
- package/dist/bundler.d.ts +27 -0
- package/dist/bundler.d.ts.map +1 -0
- package/dist/bundler.js +203 -0
- package/dist/bundler.js.map +1 -0
- package/dist/diff-parser.d.ts +46 -0
- package/dist/diff-parser.d.ts.map +1 -0
- package/dist/diff-parser.js +322 -0
- package/dist/diff-parser.js.map +1 -0
- package/dist/filter.d.ts +31 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +155 -0
- package/dist/filter.js.map +1 -0
- package/dist/git.d.ts +54 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +111 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +296 -0
- package/dist/index.js.map +1 -0
- package/dist/position.d.ts +14 -0
- package/dist/position.d.ts.map +1 -0
- package/dist/position.js +179 -0
- package/dist/position.js.map +1 -0
- package/dist/reflect.d.ts +17 -0
- package/dist/reflect.d.ts.map +1 -0
- package/dist/reflect.js +208 -0
- package/dist/reflect.js.map +1 -0
- package/dist/rules.d.ts +14 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +123 -0
- package/dist/rules.js.map +1 -0
- package/dist/types.d.ts +119 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
- package/skills/code +139 -0
- package/skills/code-review/SK +139 -0
- package/skills/code-review/SKILL +139 -0
- package/skills/code-review/SKILL.md +139 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { parsePatch } from "diff";
|
|
2
|
+
const HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
3
|
+
/**
|
|
4
|
+
* Normalize a diff line: trim whitespace, strip leading +/- diff markers, trim \r.
|
|
5
|
+
* Mirrors open-code-review's normalizeLine.
|
|
6
|
+
*/
|
|
7
|
+
export function normalizeLine(line) {
|
|
8
|
+
let s = line.replace(/\r$/, "");
|
|
9
|
+
s = s.trim();
|
|
10
|
+
if (s.startsWith("+"))
|
|
11
|
+
s = s.slice(1);
|
|
12
|
+
else if (s.startsWith("-"))
|
|
13
|
+
s = s.slice(1);
|
|
14
|
+
return s.trim();
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Split code text into normalized non-blank lines.
|
|
18
|
+
*/
|
|
19
|
+
export function splitAndNormalize(code) {
|
|
20
|
+
return code
|
|
21
|
+
.split("\n")
|
|
22
|
+
.map((l) => normalizeLine(l))
|
|
23
|
+
.filter((l) => l !== "");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse a single hunk's lines (with +/-/space prefixes) into typed HunkLine[].
|
|
27
|
+
*/
|
|
28
|
+
function parseHunkLines(lines) {
|
|
29
|
+
const result = [];
|
|
30
|
+
for (const line of lines) {
|
|
31
|
+
if (line === "")
|
|
32
|
+
continue; // trailing empty line from split, not a real hunk line
|
|
33
|
+
if (line.startsWith("\"))
|
|
34
|
+
continue;
|
|
35
|
+
if (line.startsWith("diff --git "))
|
|
36
|
+
break;
|
|
37
|
+
if (line.startsWith("+")) {
|
|
38
|
+
result.push({ type: "added", content: line.slice(1) });
|
|
39
|
+
}
|
|
40
|
+
else if (line.startsWith("-")) {
|
|
41
|
+
result.push({ type: "deleted", content: line.slice(1) });
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// Context line (' ' prefix) — only treat as context if it has the space marker.
|
|
45
|
+
const content = line.startsWith(" ") ? line.slice(1) : line;
|
|
46
|
+
result.push({ type: "context", content });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parse @@ ... @@ blocks from raw diff text into Hunk[].
|
|
53
|
+
* Lines before the first @@ header (file-level headers) are ignored.
|
|
54
|
+
*/
|
|
55
|
+
export function parseHunks(rawDiffText) {
|
|
56
|
+
const lines = rawDiffText.split("\n");
|
|
57
|
+
const hunks = [];
|
|
58
|
+
let current = null;
|
|
59
|
+
let currentLines = [];
|
|
60
|
+
for (const line of lines) {
|
|
61
|
+
const m = line.match(HUNK_HEADER_RE);
|
|
62
|
+
if (m) {
|
|
63
|
+
if (current) {
|
|
64
|
+
current.lines = parseHunkLines(currentLines);
|
|
65
|
+
hunks.push(current);
|
|
66
|
+
}
|
|
67
|
+
const oldStart = parseInt(m[1], 10);
|
|
68
|
+
const oldCount = m[2] ? parseInt(m[2], 10) : 1;
|
|
69
|
+
const newStart = parseInt(m[3], 10);
|
|
70
|
+
const newCount = m[4] ? parseInt(m[4], 10) : 1;
|
|
71
|
+
current = { oldStart, oldCount, newStart, newCount, lines: [] };
|
|
72
|
+
currentLines = [];
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (current === null)
|
|
76
|
+
continue;
|
|
77
|
+
if (line.startsWith("\"))
|
|
78
|
+
continue;
|
|
79
|
+
if (line.startsWith("diff --git ")) {
|
|
80
|
+
// Next file starts; flush.
|
|
81
|
+
current.lines = parseHunkLines(currentLines);
|
|
82
|
+
hunks.push(current);
|
|
83
|
+
current = null;
|
|
84
|
+
currentLines = [];
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
currentLines.push(line);
|
|
88
|
+
}
|
|
89
|
+
if (current) {
|
|
90
|
+
current.lines = parseHunkLines(currentLines);
|
|
91
|
+
hunks.push(current);
|
|
92
|
+
}
|
|
93
|
+
return hunks;
|
|
94
|
+
}
|
|
95
|
+
function parseFileMeta(rawDiffText) {
|
|
96
|
+
const lines = rawDiffText.split("\n");
|
|
97
|
+
let oldPath = "";
|
|
98
|
+
let newPath = "";
|
|
99
|
+
let isBinary = false;
|
|
100
|
+
let isNew = false;
|
|
101
|
+
let isDeleted = false;
|
|
102
|
+
let isRenamed = false;
|
|
103
|
+
for (const line of lines) {
|
|
104
|
+
if (line.startsWith("diff --git ")) {
|
|
105
|
+
// "diff --git a/path b/path" — extract both, but prefer ---/+++ lines below.
|
|
106
|
+
const m = line.match(/^diff --git a\/(.+?) b\/(.+)$/);
|
|
107
|
+
if (m) {
|
|
108
|
+
oldPath = m[1];
|
|
109
|
+
newPath = m[2];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (line.startsWith("--- ")) {
|
|
113
|
+
oldPath = line.slice(4).replace(/^a\//, "");
|
|
114
|
+
if (oldPath === "/dev/null") {
|
|
115
|
+
isNew = true;
|
|
116
|
+
oldPath = "";
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (line.startsWith("+++ ")) {
|
|
120
|
+
newPath = line.slice(4).replace(/^b\//, "");
|
|
121
|
+
if (newPath === "/dev/null") {
|
|
122
|
+
isDeleted = true;
|
|
123
|
+
newPath = "";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else if (line.startsWith("rename from ") || line.startsWith("rename to ")) {
|
|
127
|
+
isRenamed = true;
|
|
128
|
+
}
|
|
129
|
+
else if (line.startsWith("new file mode ")) {
|
|
130
|
+
isNew = true;
|
|
131
|
+
}
|
|
132
|
+
else if (line.startsWith("deleted file mode ")) {
|
|
133
|
+
isDeleted = true;
|
|
134
|
+
}
|
|
135
|
+
else if (line.startsWith("Binary files ") || line.includes("Binary files")) {
|
|
136
|
+
isBinary = true;
|
|
137
|
+
}
|
|
138
|
+
// Stop at first hunk header — rest is hunk content.
|
|
139
|
+
if (line.startsWith("@@ "))
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
// For renamed files without ---/+++ (pure rename, no content change), keep paths from diff --git line.
|
|
143
|
+
if (isRenamed && !oldPath && !newPath) {
|
|
144
|
+
const m = lines[0]?.match(/^diff --git a\/(.+?) b\/(.+)$/);
|
|
145
|
+
if (m) {
|
|
146
|
+
oldPath = m[1];
|
|
147
|
+
newPath = m[2];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return { oldPath, newPath, isBinary, isNew, isDeleted, isRenamed };
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Count insertions/deletions from hunks.
|
|
154
|
+
*/
|
|
155
|
+
function countChanges(hunks) {
|
|
156
|
+
let insertions = 0;
|
|
157
|
+
let deletions = 0;
|
|
158
|
+
for (const hunk of hunks) {
|
|
159
|
+
for (const line of hunk.lines) {
|
|
160
|
+
if (line.type === "added")
|
|
161
|
+
insertions++;
|
|
162
|
+
else if (line.type === "deleted")
|
|
163
|
+
deletions++;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return { insertions, deletions };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Parse a full unified diff (possibly multiple files) into FileDiff[].
|
|
170
|
+
* Uses the `diff` library's parsePatch for hunk line splitting, and
|
|
171
|
+
* raw-text scanning for git edge cases (rename/binary/new-file/deleted-file).
|
|
172
|
+
*/
|
|
173
|
+
export function parseFileDiffs(diffText) {
|
|
174
|
+
if (!diffText.trim())
|
|
175
|
+
return [];
|
|
176
|
+
// Split into per-file blocks on "diff --git " boundaries.
|
|
177
|
+
const fileBlocks = splitFileBlocks(diffText);
|
|
178
|
+
const results = [];
|
|
179
|
+
for (const block of fileBlocks) {
|
|
180
|
+
const meta = parseFileMeta(block);
|
|
181
|
+
const parsed = parsePatch(block)[0];
|
|
182
|
+
const hunks = [];
|
|
183
|
+
if (parsed && parsed.hunks.length > 0) {
|
|
184
|
+
for (const ph of parsed.hunks) {
|
|
185
|
+
const lines = [];
|
|
186
|
+
for (const rawLine of ph.lines) {
|
|
187
|
+
if (rawLine === "")
|
|
188
|
+
continue;
|
|
189
|
+
if (rawLine.startsWith("\"))
|
|
190
|
+
continue;
|
|
191
|
+
if (rawLine.startsWith("+")) {
|
|
192
|
+
lines.push({ type: "added", content: rawLine.slice(1) });
|
|
193
|
+
}
|
|
194
|
+
else if (rawLine.startsWith("-")) {
|
|
195
|
+
lines.push({ type: "deleted", content: rawLine.slice(1) });
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
const content = rawLine.startsWith(" ") ? rawLine.slice(1) : rawLine;
|
|
199
|
+
lines.push({ type: "context", content });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
hunks.push({
|
|
203
|
+
oldStart: ph.oldStart,
|
|
204
|
+
oldCount: ph.oldLines,
|
|
205
|
+
newStart: ph.newStart,
|
|
206
|
+
newCount: ph.newLines,
|
|
207
|
+
lines,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const { insertions, deletions } = countChanges(hunks);
|
|
212
|
+
const path = meta.newPath || meta.oldPath;
|
|
213
|
+
if (!path && !meta.isBinary)
|
|
214
|
+
continue; // skip unparseable blocks
|
|
215
|
+
results.push({
|
|
216
|
+
oldPath: meta.oldPath,
|
|
217
|
+
newPath: meta.newPath,
|
|
218
|
+
diff: block,
|
|
219
|
+
hunks,
|
|
220
|
+
isBinary: meta.isBinary,
|
|
221
|
+
isNew: meta.isNew,
|
|
222
|
+
isDeleted: meta.isDeleted,
|
|
223
|
+
isRenamed: meta.isRenamed,
|
|
224
|
+
insertions,
|
|
225
|
+
deletions,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return results;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Split a multi-file unified diff into per-file blocks.
|
|
232
|
+
* Each block starts at a "diff --git " line and ends before the next one.
|
|
233
|
+
*/
|
|
234
|
+
function splitFileBlocks(diffText) {
|
|
235
|
+
const lines = diffText.split("\n");
|
|
236
|
+
const blocks = [];
|
|
237
|
+
let current = [];
|
|
238
|
+
for (const line of lines) {
|
|
239
|
+
if (line.startsWith("diff --git ") && current.length > 0) {
|
|
240
|
+
blocks.push(current.join("\n"));
|
|
241
|
+
current = [];
|
|
242
|
+
}
|
|
243
|
+
current.push(line);
|
|
244
|
+
}
|
|
245
|
+
if (current.length > 0) {
|
|
246
|
+
blocks.push(current.join("\n"));
|
|
247
|
+
}
|
|
248
|
+
return blocks;
|
|
249
|
+
}
|
|
250
|
+
export function extractSideLines(hunk, newSide) {
|
|
251
|
+
const result = [];
|
|
252
|
+
let oldLine = hunk.oldStart;
|
|
253
|
+
let newLine = hunk.newStart;
|
|
254
|
+
for (const l of hunk.lines) {
|
|
255
|
+
switch (l.type) {
|
|
256
|
+
case "context":
|
|
257
|
+
result.push({
|
|
258
|
+
lineNum: newSide ? newLine : oldLine,
|
|
259
|
+
content: normalizeLine(l.content),
|
|
260
|
+
});
|
|
261
|
+
oldLine++;
|
|
262
|
+
newLine++;
|
|
263
|
+
break;
|
|
264
|
+
case "added":
|
|
265
|
+
if (newSide) {
|
|
266
|
+
result.push({ lineNum: newLine, content: normalizeLine(l.content) });
|
|
267
|
+
}
|
|
268
|
+
newLine++;
|
|
269
|
+
break;
|
|
270
|
+
case "deleted":
|
|
271
|
+
if (!newSide) {
|
|
272
|
+
result.push({ lineNum: oldLine, content: normalizeLine(l.content) });
|
|
273
|
+
}
|
|
274
|
+
oldLine++;
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return result;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Scan sideLines for a consecutive run matching all targetLines.
|
|
282
|
+
* Returns the start/end line numbers of the match, or null.
|
|
283
|
+
* Mirrors open-code-review's matchConsecutive.
|
|
284
|
+
*/
|
|
285
|
+
export function matchConsecutive(sideLines, targetLines) {
|
|
286
|
+
if (targetLines.length === 0 || sideLines.length < targetLines.length) {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
for (let i = 0; i <= sideLines.length - targetLines.length; i++) {
|
|
290
|
+
let matched = true;
|
|
291
|
+
for (let j = 0; j < targetLines.length; j++) {
|
|
292
|
+
if (sideLines[i + j].content !== targetLines[j]) {
|
|
293
|
+
matched = false;
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (matched) {
|
|
298
|
+
return {
|
|
299
|
+
start: sideLines[i].lineNum,
|
|
300
|
+
end: sideLines[i + targetLines.length - 1].lineNum,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Get the set of changed (added) line numbers in a hunk (new-file line numbers).
|
|
308
|
+
*/
|
|
309
|
+
export function getAddedLineNumbers(hunks) {
|
|
310
|
+
const result = new Set();
|
|
311
|
+
for (const hunk of hunks) {
|
|
312
|
+
let newLine = hunk.newStart;
|
|
313
|
+
for (const l of hunk.lines) {
|
|
314
|
+
if (l.type === "added")
|
|
315
|
+
result.add(newLine);
|
|
316
|
+
if (l.type === "added" || l.type === "context")
|
|
317
|
+
newLine++;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
//# sourceMappingURL=diff-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-parser.js","sourceRoot":"","sources":["../src/diff-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAGlC,MAAM,cAAc,GAAG,6CAA6C,CAAC;AAErE;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACb,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACjC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,KAAe;IACrC,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,EAAE;YAAE,SAAS,CAAC,uDAAuD;QAClF,IAAI,IAAI,CAAC,UAAU,CAAC,8BAA8B,CAAC;YAAE,SAAS;QAC9D,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;YAAE,MAAM;QAC1C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,gFAAgF;YAChF,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB;IAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,IAAI,OAAO,GAAgB,IAAI,CAAC;IAChC,IAAI,YAAY,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC;YACN,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;gBAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC;YACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,OAAO,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;YAChE,YAAY,GAAG,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,IAAI;YAAE,SAAS;QAC/B,IAAI,IAAI,CAAC,UAAU,CAAC,8BAA8B,CAAC;YAAE,SAAS;QAC9D,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACnC,2BAA2B;YAC3B,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,GAAG,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QACD,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAeD,SAAS,aAAa,CAAC,WAAmB;IACxC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACnC,6EAA6E;YAC7E,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACtD,IAAI,CAAC,EAAE,CAAC;gBACN,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACf,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC5C,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;gBAC5B,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO,GAAG,EAAE,CAAC;YACf,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC5C,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;gBAC5B,SAAS,GAAG,IAAI,CAAC;gBACjB,OAAO,GAAG,EAAE,CAAC;YACf,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5E,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC7C,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACjD,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7E,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,oDAAoD;QACpD,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,MAAM;IACpC,CAAC;IAED,uGAAuG;IACvG,IAAI,SAAS,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC3D,IAAI,CAAC,EAAE,CAAC;YACN,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;gBAAE,UAAU,EAAE,CAAC;iBACnC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;gBAAE,SAAS,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAEhC,0DAA0D;IAC1D,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE7C,MAAM,OAAO,GAAe,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,KAAK,GAAW,EAAE,CAAC;QAEzB,IAAI,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAe,EAAE,CAAC;gBAC7B,KAAK,MAAM,OAAO,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;oBAC/B,IAAI,OAAO,KAAK,EAAE;wBAAE,SAAS;oBAC7B,IAAI,OAAO,CAAC,UAAU,CAAC,8BAA8B,CAAC;wBAAE,SAAS;oBACjE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBAC3D,CAAC;yBAAM,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACnC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBAC7D,CAAC;yBAAM,CAAC;wBACN,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;wBACrE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC3C,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC;oBACT,QAAQ,EAAE,EAAE,CAAC,QAAQ;oBACrB,QAAQ,EAAE,EAAE,CAAC,QAAQ;oBACrB,QAAQ,EAAE,EAAE,CAAC,QAAQ;oBACrB,QAAQ,EAAE,EAAE,CAAC,QAAQ;oBACrB,KAAK;iBACN,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;QAC1C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,SAAS,CAAC,0BAA0B;QAEjE,OAAO,CAAC,IAAI,CAAC;YACX,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,KAAK;YACX,KAAK;YACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,UAAU;YACV,SAAS;SACV,CAAC,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,SAAS,eAAe,CAAC,QAAgB;IACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAChC,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAaD,MAAM,UAAU,gBAAgB,CAAC,IAAU,EAAE,OAAgB;IAC3D,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC5B,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;IAE5B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,SAAS;gBACZ,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;oBACpC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC;iBAClC,CAAC,CAAC;gBACH,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,CAAC;gBACV,MAAM;YACR,KAAK,OAAO;gBACV,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACvE,CAAC;gBACD,OAAO,EAAE,CAAC;gBACV,MAAM;YACR,KAAK,SAAS;gBACZ,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACvE,CAAC;gBACD,OAAO,EAAE,CAAC;gBACV,MAAM;QACV,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAAwB,EACxB,WAAqB;IAErB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChE,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,IAAI,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChD,OAAO,GAAG,KAAK,CAAC;gBAChB,MAAM;YACR,CAAC;QACH,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO;gBACL,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO;gBAC3B,GAAG,EAAE,SAAS,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO;aACnD,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;gBAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,EAAE,CAAC;QAC5D,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/filter.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { FilterConfig } from "./types.js";
|
|
2
|
+
/** Built-in default blacklist of glob patterns. */
|
|
3
|
+
export declare const DEFAULT_EXCLUDE: string[];
|
|
4
|
+
/**
|
|
5
|
+
* Check if a path has a binary file extension.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isBinaryByExtension(path: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Match a path against a list of glob patterns (case-insensitive).
|
|
10
|
+
* Brace expansion like "*.{ts,js}" is handled by minimatch.
|
|
11
|
+
*/
|
|
12
|
+
export declare function matchAny(path: string, patterns: string[]): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Load and merge filter config from repo, home, and built-in defaults.
|
|
15
|
+
* Priority: repo > home > built-in defaults.
|
|
16
|
+
* User exclude patterns are appended to (not replacing) the built-in defaults;
|
|
17
|
+
* user include patterns (when present) restrict to only matching files.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadFilterConfig(repo: string): Promise<FilterConfig>;
|
|
20
|
+
/**
|
|
21
|
+
* Filter a list of file paths.
|
|
22
|
+
* - Files matching any exclude pattern are removed.
|
|
23
|
+
* - If include patterns are present, only files matching an include pattern are kept.
|
|
24
|
+
* - Binary files (by extension) are removed.
|
|
25
|
+
* @returns kept files and count of filtered-out files.
|
|
26
|
+
*/
|
|
27
|
+
export declare function filterFiles(files: string[], config: FilterConfig): {
|
|
28
|
+
kept: string[];
|
|
29
|
+
filtered: number;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,YAAY,CAAC;AAE5D,mDAAmD;AACnD,eAAO,MAAM,eAAe,EAAE,MAAM,EAgDnC,CAAC;AAYF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMzD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAMlE;AAeD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqB1E;AAMD;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,YAAY,GACnB;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAqBtC"}
|
package/dist/filter.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { minimatch } from "minimatch";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
/** Built-in default blacklist of glob patterns. */
|
|
6
|
+
export const DEFAULT_EXCLUDE = [
|
|
7
|
+
"**/*.lock",
|
|
8
|
+
"**/package-lock.json",
|
|
9
|
+
"**/yarn.lock",
|
|
10
|
+
"**/pnpm-lock.yaml",
|
|
11
|
+
"**/*.min.js",
|
|
12
|
+
"**/*.min.css",
|
|
13
|
+
"**/*.map",
|
|
14
|
+
// Binary file extensions
|
|
15
|
+
"**/*.png",
|
|
16
|
+
"**/*.jpg",
|
|
17
|
+
"**/*.jpeg",
|
|
18
|
+
"**/*.gif",
|
|
19
|
+
"**/*.bmp",
|
|
20
|
+
"**/*.ico",
|
|
21
|
+
"**/*.svg",
|
|
22
|
+
"**/*.zip",
|
|
23
|
+
"**/*.tar",
|
|
24
|
+
"**/*.gz",
|
|
25
|
+
"**/*.tgz",
|
|
26
|
+
"**/*.bz2",
|
|
27
|
+
"**/*.7z",
|
|
28
|
+
"**/*.rar",
|
|
29
|
+
"**/*.pdf",
|
|
30
|
+
"**/*.doc",
|
|
31
|
+
"**/*.docx",
|
|
32
|
+
"**/*.xls",
|
|
33
|
+
"**/*.xlsx",
|
|
34
|
+
"**/*.ppt",
|
|
35
|
+
"**/*.pptx",
|
|
36
|
+
"**/*.exe",
|
|
37
|
+
"**/*.dll",
|
|
38
|
+
"**/*.so",
|
|
39
|
+
"**/*.dylib",
|
|
40
|
+
"**/*.class",
|
|
41
|
+
"**/*.jar",
|
|
42
|
+
"**/*.war",
|
|
43
|
+
"**/*.wasm",
|
|
44
|
+
"**/*.mp3",
|
|
45
|
+
"**/*.mp4",
|
|
46
|
+
"**/*.avi",
|
|
47
|
+
"**/*.mov",
|
|
48
|
+
"**/*.webp",
|
|
49
|
+
"**/*.ttf",
|
|
50
|
+
"**/*.otf",
|
|
51
|
+
"**/*.woff",
|
|
52
|
+
"**/*.woff2",
|
|
53
|
+
"**/*.eot",
|
|
54
|
+
];
|
|
55
|
+
/** Binary file extensions for fallback detection (without glob wrapper). */
|
|
56
|
+
const BINARY_EXTENSIONS = new Set([
|
|
57
|
+
".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".svg",
|
|
58
|
+
".zip", ".tar", ".gz", ".tgz", ".bz2", ".7z", ".rar",
|
|
59
|
+
".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
|
|
60
|
+
".exe", ".dll", ".so", ".dylib", ".class", ".jar", ".war", ".wasm",
|
|
61
|
+
".mp3", ".mp4", ".avi", ".mov", ".webp",
|
|
62
|
+
".ttf", ".otf", ".woff", ".woff2", ".eot",
|
|
63
|
+
]);
|
|
64
|
+
/**
|
|
65
|
+
* Check if a path has a binary file extension.
|
|
66
|
+
*/
|
|
67
|
+
export function isBinaryByExtension(path) {
|
|
68
|
+
const lower = path.toLowerCase();
|
|
69
|
+
for (const ext of BINARY_EXTENSIONS) {
|
|
70
|
+
if (lower.endsWith(ext))
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Match a path against a list of glob patterns (case-insensitive).
|
|
77
|
+
* Brace expansion like "*.{ts,js}" is handled by minimatch.
|
|
78
|
+
*/
|
|
79
|
+
export function matchAny(path, patterns) {
|
|
80
|
+
const lowerPath = path.toLowerCase();
|
|
81
|
+
for (const pattern of patterns) {
|
|
82
|
+
if (minimatch(lowerPath, pattern.toLowerCase()))
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Load a rules.json file from a directory, returning null if missing or unparseable.
|
|
89
|
+
*/
|
|
90
|
+
async function loadRulesFile(dir) {
|
|
91
|
+
const filePath = join(dir, ".code-review", "rules.json");
|
|
92
|
+
try {
|
|
93
|
+
const content = await readFile(filePath, "utf8");
|
|
94
|
+
return JSON.parse(content);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Load and merge filter config from repo, home, and built-in defaults.
|
|
102
|
+
* Priority: repo > home > built-in defaults.
|
|
103
|
+
* User exclude patterns are appended to (not replacing) the built-in defaults;
|
|
104
|
+
* user include patterns (when present) restrict to only matching files.
|
|
105
|
+
*/
|
|
106
|
+
export async function loadFilterConfig(repo) {
|
|
107
|
+
const repoConfig = await loadRulesFile(repo);
|
|
108
|
+
const homeConfig = await loadRulesFile(homedir());
|
|
109
|
+
const repoFilters = repoConfig?.filters;
|
|
110
|
+
const homeFilters = homeConfig?.filters;
|
|
111
|
+
// Merge excludes: built-in defaults + home + repo (all apply, repo wins on conflict by being last).
|
|
112
|
+
const exclude = [
|
|
113
|
+
...DEFAULT_EXCLUDE,
|
|
114
|
+
...(homeFilters?.exclude ?? []),
|
|
115
|
+
...(repoFilters?.exclude ?? []),
|
|
116
|
+
];
|
|
117
|
+
// Merge includes: repo include wins if present, else home, else empty (no restriction).
|
|
118
|
+
const include = repoFilters?.include ??
|
|
119
|
+
homeFilters?.include ??
|
|
120
|
+
[];
|
|
121
|
+
return { include, exclude: dedup(exclude) };
|
|
122
|
+
}
|
|
123
|
+
function dedup(arr) {
|
|
124
|
+
return [...new Set(arr)];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Filter a list of file paths.
|
|
128
|
+
* - Files matching any exclude pattern are removed.
|
|
129
|
+
* - If include patterns are present, only files matching an include pattern are kept.
|
|
130
|
+
* - Binary files (by extension) are removed.
|
|
131
|
+
* @returns kept files and count of filtered-out files.
|
|
132
|
+
*/
|
|
133
|
+
export function filterFiles(files, config) {
|
|
134
|
+
const kept = [];
|
|
135
|
+
let filtered = 0;
|
|
136
|
+
for (const file of files) {
|
|
137
|
+
// Normalize to forward slashes.
|
|
138
|
+
const path = file.replace(/\\/g, "/");
|
|
139
|
+
if (isBinaryByExtension(path)) {
|
|
140
|
+
filtered++;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
if (matchAny(path, config.exclude)) {
|
|
144
|
+
filtered++;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (config.include.length > 0 && !matchAny(path, config.include)) {
|
|
148
|
+
filtered++;
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
kept.push(path);
|
|
152
|
+
}
|
|
153
|
+
return { kept, filtered };
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"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"}
|
package/dist/git.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { SimpleGit } from "simple-git";
|
|
2
|
+
/** File-level metadata from `git diff --summary`. */
|
|
3
|
+
export interface DiffFileSummary {
|
|
4
|
+
file: string;
|
|
5
|
+
insertions: number;
|
|
6
|
+
deletions: number;
|
|
7
|
+
binary: boolean;
|
|
8
|
+
}
|
|
9
|
+
/** Porcelain status entry for a file. */
|
|
10
|
+
export interface StatusEntry {
|
|
11
|
+
path: string;
|
|
12
|
+
/** "untracked" | "modified" | "added" | "deleted" | "renamed" | "staged" */
|
|
13
|
+
status: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Open a simple-git instance for a repo path.
|
|
17
|
+
* Falls back to cwd when repo is empty.
|
|
18
|
+
*/
|
|
19
|
+
export declare function openRepo(repo?: string): SimpleGit;
|
|
20
|
+
/**
|
|
21
|
+
* Get the unified diff text for a ref.
|
|
22
|
+
* `ref` may be a range like "main..feature" or a single ref like "HEAD".
|
|
23
|
+
*/
|
|
24
|
+
export declare function getDiff(repo: string, ref: string): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Get the unified diff text for a single file at a ref.
|
|
27
|
+
* Uses `git diff <ref> -- <path>` to scope to one file.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getDiffForFile(repo: string, ref: string, path: string): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Get file-level diff metadata (insertions/deletions/binary) for a ref.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getDiffSummary(repo: string, ref: string): Promise<DiffFileSummary[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Get the content of a file at a given ref (e.g. "HEAD", "main").
|
|
36
|
+
* For untracked files, pass ref="WORKTREE" to read from the working directory.
|
|
37
|
+
*/
|
|
38
|
+
export declare function getFileContent(repo: string, ref: string, path: string): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Get porcelain status for untracked file detection.
|
|
41
|
+
* Returns entries with status "untracked" for files git doesn't track.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getStatus(repo: string): Promise<StatusEntry[]>;
|
|
44
|
+
/**
|
|
45
|
+
* List untracked files (not yet `git add`-ed).
|
|
46
|
+
*/
|
|
47
|
+
export declare function getUntrackedFiles(repo: string): Promise<string[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Synthesize a full-file-add diff for an untracked file,
|
|
50
|
+
* equivalent to `git diff --no-index /dev/null <file>`.
|
|
51
|
+
* Reads the file content and wraps it in a unified diff with all lines added.
|
|
52
|
+
*/
|
|
53
|
+
export declare function synthesizeUntrackedDiff(repo: string, path: string): Promise<string>;
|
|
54
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,qDAAqD;AACrD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAEjD;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGxE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,eAAe,EAAE,CAAC,CAS5B;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAcpE;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAIvE;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAuBjB"}
|