@mnemonik/shared 7.119.1 → 7.120.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/codeScanner.d.ts +87 -18
- package/dist/codeScanner.d.ts.map +1 -1
- package/dist/codeScanner.js +229 -74
- package/dist/codeScanner.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/indexClassifier.d.ts +178 -0
- package/dist/indexClassifier.d.ts.map +1 -0
- package/dist/indexClassifier.js +585 -0
- package/dist/indexClassifier.js.map +1 -0
- package/dist/indexJudge.d.ts +50 -0
- package/dist/indexJudge.d.ts.map +1 -0
- package/dist/indexJudge.js +116 -0
- package/dist/indexJudge.js.map +1 -0
- package/package.json +1 -1
- package/src/codeScanner.ts +305 -81
- package/src/index.ts +34 -0
- package/src/indexClassifier.ts +681 -0
- package/src/indexJudge.ts +149 -0
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default indexing rules: which files are not code an agent works with.
|
|
3
|
+
*
|
|
4
|
+
* Code search should return the code agents edit, not generated clients,
|
|
5
|
+
* minified bundles, binary files, vendored dependencies or data dumps. These
|
|
6
|
+
* rules are SOFT defaults: a project can re-include any path they exclude, and
|
|
7
|
+
* that is what separates them from the hard rules that stay where they are
|
|
8
|
+
* (`isSecretFile`, protected paths, symlinks, nested git boundaries and
|
|
9
|
+
* `BUILT_IN_IGNORE_DIRS`, none of which can be overridden).
|
|
10
|
+
*
|
|
11
|
+
* Precedence, highest first:
|
|
12
|
+
* 1. hard rules - applied by the callers before this module is consulted;
|
|
13
|
+
* 2. the project's .gitignore / .mnemonikignore - a path they ignore is out,
|
|
14
|
+
* and a `!pattern` that matches the path ITSELF re-includes it from every
|
|
15
|
+
* soft default (a re-included parent directory does not: `.yarn/*` plus
|
|
16
|
+
* `!.yarn/releases`, Yarn's own recommended .gitignore, must not opt the
|
|
17
|
+
* bundled Yarn release back in);
|
|
18
|
+
* 3. .gitattributes - `linguist-vendored` / `linguist-generated` set or
|
|
19
|
+
* `=true` excludes, `-linguist-...` or `=false` re-includes, `binary` or
|
|
20
|
+
* `-text` means binary. Hierarchical, last match wins, as git resolves it;
|
|
21
|
+
* 4. the soft defaults below - path rules first, then content rules.
|
|
22
|
+
*
|
|
23
|
+
* ONE implementation for every place a path is judged: the daemon walk, its
|
|
24
|
+
* watcher and discovery walk, the server's push backstop and the retirement
|
|
25
|
+
* of stored rows. Two copies of a rule drift, and here drift means the daemon
|
|
26
|
+
* and the server disagree about what exists.
|
|
27
|
+
*
|
|
28
|
+
* Content rules read the SCRUBBED text (`scrubSecrets`), because that is the
|
|
29
|
+
* text the server receives: classifying the raw bytes on one side and the
|
|
30
|
+
* scrubbed bytes on the other would let a redaction placeholder move a file
|
|
31
|
+
* across the minified threshold on one side only.
|
|
32
|
+
*/
|
|
33
|
+
import { posix } from 'path';
|
|
34
|
+
export const INDEX_EXCLUSION_REASONS = [
|
|
35
|
+
'vendored',
|
|
36
|
+
'generated',
|
|
37
|
+
'minified',
|
|
38
|
+
'binary',
|
|
39
|
+
'data_dump',
|
|
40
|
+
'changelog',
|
|
41
|
+
];
|
|
42
|
+
const REASON_LABELS = {
|
|
43
|
+
vendored: 'vendored code',
|
|
44
|
+
generated: 'generated code',
|
|
45
|
+
minified: 'minified code',
|
|
46
|
+
binary: 'a binary file',
|
|
47
|
+
data_dump: 'a data dump',
|
|
48
|
+
changelog: 'a changelog',
|
|
49
|
+
};
|
|
50
|
+
/** Human phrase for a reason: "generated code", "a binary file". */
|
|
51
|
+
export function indexExclusionLabel(reason) {
|
|
52
|
+
return REASON_LABELS[reason];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The one line an agent sees when it asks about an excluded path. Short on
|
|
56
|
+
* purpose: the agent needs to know the absence is deliberate and that its own
|
|
57
|
+
* file tools still reach the file.
|
|
58
|
+
*/
|
|
59
|
+
export function indexExclusionNotice(reason, subject) {
|
|
60
|
+
return subject
|
|
61
|
+
? `${subject} is not in the code index: excluded by default as ${REASON_LABELS[reason]}. Read and Grep still work on it.`
|
|
62
|
+
: `Not in the code index: excluded by default as ${REASON_LABELS[reason]}. Read and Grep still work on this file.`;
|
|
63
|
+
}
|
|
64
|
+
export function isIndexExclusionReason(value) {
|
|
65
|
+
return (typeof value === 'string' && INDEX_EXCLUSION_REASONS.includes(value));
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Directory rules, tested against a path that ends in '/' for a directory and
|
|
69
|
+
* against the full file path for a file, so the same regex prunes a walk and
|
|
70
|
+
* classifies a file under it. Case-sensitive, as written: `Vendor/` is the
|
|
71
|
+
* CocoaPods/Swift spelling, and `Tests/fixtures/` the Swift package one.
|
|
72
|
+
*/
|
|
73
|
+
const DIRECTORY_RULES = [
|
|
74
|
+
// R2 - vendored dependencies and archive debris.
|
|
75
|
+
{
|
|
76
|
+
reason: 'vendored',
|
|
77
|
+
rule: 'vendored directory',
|
|
78
|
+
re: /(^|\/)(vendors?|Vendor|third[-_]?party|3rd[-_]?party|Godeps|Carthage|jspm_packages|site-packages|dist-packages|__MACOSX)\//,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
reason: 'vendored',
|
|
82
|
+
rule: 'Yarn release/plugin/cache directory',
|
|
83
|
+
re: /(^|\/)\.yarn\/(releases|plugins|sdks|versions|unplugged|cache)\//,
|
|
84
|
+
},
|
|
85
|
+
{ reason: 'vendored', rule: 'documentation build output', re: /(^|\/)docs?\/_?build\// },
|
|
86
|
+
// Test fixtures are copies of other code: byte-identical snapshot trees
|
|
87
|
+
// stole the content-hash dedup slot from the real file and outranked it in
|
|
88
|
+
// code_search. This folds in the old built-in `/tests/fixtures/*` pattern.
|
|
89
|
+
{ reason: 'vendored', rule: 'test fixtures', re: /(^|\/)([Tt]ests?|[Ss]pecs?)\/fixtures\// },
|
|
90
|
+
{ reason: 'vendored', rule: 'test fixtures', re: /(^|\/)(testdata|__fixtures__)\// },
|
|
91
|
+
{ reason: 'vendored', rule: 'test snapshots', re: /(^|\/)__snapshots__\// },
|
|
92
|
+
// R3 - generated output directories.
|
|
93
|
+
{
|
|
94
|
+
reason: 'generated',
|
|
95
|
+
rule: 'generated directory',
|
|
96
|
+
re: /(^|\/)(__generated__|_generated|generated|autogen)\//,
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
/**
|
|
100
|
+
* R3 by base name. `.test.` / `.spec.` names are exempt (see
|
|
101
|
+
* `isTestOrSpecName`): `Generated.test.ts` tests generated code, it is not it.
|
|
102
|
+
*/
|
|
103
|
+
const GENERATED_BASENAME_RULES = [
|
|
104
|
+
// Infixes: foo.gen.ts, foo.g.dart, foo.pb.go, foo.pb.gw.go, foo.freezed.dart,
|
|
105
|
+
// Form1.Designer.cs. Case-insensitive: Visual Studio writes `.Designer.cs`.
|
|
106
|
+
{ rule: 'generated infix', re: /\.(gen|g|pb|pb\.gw|freezed|designer)\.[^.]+$/i },
|
|
107
|
+
// Protocol Buffers / gRPC outputs.
|
|
108
|
+
{ rule: 'protobuf/gRPC output', re: /_pb2(_grpc)?\.pyi?$/ },
|
|
109
|
+
{ rule: 'protobuf/gRPC output', re: /_pb\.(js|ts)$/ },
|
|
110
|
+
{ rule: 'protobuf/gRPC output', re: /_grpc_pb\..+$/ },
|
|
111
|
+
{ rule: 'protobuf/gRPC output', re: /_grpc\.pb\.go$/ },
|
|
112
|
+
{ rule: 'protobuf/gRPC output', re: /\.pb\.(go|cc|h|swift|dart|ts|js)$/ },
|
|
113
|
+
// SpecFlow, Yarn Plug'n'Play, Delphi type libraries.
|
|
114
|
+
{ rule: 'SpecFlow feature binding', re: /\.feature\.cs$/ },
|
|
115
|
+
{ rule: "Yarn Plug'n'Play loader", re: /^\.pnp\./ },
|
|
116
|
+
{ rule: 'Delphi type library', re: /_tlb\.pas$/ },
|
|
117
|
+
];
|
|
118
|
+
function isTestOrSpecName(base) {
|
|
119
|
+
return base.includes('.test.') || base.includes('.spec.');
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* A base name whose stem token is `generated`: the name split on '.', minus
|
|
123
|
+
* the final extension, contains the token `generated` (any case).
|
|
124
|
+
* `Generated.ts`, `foo.generated.ts`, `api.generated.d.ts`; not
|
|
125
|
+
* `generatedClient.ts`, not `generator.ts`.
|
|
126
|
+
*/
|
|
127
|
+
function hasGeneratedStemToken(base) {
|
|
128
|
+
const tokens = base.split('.');
|
|
129
|
+
if (tokens.length < 2)
|
|
130
|
+
return false;
|
|
131
|
+
return tokens.slice(0, -1).some((token) => token.toLowerCase() === 'generated');
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* R9. Upper-case stems match with any extension, as the convention is
|
|
135
|
+
* written (`CHANGELOG`, `NEWS`, `HISTORY.rst`). Other spellings match only as
|
|
136
|
+
* a document (`History.md`, `changelog.md`): `history.ts` and `news.py` are
|
|
137
|
+
* real modules in real applications.
|
|
138
|
+
*/
|
|
139
|
+
const CHANGELOG_UPPER = /^(CHANGELOG|CHANGES|HISTORY|NEWS)(\.[^/]*)?$/;
|
|
140
|
+
const CHANGELOG_DOC = /^(changelog|changes|history|news)(\.(md|markdown|rst|txt|adoc))?$/i;
|
|
141
|
+
function posixPath(relPath) {
|
|
142
|
+
return relPath.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Soft default for a directory, from its path alone. `dirRel` is the
|
|
146
|
+
* directory's root-relative path, with or without a trailing slash. Used to
|
|
147
|
+
* prune walks: nothing under a vendored or generated directory can be
|
|
148
|
+
* included by a soft default.
|
|
149
|
+
*/
|
|
150
|
+
export function softDefaultForDirectory(dirRel) {
|
|
151
|
+
const path = posixPath(dirRel).replace(/\/+$/, '');
|
|
152
|
+
if (!path)
|
|
153
|
+
return null;
|
|
154
|
+
const withSlash = `${path}/`;
|
|
155
|
+
for (const { reason, rule, re } of DIRECTORY_RULES) {
|
|
156
|
+
if (re.test(withSlash))
|
|
157
|
+
return { reason, rule };
|
|
158
|
+
}
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
/** Soft default for a file from its path alone (R2, R3 by name, R8 AppleDouble, R9). */
|
|
162
|
+
export function softDefaultForPath(relPath) {
|
|
163
|
+
const path = posixPath(relPath);
|
|
164
|
+
if (!path)
|
|
165
|
+
return null;
|
|
166
|
+
for (const { reason, rule, re } of DIRECTORY_RULES) {
|
|
167
|
+
if (re.test(path))
|
|
168
|
+
return { reason, rule };
|
|
169
|
+
}
|
|
170
|
+
const base = posix.basename(path);
|
|
171
|
+
// R8: AppleDouble resource forks (`._name.js`) are binary metadata macOS
|
|
172
|
+
// writes beside a file on non-HFS volumes and inside zip archives.
|
|
173
|
+
if (base.startsWith('._'))
|
|
174
|
+
return { reason: 'binary', rule: 'AppleDouble resource fork' };
|
|
175
|
+
if (!isTestOrSpecName(base)) {
|
|
176
|
+
if (hasGeneratedStemToken(base))
|
|
177
|
+
return { reason: 'generated', rule: 'generated file name' };
|
|
178
|
+
for (const { rule, re } of GENERATED_BASENAME_RULES) {
|
|
179
|
+
if (re.test(base))
|
|
180
|
+
return { reason: 'generated', rule };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (CHANGELOG_UPPER.test(base) || CHANGELOG_DOC.test(base)) {
|
|
184
|
+
return { reason: 'changelog', rule: 'changelog file' };
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// Content rules
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
/** git's binary heuristic window. */
|
|
192
|
+
export const BINARY_SNIFF_BYTES = 8000;
|
|
193
|
+
/** Header detection looks at this many leading lines. */
|
|
194
|
+
const HEADER_LINES = 10;
|
|
195
|
+
/** R5: average line length above which a .js/.mjs/.cjs/.css file is minified. */
|
|
196
|
+
export const MINIFIED_AVERAGE_LINE_LENGTH = 110;
|
|
197
|
+
/** R5: a line longer than this, in UTF-8 bytes, is a minified line. */
|
|
198
|
+
export const MINIFIED_LONG_LINE_BYTES = 4096;
|
|
199
|
+
/** R7: a .sql file with at least this many INSERT INTO statements is a dump. */
|
|
200
|
+
export const DATA_DUMP_INSERT_THRESHOLD = 50;
|
|
201
|
+
const MINIFIABLE_EXTENSION = /\.(js|mjs|cjs|css)$/i;
|
|
202
|
+
/**
|
|
203
|
+
* Comment-line openers across the languages the scanner reads. A header rule
|
|
204
|
+
* only ever reads comment lines: code that mentions "generated" in a string
|
|
205
|
+
* literal is code.
|
|
206
|
+
*/
|
|
207
|
+
const COMMENT_LINE = /^\s*(\/\/|\/\*|\*|#|--|;|<!--|%|\(\*|\{-|"""|''')/;
|
|
208
|
+
const GO_GENERATED_HEADER = /^\/\/ Code generated .* DO NOT EDIT\.$/;
|
|
209
|
+
const AT_GENERATED = /@generated\b/;
|
|
210
|
+
const GENERATION_PHRASE = /\b(generated by|auto-generated|autogenerated|this file was generated|code generated)\b/i;
|
|
211
|
+
const DO_NOT_EDIT_PHRASE = /\b(do not edit|do not modify|manual changes will be overwritten)\b/i;
|
|
212
|
+
/**
|
|
213
|
+
* R4. A file is generated by its header when, within its first ten lines:
|
|
214
|
+
* a Go-style `// Code generated ... DO NOT EDIT.` line stands alone; or a
|
|
215
|
+
* comment line carries `@generated`; or the comment lines carry BOTH a
|
|
216
|
+
* generation phrase and a do-not-edit phrase. One phrase alone never counts -
|
|
217
|
+
* hand-written files say "generated by" about their outputs all the time.
|
|
218
|
+
*/
|
|
219
|
+
function generatedByHeader(content) {
|
|
220
|
+
const lines = content.split('\n', HEADER_LINES);
|
|
221
|
+
let generation = false;
|
|
222
|
+
let doNotEdit = false;
|
|
223
|
+
for (const raw of lines) {
|
|
224
|
+
const line = raw.replace(/\r$/, '');
|
|
225
|
+
if (GO_GENERATED_HEADER.test(line))
|
|
226
|
+
return 'Go generated-code header';
|
|
227
|
+
if (!COMMENT_LINE.test(line))
|
|
228
|
+
continue;
|
|
229
|
+
if (AT_GENERATED.test(line))
|
|
230
|
+
return '@generated marker';
|
|
231
|
+
if (GENERATION_PHRASE.test(line))
|
|
232
|
+
generation = true;
|
|
233
|
+
if (DO_NOT_EDIT_PHRASE.test(line))
|
|
234
|
+
doNotEdit = true;
|
|
235
|
+
}
|
|
236
|
+
return generation && doNotEdit ? 'generated + do-not-edit header' : null;
|
|
237
|
+
}
|
|
238
|
+
function utf8Length(line) {
|
|
239
|
+
// A UTF-16 unit is at most 3 UTF-8 bytes; skip the exact count when even
|
|
240
|
+
// that bound cannot reach the threshold.
|
|
241
|
+
if (line.length * 3 <= MINIFIED_LONG_LINE_BYTES)
|
|
242
|
+
return line.length;
|
|
243
|
+
return Buffer.byteLength(line, 'utf8');
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* R5. More than one line over 4,096 bytes means minified, whatever the
|
|
247
|
+
* language. A single long line does not: one embedded data URI or a long
|
|
248
|
+
* literal table in hand-written source is common, and a 1,024-character
|
|
249
|
+
* single-line rule would exclude this repository's own src/server/tools.ts.
|
|
250
|
+
*/
|
|
251
|
+
function minified(relPath, content) {
|
|
252
|
+
const lines = content.split('\n');
|
|
253
|
+
let longLines = 0;
|
|
254
|
+
let total = 0;
|
|
255
|
+
for (const line of lines) {
|
|
256
|
+
total += line.length;
|
|
257
|
+
if (line.length > MINIFIED_LONG_LINE_BYTES / 3 && utf8Length(line) > MINIFIED_LONG_LINE_BYTES) {
|
|
258
|
+
longLines++;
|
|
259
|
+
if (longLines > 1)
|
|
260
|
+
return 'two or more lines over 4,096 bytes';
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (MINIFIABLE_EXTENSION.test(relPath) && lines.length > 0) {
|
|
264
|
+
const average = total / lines.length;
|
|
265
|
+
if (average > MINIFIED_AVERAGE_LINE_LENGTH)
|
|
266
|
+
return 'average line length over 110';
|
|
267
|
+
}
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
const INSERT_INTO = /\binsert\s+into\b/gi;
|
|
271
|
+
const COPY_FROM_STDIN = /^\s*COPY\s+[^\n]*\bFROM\s+stdin\b/im;
|
|
272
|
+
/** R7. Schema lives in migrations; rows do not belong in a code index. */
|
|
273
|
+
function dataDump(relPath, content) {
|
|
274
|
+
if (!/\.sql$/i.test(relPath))
|
|
275
|
+
return null;
|
|
276
|
+
if (/(^|\/)migrations\//i.test(posixPath(relPath)))
|
|
277
|
+
return null;
|
|
278
|
+
if (COPY_FROM_STDIN.test(content))
|
|
279
|
+
return 'SQL COPY ... FROM stdin';
|
|
280
|
+
let inserts = 0;
|
|
281
|
+
INSERT_INTO.lastIndex = 0;
|
|
282
|
+
while (INSERT_INTO.exec(content) !== null) {
|
|
283
|
+
if (++inserts >= DATA_DUMP_INSERT_THRESHOLD)
|
|
284
|
+
return 'SQL with 50+ INSERT INTO statements';
|
|
285
|
+
}
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Soft default from a file's content (R4, R5, R7, R8). `content` is the
|
|
290
|
+
* decoded, scrubbed text. R8 uses git's heuristic: a NUL in the first 8,000
|
|
291
|
+
* characters (which cover at least the first 8,000 bytes).
|
|
292
|
+
*/
|
|
293
|
+
export function softDefaultForContent(relPath, content) {
|
|
294
|
+
if (content.slice(0, BINARY_SNIFF_BYTES).includes('\0')) {
|
|
295
|
+
return { reason: 'binary', rule: 'NUL byte in the first 8,000 bytes' };
|
|
296
|
+
}
|
|
297
|
+
const header = generatedByHeader(content);
|
|
298
|
+
if (header)
|
|
299
|
+
return { reason: 'generated', rule: header };
|
|
300
|
+
const minifiedRule = minified(relPath, content);
|
|
301
|
+
if (minifiedRule)
|
|
302
|
+
return { reason: 'minified', rule: minifiedRule };
|
|
303
|
+
const dump = dataDump(relPath, content);
|
|
304
|
+
if (dump)
|
|
305
|
+
return { reason: 'data_dump', rule: dump };
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
function escapeRegex(char) {
|
|
309
|
+
return /[.+^${}()|[\]\\*?/]/.test(char) ? `\\${char}` : char;
|
|
310
|
+
}
|
|
311
|
+
/** git wildmatch, FNM_PATHNAME semantics: `*` stops at '/', `**` crosses it. */
|
|
312
|
+
function globToRegex(glob) {
|
|
313
|
+
let re = '';
|
|
314
|
+
let i = 0;
|
|
315
|
+
while (i < glob.length) {
|
|
316
|
+
if (glob.startsWith('**', i)) {
|
|
317
|
+
const atSegmentStart = i === 0 || glob[i - 1] === '/';
|
|
318
|
+
const next = glob[i + 2];
|
|
319
|
+
if (atSegmentStart && next === '/') {
|
|
320
|
+
re += '(?:.*/)?';
|
|
321
|
+
i += 3;
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
if (atSegmentStart && next === undefined) {
|
|
325
|
+
re += '.*';
|
|
326
|
+
i += 2;
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
re += '[^/]*';
|
|
330
|
+
i += 2;
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const char = glob[i];
|
|
334
|
+
if (char === '*') {
|
|
335
|
+
re += '[^/]*';
|
|
336
|
+
}
|
|
337
|
+
else if (char === '?') {
|
|
338
|
+
re += '[^/]';
|
|
339
|
+
}
|
|
340
|
+
else if (char === '[') {
|
|
341
|
+
const close = glob.indexOf(']', i + 2);
|
|
342
|
+
if (close === -1) {
|
|
343
|
+
re += '\\[';
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
let body = glob.slice(i + 1, close);
|
|
347
|
+
if (body.startsWith('!'))
|
|
348
|
+
body = `^${body.slice(1)}`;
|
|
349
|
+
re += `[${body.replace(/\\/g, '\\\\')}]`;
|
|
350
|
+
i = close;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
else if (char === '\\' && i + 1 < glob.length) {
|
|
354
|
+
re += escapeRegex(glob[i + 1]);
|
|
355
|
+
i++;
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
re += escapeRegex(char);
|
|
359
|
+
}
|
|
360
|
+
i++;
|
|
361
|
+
}
|
|
362
|
+
return new RegExp(`^${re}$`);
|
|
363
|
+
}
|
|
364
|
+
/** Split one attributes line into its pattern and attribute tokens. */
|
|
365
|
+
function splitAttributesLine(line) {
|
|
366
|
+
let pattern;
|
|
367
|
+
let rest;
|
|
368
|
+
if (line.startsWith('"')) {
|
|
369
|
+
// C-style quoted pattern; only the escapes a path can need.
|
|
370
|
+
let i = 1;
|
|
371
|
+
let out = '';
|
|
372
|
+
for (; i < line.length && line[i] !== '"'; i++) {
|
|
373
|
+
if (line[i] === '\\' && i + 1 < line.length) {
|
|
374
|
+
i++;
|
|
375
|
+
out += line[i] === 't' ? '\t' : line[i] === 'n' ? '\n' : line[i];
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
out += line[i];
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
if (i >= line.length)
|
|
382
|
+
return null;
|
|
383
|
+
pattern = out;
|
|
384
|
+
rest = line.slice(i + 1);
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
const match = /^(\S+)(.*)$/.exec(line);
|
|
388
|
+
if (!match)
|
|
389
|
+
return null;
|
|
390
|
+
pattern = match[1];
|
|
391
|
+
rest = match[2];
|
|
392
|
+
}
|
|
393
|
+
return { pattern, attrs: rest.split(/\s+/).filter(Boolean) };
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Parse one .gitattributes file. Comments, blank lines, macro definitions
|
|
397
|
+
* (`[attr]...`) and negative patterns (forbidden by git) are skipped. The
|
|
398
|
+
* built-in `binary` macro is expanded to `-text`, which is the part of it this
|
|
399
|
+
* module reads.
|
|
400
|
+
*/
|
|
401
|
+
export function parseGitattributes(text) {
|
|
402
|
+
const rules = [];
|
|
403
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
404
|
+
const line = rawLine.trim();
|
|
405
|
+
if (!line || line.startsWith('#') || line.startsWith('[attr]'))
|
|
406
|
+
continue;
|
|
407
|
+
const split = splitAttributesLine(line);
|
|
408
|
+
if (!split || split.pattern.startsWith('!'))
|
|
409
|
+
continue;
|
|
410
|
+
let { pattern } = split;
|
|
411
|
+
// A pattern that only matches a directory never applies to the files
|
|
412
|
+
// inside it (git: "use path/** instead"), so it can classify nothing.
|
|
413
|
+
if (pattern.endsWith('/'))
|
|
414
|
+
continue;
|
|
415
|
+
const attrs = new Map();
|
|
416
|
+
for (const token of split.attrs) {
|
|
417
|
+
if (token.startsWith('-'))
|
|
418
|
+
attrs.set(token.slice(1), false);
|
|
419
|
+
else if (token.startsWith('!'))
|
|
420
|
+
attrs.set(token.slice(1), undefined);
|
|
421
|
+
else if (token.includes('=')) {
|
|
422
|
+
const eq = token.indexOf('=');
|
|
423
|
+
attrs.set(token.slice(0, eq), token.slice(eq + 1));
|
|
424
|
+
}
|
|
425
|
+
else
|
|
426
|
+
attrs.set(token, true);
|
|
427
|
+
}
|
|
428
|
+
if (attrs.get('binary') === true)
|
|
429
|
+
attrs.set('text', false);
|
|
430
|
+
if (attrs.size === 0)
|
|
431
|
+
continue;
|
|
432
|
+
const basenameOnly = !pattern.includes('/');
|
|
433
|
+
if (pattern.startsWith('/'))
|
|
434
|
+
pattern = pattern.slice(1);
|
|
435
|
+
rules.push({ re: globToRegex(pattern), basenameOnly, attrs });
|
|
436
|
+
}
|
|
437
|
+
return rules;
|
|
438
|
+
}
|
|
439
|
+
function booleanAttribute(value) {
|
|
440
|
+
if (value === true || value === 'true')
|
|
441
|
+
return true;
|
|
442
|
+
if (value === false || value === 'false')
|
|
443
|
+
return false;
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Resolve `linguist-vendored`, `linguist-generated` and binary-ness for one
|
|
448
|
+
* root-relative path. `layers` are applied root first, then deeper; within a
|
|
449
|
+
* file, later lines win - git's own order. `linguist-documentation` is not
|
|
450
|
+
* read: documentation is what agents read.
|
|
451
|
+
*/
|
|
452
|
+
export function linguistAttributesFor(relPath, layers) {
|
|
453
|
+
const path = posixPath(relPath);
|
|
454
|
+
const state = new Map();
|
|
455
|
+
// Array.prototype.sort is stable, so equal depths keep the caller's order.
|
|
456
|
+
const ordered = [...layers].sort((a, b) => depthOf(a.baseRel) - depthOf(b.baseRel));
|
|
457
|
+
for (const layer of ordered) {
|
|
458
|
+
let sub;
|
|
459
|
+
if (layer.baseRel === '')
|
|
460
|
+
sub = path;
|
|
461
|
+
else if (path.startsWith(`${layer.baseRel}/`))
|
|
462
|
+
sub = path.slice(layer.baseRel.length + 1);
|
|
463
|
+
else
|
|
464
|
+
continue;
|
|
465
|
+
const base = posix.basename(sub);
|
|
466
|
+
for (const rule of layer.rules) {
|
|
467
|
+
if (!(rule.basenameOnly ? rule.re.test(base) : rule.re.test(sub)))
|
|
468
|
+
continue;
|
|
469
|
+
for (const [name, value] of rule.attrs)
|
|
470
|
+
state.set(name, value);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return {
|
|
474
|
+
vendored: booleanAttribute(state.get('linguist-vendored')),
|
|
475
|
+
generated: booleanAttribute(state.get('linguist-generated')),
|
|
476
|
+
binary: state.get('text') === false,
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
function depthOf(baseRel) {
|
|
480
|
+
return baseRel === '' ? 0 : baseRel.split('/').length;
|
|
481
|
+
}
|
|
482
|
+
/** True when any rule in these layers can re-include a path (`-linguist-*` or `=false`). */
|
|
483
|
+
export function gitattributesCanReinclude(layers) {
|
|
484
|
+
return layers.some((layer) => layer.rules.some((rule) => ['linguist-vendored', 'linguist-generated'].some((name) => booleanAttribute(rule.attrs.get(name)) === false)));
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Should this path be indexed? `{ include: true }`, or
|
|
488
|
+
* `{ include: false, reason, rule }`. Hard rules are not this function's
|
|
489
|
+
* business: a caller excludes secrets, protected paths, symlinks, nested git
|
|
490
|
+
* boundaries, built-in directories and user-ignored paths first.
|
|
491
|
+
*/
|
|
492
|
+
export function classifyForIndex(relPath, options = {}) {
|
|
493
|
+
if (options.ignoreFileVerdict === 'unignored')
|
|
494
|
+
return { include: true, override: 'ignore_file' };
|
|
495
|
+
if (options.attributes && options.attributes.length > 0) {
|
|
496
|
+
const attrs = linguistAttributesFor(relPath, options.attributes);
|
|
497
|
+
if (attrs.vendored === true) {
|
|
498
|
+
return { include: false, reason: 'vendored', rule: '.gitattributes linguist-vendored' };
|
|
499
|
+
}
|
|
500
|
+
if (attrs.generated === true) {
|
|
501
|
+
return { include: false, reason: 'generated', rule: '.gitattributes linguist-generated' };
|
|
502
|
+
}
|
|
503
|
+
if (attrs.binary)
|
|
504
|
+
return { include: false, reason: 'binary', rule: '.gitattributes binary' };
|
|
505
|
+
if (attrs.vendored === false || attrs.generated === false) {
|
|
506
|
+
return { include: true, override: 'gitattributes' };
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
const byPath = softDefaultForPath(relPath);
|
|
510
|
+
if (byPath)
|
|
511
|
+
return { include: false, ...byPath };
|
|
512
|
+
if (options.content !== undefined) {
|
|
513
|
+
const byContent = softDefaultForContent(relPath, options.content);
|
|
514
|
+
if (byContent)
|
|
515
|
+
return { include: false, ...byContent };
|
|
516
|
+
}
|
|
517
|
+
return { include: true };
|
|
518
|
+
}
|
|
519
|
+
// ---------------------------------------------------------------------------
|
|
520
|
+
// Rule upload (daemon -> server)
|
|
521
|
+
// ---------------------------------------------------------------------------
|
|
522
|
+
/**
|
|
523
|
+
* The daemon uploads its root .gitignore / .mnemonikignore lines verbatim
|
|
524
|
+
* (`ignorePatterns`, the server's privacy list). The other rule lines the
|
|
525
|
+
* walk applied ride along as gitignore COMMENT lines, so a server or matcher
|
|
526
|
+
* that predates them reads them as comments and changes nothing:
|
|
527
|
+
*
|
|
528
|
+
* `#mnemonik:gitignore <dir>\t<line>` - a nested .gitignore /
|
|
529
|
+
* .mnemonikignore line, for
|
|
530
|
+
* `!pattern` overrides
|
|
531
|
+
* `#mnemonik:gitattributes <dir>\t<line>` - a .gitattributes line; <dir>
|
|
532
|
+
* is empty for the root file
|
|
533
|
+
*
|
|
534
|
+
* With them the server and retirement judge a path exactly as the daemon did.
|
|
535
|
+
*/
|
|
536
|
+
export const NESTED_IGNORE_TAG = '#mnemonik:gitignore ';
|
|
537
|
+
export const GITATTRIBUTES_TAG = '#mnemonik:gitattributes ';
|
|
538
|
+
export function encodeNestedIgnoreLine(baseRel, line) {
|
|
539
|
+
return `${NESTED_IGNORE_TAG}${baseRel}\t${line}`;
|
|
540
|
+
}
|
|
541
|
+
export function encodeGitattributesLine(baseRel, line) {
|
|
542
|
+
return `${GITATTRIBUTES_TAG}${baseRel}\t${line}`;
|
|
543
|
+
}
|
|
544
|
+
function decodeTagged(line, tag) {
|
|
545
|
+
if (!line.startsWith(tag))
|
|
546
|
+
return null;
|
|
547
|
+
const rest = line.slice(tag.length);
|
|
548
|
+
const tab = rest.indexOf('\t');
|
|
549
|
+
if (tab === -1)
|
|
550
|
+
return null;
|
|
551
|
+
const baseRel = rest.slice(0, tab);
|
|
552
|
+
if (baseRel.split('/').some((segment) => segment === '..'))
|
|
553
|
+
return null;
|
|
554
|
+
return { baseRel, body: rest.slice(tab + 1) };
|
|
555
|
+
}
|
|
556
|
+
export function decodeIndexRules(patterns) {
|
|
557
|
+
const decoded = {
|
|
558
|
+
rootIgnore: [],
|
|
559
|
+
nestedIgnore: new Map(),
|
|
560
|
+
attributes: new Map(),
|
|
561
|
+
};
|
|
562
|
+
for (const line of patterns) {
|
|
563
|
+
if (typeof line !== 'string')
|
|
564
|
+
continue;
|
|
565
|
+
const nested = decodeTagged(line, NESTED_IGNORE_TAG);
|
|
566
|
+
if (nested) {
|
|
567
|
+
if (nested.baseRel === '')
|
|
568
|
+
continue;
|
|
569
|
+
const lines = decoded.nestedIgnore.get(nested.baseRel) ?? [];
|
|
570
|
+
lines.push(nested.body);
|
|
571
|
+
decoded.nestedIgnore.set(nested.baseRel, lines);
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
const attr = decodeTagged(line, GITATTRIBUTES_TAG);
|
|
575
|
+
if (attr) {
|
|
576
|
+
const lines = decoded.attributes.get(attr.baseRel) ?? [];
|
|
577
|
+
lines.push(attr.body);
|
|
578
|
+
decoded.attributes.set(attr.baseRel, lines);
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
decoded.rootIgnore.push(line);
|
|
582
|
+
}
|
|
583
|
+
return decoded;
|
|
584
|
+
}
|
|
585
|
+
//# sourceMappingURL=indexClassifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexClassifier.js","sourceRoot":"","sources":["../src/indexClassifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Judge a stored or pushed path the way the daemon judged it, from the rules
|
|
3
|
+
* the daemon uploaded (`projects.scanner_ignore_patterns`).
|
|
4
|
+
*
|
|
5
|
+
* The daemon walks the disk with every rule file in front of it. The server
|
|
6
|
+
* never sees the disk; it has the root .gitignore / .mnemonikignore lines (the
|
|
7
|
+
* privacy list) plus the tagged nested-ignore and .gitattributes lines the
|
|
8
|
+
* daemon uploads beside them (`indexClassifier.ts`, "Rule upload"). This
|
|
9
|
+
* module rebuilds the same precedence from those lines so the /scan/push
|
|
10
|
+
* backstop, file_push, the dropped-path marker bookkeeping and retirement all
|
|
11
|
+
* reach the daemon's answer:
|
|
12
|
+
*
|
|
13
|
+
* hard built-in directories, secret files, the root ignore patterns
|
|
14
|
+
* (makeIgnoreMatcher - unchanged, never overridable), and a nested
|
|
15
|
+
* ignore file that ignores the path;
|
|
16
|
+
* soft classifyForIndex: `!pattern` and .gitattributes overrides, then the
|
|
17
|
+
* soft defaults - path rules always, content rules when content is
|
|
18
|
+
* supplied.
|
|
19
|
+
*/
|
|
20
|
+
import { type IndexExclusionReason } from './indexClassifier.js';
|
|
21
|
+
export type IndexJudgement = {
|
|
22
|
+
excluded: false;
|
|
23
|
+
/**
|
|
24
|
+
* Why the soft defaults did not apply: a project rule re-included the
|
|
25
|
+
* path, or it is an authority file (`AUTHORITY_FILE_MATCHERS`) - collected
|
|
26
|
+
* whole for doc-truth, never chunked, and never judged by the defaults on
|
|
27
|
+
* the daemon either. Content rules do not run for any of them.
|
|
28
|
+
*/
|
|
29
|
+
override?: 'ignore_file' | 'gitattributes' | 'authority';
|
|
30
|
+
} | {
|
|
31
|
+
excluded: true;
|
|
32
|
+
kind: 'hard';
|
|
33
|
+
rule: string;
|
|
34
|
+
} | {
|
|
35
|
+
excluded: true;
|
|
36
|
+
kind: 'soft';
|
|
37
|
+
reason: IndexExclusionReason;
|
|
38
|
+
rule: string;
|
|
39
|
+
};
|
|
40
|
+
export interface IndexJudge {
|
|
41
|
+
/** Hard rules and the path-only soft defaults, with the project's overrides. */
|
|
42
|
+
judgePath(relPath: string): IndexJudgement;
|
|
43
|
+
/**
|
|
44
|
+
* `judgePath`, then the content rules when `content` (decoded, scrubbed
|
|
45
|
+
* text) is supplied and no project rule re-included the path.
|
|
46
|
+
*/
|
|
47
|
+
judge(relPath: string, content?: string): IndexJudgement;
|
|
48
|
+
}
|
|
49
|
+
export declare function makeIndexJudge(storedPatterns?: readonly string[]): IndexJudge;
|
|
50
|
+
//# sourceMappingURL=indexJudge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexJudge.d.ts","sourceRoot":"","sources":["../src/indexJudge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAOL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,cAAc,GACtB;IACE,QAAQ,EAAE,KAAK,CAAC;IAChB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,aAAa,GAAG,eAAe,GAAG,WAAW,CAAC;CAC1D,GACD;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjF,MAAM,WAAW,UAAU;IACzB,gFAAgF;IAChF,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAAC;IAC3C;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC;CAC1D;AAuCD,wBAAgB,cAAc,CAAC,cAAc,GAAE,SAAS,MAAM,EAAO,GAAG,UAAU,CAuDjF"}
|