@mnemonik/shared 7.119.2 → 7.120.1
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/gitEditDetector.d.ts +91 -0
- package/dist/gitEditDetector.d.ts.map +1 -1
- package/dist/gitEditDetector.js +515 -3
- package/dist/gitEditDetector.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/gitEditDetector.ts +578 -3
- package/src/index.ts +34 -0
- package/src/indexClassifier.ts +681 -0
- package/src/indexJudge.ts +149 -0
package/dist/codeScanner.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Code Scanner - Parse and chunk source files for embedding
|
|
3
3
|
*/
|
|
4
4
|
import { type Stats } from 'fs';
|
|
5
|
+
import { type IndexExclusionReason } from './indexClassifier.js';
|
|
5
6
|
/**
|
|
6
7
|
* The one file-size ceiling in Mnemonik. A file at or below this is scanned,
|
|
7
8
|
* chunked, AND pushed verbatim; a file above it is uniformly outside the
|
|
@@ -66,6 +67,24 @@ export interface ScanOptions {
|
|
|
66
67
|
/** Additional protected paths for isolated homes/tests; defaults can only be extended. */
|
|
67
68
|
protectedPaths?: readonly string[];
|
|
68
69
|
}
|
|
70
|
+
/** The rule-file lines one directory contributed to a walk. */
|
|
71
|
+
export interface IndexRuleFiles {
|
|
72
|
+
/** .gitignore + .mnemonikignore lines, unioned, in read order. */
|
|
73
|
+
ignore: string[];
|
|
74
|
+
/** .gitattributes lines, in read order. */
|
|
75
|
+
attributes: string[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A file a walk declined to index because a soft default excluded it.
|
|
79
|
+
* `stage: 'content'` means the file was read and its content decided.
|
|
80
|
+
*/
|
|
81
|
+
export interface IndexExcludedFile {
|
|
82
|
+
/** Root-relative POSIX path, spelled as a chunk's `filePath`. */
|
|
83
|
+
path: string;
|
|
84
|
+
reason: IndexExclusionReason;
|
|
85
|
+
rule: string;
|
|
86
|
+
stage: 'path' | 'content';
|
|
87
|
+
}
|
|
69
88
|
/**
|
|
70
89
|
* Directory basenames the scanner never indexes, across every ecosystem -
|
|
71
90
|
* generated output, package-manager/build caches, and vendored deps. SINGLE
|
|
@@ -139,12 +158,11 @@ export declare function isAuthorityOnlyPath(relPath: string): boolean;
|
|
|
139
158
|
*/
|
|
140
159
|
export declare const AUTHORITY_FILE_MATCHERS: Array<(relPath: string) => boolean>;
|
|
141
160
|
/**
|
|
142
|
-
* Segment-anchored match for
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
* share one definition instead of hand-rolling copies that can drift.
|
|
161
|
+
* Segment-anchored match for `tests/fixtures/` - matches at the path root or
|
|
162
|
+
* immediately after a `/`. Indexing no longer uses it (the fixture rule is the
|
|
163
|
+
* soft default in indexClassifier.ts, which a project can override); it stays
|
|
164
|
+
* for query-time hygiene over rows indexed before that rule existed
|
|
165
|
+
* (`MemoryManager.searchCodePointers`).
|
|
148
166
|
*/
|
|
149
167
|
export declare const FIXTURE_PATH_RE: RegExp;
|
|
150
168
|
export declare function isFixturePath(path: string): boolean;
|
|
@@ -220,28 +238,59 @@ export declare class CodeScanner {
|
|
|
220
238
|
*/
|
|
221
239
|
private isChunkable;
|
|
222
240
|
/**
|
|
223
|
-
* Read `.gitignore` + `.mnemonikignore` in `absDir` and
|
|
224
|
-
*
|
|
225
|
-
* additional gitignore-syntax exclusion list).
|
|
226
|
-
* exists. FAIL-CLOSED: a non-ENOENT read
|
|
227
|
-
* latches `walk.complete = false` so callers
|
|
228
|
-
* treat it as untrustworthy rather than
|
|
241
|
+
* Read `.gitignore` + `.mnemonikignore` + `.gitattributes` in `absDir` and
|
|
242
|
+
* compile them into one layer (the two ignore files are unioned -
|
|
243
|
+
* `.mnemonikignore` is just an additional gitignore-syntax exclusion list).
|
|
244
|
+
* Returns null when none of the three exists. FAIL-CLOSED: a non-ENOENT read
|
|
245
|
+
* error (EISDIR, EACCES, timeout) latches `walk.complete = false` so callers
|
|
246
|
+
* deriving *removals* from the walk treat it as untrustworthy rather than
|
|
247
|
+
* silently ignoring nothing.
|
|
229
248
|
*/
|
|
230
249
|
private loadIgnoreLayer;
|
|
231
250
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* ignores OR re-includes (via a `!negation`) wins,
|
|
235
|
-
* deeper `.gitignore` overrides a shallower one.
|
|
236
|
-
* trailing slash so `foo/` dir-only rules
|
|
251
|
+
* What the .gitignore / .mnemonikignore layers in `stack` say about
|
|
252
|
+
* `entryRel` (relative to the scan root). Tested deepest-first: the first
|
|
253
|
+
* layer that explicitly ignores OR re-includes (via a `!negation`) wins,
|
|
254
|
+
* matching git's rule that a deeper `.gitignore` overrides a shallower one.
|
|
255
|
+
* Directories are tested with a trailing slash so `foo/` dir-only rules
|
|
256
|
+
* match the directory itself. `'unignored'` means a negation matched this
|
|
257
|
+
* path itself; a re-included parent directory leaves its files `'unmatched'`.
|
|
237
258
|
*/
|
|
259
|
+
private ignoreVerdict;
|
|
238
260
|
private ignoredByStack;
|
|
261
|
+
private static attributeLayers;
|
|
262
|
+
/**
|
|
263
|
+
* Skip this directory? User-ignored directories are skipped as before. A
|
|
264
|
+
* directory a soft default excludes (vendor/, generated/, ...) is pruned too -
|
|
265
|
+
* nothing under it can be indexed - UNLESS a rule above it could re-include
|
|
266
|
+
* something inside it: a `!pattern` or a `-linguist-*` attribute. Then the
|
|
267
|
+
* walk descends and judges each file, so the override works. Rule files
|
|
268
|
+
* INSIDE a pruned directory are never read: a vendored library's own
|
|
269
|
+
* .gitignore negations are not the project's intent.
|
|
270
|
+
*/
|
|
271
|
+
private skipDirectory;
|
|
272
|
+
/**
|
|
273
|
+
* The index decision for a file from its path and the rule stack: `null`
|
|
274
|
+
* when a user ignore rule excludes it, otherwise the classifier's answer
|
|
275
|
+
* (precedence in indexClassifier.ts). Content rules are the caller's next
|
|
276
|
+
* step for an included path without an `override`.
|
|
277
|
+
*/
|
|
278
|
+
private classifyEntry;
|
|
239
279
|
/**
|
|
240
280
|
* Reconstruct the root->parent ignore-layer stack for a single file, for the
|
|
241
281
|
* incremental `scanFiles` path (which has a flat file list, not a recursive
|
|
242
282
|
* walk). Layers are memoized per directory in `cache` across a batch.
|
|
243
283
|
*/
|
|
244
284
|
private buildIgnoreStackForFile;
|
|
285
|
+
/**
|
|
286
|
+
* A predicate for walkers outside this class (the daemon's file watcher):
|
|
287
|
+
* true when the walk would descend into `absDir`, by the same rules
|
|
288
|
+
* `listFiles` applies - user ignore files and soft-default directories,
|
|
289
|
+
* with their overrides. Rule files are read once per directory for the life
|
|
290
|
+
* of the returned predicate; take a fresh one after a rule file changes.
|
|
291
|
+
* Directories outside `rootPath`, and the root itself, always pass.
|
|
292
|
+
*/
|
|
293
|
+
directoryFilter(rootPath: string): (absDir: string) => Promise<boolean>;
|
|
245
294
|
/**
|
|
246
295
|
* True when any directory strictly between `rootPath` and `filePath`
|
|
247
296
|
* carries its own `.git` entry (see isGitBoundary). Paths that don't
|
|
@@ -280,6 +329,8 @@ export declare class CodeScanner {
|
|
|
280
329
|
chunks: CodeChunk[];
|
|
281
330
|
complete: boolean;
|
|
282
331
|
chunkless: string[];
|
|
332
|
+
/** Files a soft default excluded by their content (path exclusions are not listed). */
|
|
333
|
+
excluded: IndexExcludedFile[];
|
|
283
334
|
}>;
|
|
284
335
|
/**
|
|
285
336
|
* Enumerate scan-eligible relative file paths under `rootPath` without
|
|
@@ -308,7 +359,20 @@ export declare class CodeScanner {
|
|
|
308
359
|
listFilesWithStatus(rootPath: string): Promise<{
|
|
309
360
|
paths: string[];
|
|
310
361
|
complete: boolean;
|
|
362
|
+
/**
|
|
363
|
+
* Listed paths a project rule re-included (a `!pattern` or a
|
|
364
|
+
* `-linguist-*` attribute). Content rules do not apply to them; every
|
|
365
|
+
* other listed path still answers to the content rules when read.
|
|
366
|
+
*/
|
|
367
|
+
overridden: Set<string>;
|
|
311
368
|
}>;
|
|
369
|
+
/**
|
|
370
|
+
* The rule files the last complete `listFilesWithStatus` walk of `rootPath`
|
|
371
|
+
* applied, by directory ('' = root). Null before the first complete walk.
|
|
372
|
+
* The daemon uploads these lines so the server judges paths as it did.
|
|
373
|
+
*/
|
|
374
|
+
indexRuleFiles(rootPath: string): Promise<ReadonlyMap<string, IndexRuleFiles> | null>;
|
|
375
|
+
private readonly ruleFilesByRoot;
|
|
312
376
|
private traversePaths;
|
|
313
377
|
/**
|
|
314
378
|
* Scan specific files and extract code chunks.
|
|
@@ -319,8 +383,13 @@ export declare class CodeScanner {
|
|
|
319
383
|
* but yielded no chunk because each section fell under `minChunkSize`. The
|
|
320
384
|
* daemon still pushes such a file's whole content: it is a doc the project
|
|
321
385
|
* owns, and it would otherwise never reach the server.
|
|
386
|
+
*
|
|
387
|
+
* `excluded`, when given, receives every chunkable file a soft default
|
|
388
|
+
* excluded (indexClassifier.ts), by path or by content. The daemon tells the
|
|
389
|
+
* server about content exclusions so the server can retire what an earlier
|
|
390
|
+
* version of the file left in the index.
|
|
322
391
|
*/
|
|
323
|
-
scanFiles(filePaths: string[], rootPath: string, chunkless?: string[]): Promise<CodeChunk[]>;
|
|
392
|
+
scanFiles(filePaths: string[], rootPath: string, chunkless?: string[], excluded?: IndexExcludedFile[]): Promise<CodeChunk[]>;
|
|
324
393
|
/**
|
|
325
394
|
* Daemon-side secret redaction: scrub credentials from chunk content
|
|
326
395
|
* before they leave this process. contentHash is recomputed from the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeScanner.d.ts","sourceRoot":"","sources":["../src/codeScanner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"codeScanner.d.ts","sourceRoot":"","sources":["../src/codeScanner.ts"],"names":[],"mappings":"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"}
|