@any-nav/scan 0.1.0 → 0.2.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/CHANGELOG.md +62 -0
- package/README.md +39 -12
- package/dist/budget.d.ts +26 -0
- package/dist/budget.js +25 -0
- package/dist/budget.js.map +1 -0
- package/dist/description.d.ts +24 -13
- package/dist/description.js +46 -27
- package/dist/description.js.map +1 -1
- package/dist/engine-mapping.d.ts +48 -0
- package/dist/engine-mapping.js +127 -0
- package/dist/engine-mapping.js.map +1 -0
- package/dist/hydration.d.ts +49 -0
- package/dist/hydration.js +181 -0
- package/dist/hydration.js.map +1 -0
- package/dist/index.d.ts +17 -6
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/scan.d.ts +6 -42
- package/dist/scan.js +39 -488
- package/dist/scan.js.map +1 -1
- package/dist/tree-replay.d.ts +61 -0
- package/dist/tree-replay.js +256 -0
- package/dist/tree-replay.js.map +1 -0
- package/dist/types.d.ts +18 -6
- package/package.json +11 -3
- package/dist/gitignore.d.ts +0 -9
- package/dist/gitignore.js +0 -128
- package/dist/gitignore.js.map +0 -1
package/dist/scan.js
CHANGED
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Scan: walk a Markdown folder into a NavTree under the routes traversal
|
|
3
|
-
* semantics (
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
3
|
+
* semantics (absorption — port, don't rewrite). Since the pathscope
|
|
4
|
+
* delegation (facade transition: the public API and
|
|
5
|
+
* behavior stand, the walk engine is swapped) the scan is two layers:
|
|
6
|
+
*
|
|
7
|
+
* - engine — @catheadowl/pathscope `walkScope` answers "which files are in
|
|
8
|
+
* scope": the gitignore cascade (nested, plus inheritance above the scan
|
|
9
|
+
* root), mounted exclusion presets
|
|
10
|
+
* (vcs/deps/build = the old nine-entry floor plus vendor/ and coverage/,
|
|
11
|
+
* an accepted increment; agentDocs = the built-in AGENTS.md/CLAUDE.md
|
|
12
|
+
* exclusion), the policy layer carrying the resolved excludeDirs (rear
|
|
13
|
+
* seat: gitignore negations cannot resurrect a floor entry, as before),
|
|
14
|
+
* the dot category, and boundary stones. respectGitignore and
|
|
15
|
+
* excludeDotEntries pass straight through.
|
|
16
|
+
* - consumer replay (this package) — the Markdown-only post-filter, the
|
|
17
|
+
* case-insensitive excludeFiles check, the sorted (localeCompare) DFS
|
|
18
|
+
* assembly with empty-directory pruning, the maxFiles budget (its unit
|
|
19
|
+
* is a TREE ENTRY — a Markdown file surviving the filters — so the
|
|
20
|
+
* engine query runs unbounded and the replay owns the fact-safe cut and
|
|
21
|
+
* its diagnostics), NavNode/markdown-locator assembly, and the
|
|
22
|
+
* description chains: folder descriptions from the directory's
|
|
23
|
+
* standardized carriers in order — its `package.json` `description`,
|
|
24
|
+
* then its `manifest.yml` `metadata.description` — else from
|
|
25
|
+
* the folder's own README.md; dir nodes also carry
|
|
26
|
+
* `markdown` — the representative README child's path, present iff the
|
|
27
|
+
* tree contains it, known from enumeration alone in both
|
|
28
|
+
* walks. Description extraction is the ported routes chain
|
|
29
|
+
* (description.ts); null falls to core's placeholder + diagnostic,
|
|
30
|
+
* which routes does not have and core keeps (stricter).
|
|
10
31
|
*
|
|
11
32
|
* Read-only by contract: scanning must never modify source files
|
|
12
33
|
* (map is not territory).
|
|
@@ -20,366 +41,18 @@
|
|
|
20
41
|
* to the serial walk this replaced — and fetch a bounded head that provably
|
|
21
42
|
* covers the extraction chain's input (frontmatter + the body-head window),
|
|
22
43
|
* extended adaptively, never more bytes than the chain can consume.
|
|
44
|
+
*
|
|
45
|
+
* File split 2026-10-24: this module keeps the two entry points and their
|
|
46
|
+
* output faces; the four blocks they share live beside it — engine-mapping
|
|
47
|
+
* (options/preset mapping + the walkScope bridge), tree-replay (the sorted
|
|
48
|
+
* DFS replay), budget (the maxFiles state + cut diagnostics), hydration
|
|
49
|
+
* (the read pipeline + provider face).
|
|
23
50
|
*/
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Agent-instruction files harnesses load on their own; they carry no
|
|
31
|
-
* navigation value (the agent already has them) so they never appear in
|
|
32
|
-
* navigation (routes DEFAULT_EXCLUDE_FILES, ported).
|
|
33
|
-
*/
|
|
34
|
-
export const DEFAULT_EXCLUDE_FILES = ['AGENTS.md', 'CLAUDE.md'];
|
|
35
|
-
/** routes DEFAULT_EXCLUDE_DIRS, ported verbatim. Always on (the safety
|
|
36
|
-
* floor); user excludeDirs entries append to it, never replace it — a
|
|
37
|
-
* generate-era 'any-nav' entry was retired with `list --write` (the
|
|
38
|
-
* materialization target is now any file the caller names). */
|
|
39
|
-
export const DEFAULT_EXCLUDE_DIRS = [
|
|
40
|
-
'.git',
|
|
41
|
-
'.hg',
|
|
42
|
-
'.svn',
|
|
43
|
-
'node_modules',
|
|
44
|
-
'.pnpm',
|
|
45
|
-
'dist',
|
|
46
|
-
'build',
|
|
47
|
-
'lib',
|
|
48
|
-
'out',
|
|
49
|
-
];
|
|
50
|
-
export function resolveScanOptions(config) {
|
|
51
|
-
// Additive ruling (ADR-0010 update 2026-10-07): the built-in tables are the
|
|
52
|
-
// always-on floor, user entries append — "the file states only exceptions"
|
|
53
|
-
// must not mean restating the defaults to add one. Duplicates are harmless
|
|
54
|
-
// (membership checks only), so a plain concat stays honest.
|
|
55
|
-
return {
|
|
56
|
-
excludeDirs: [...DEFAULT_EXCLUDE_DIRS, ...(config?.excludeDirs ?? [])],
|
|
57
|
-
excludeFiles: [...DEFAULT_EXCLUDE_FILES, ...(config?.excludeFiles ?? [])],
|
|
58
|
-
excludeDotEntries: config?.excludeDotEntries ?? true,
|
|
59
|
-
respectGitignore: config?.respectGitignore ?? true,
|
|
60
|
-
maxFiles: config?.maxFiles ?? 2000,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
export const builtinDescriptionProvider = {
|
|
64
|
-
extract: (file) => Promise.resolve(extractDescription(file.content)),
|
|
65
|
-
};
|
|
66
|
-
export function isExcludedFileName(name, excludeFiles) {
|
|
67
|
-
if (excludeFiles.length === 0)
|
|
68
|
-
return false;
|
|
69
|
-
const lower = name.toLowerCase();
|
|
70
|
-
return excludeFiles.some((excluded) => excluded.toLowerCase() === lower);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Directory description sidecars (2026-10-07): the Docusaurus ecosystem
|
|
74
|
-
* names — a folder may state its navigation description in one of these
|
|
75
|
-
* instead of its README (release-face READMEs stay untouched). The first
|
|
76
|
-
* existing name in this order is authoritative; the files are never Markdown
|
|
77
|
-
* so they never enter the tree, and they never consume the maxFiles budget.
|
|
78
|
-
*/
|
|
79
|
-
export const DIR_SIDECAR_NAMES = ['_category_.yml', '_category_.yaml', '_category_.json'];
|
|
80
|
-
export function isDirSidecarName(name) {
|
|
81
|
-
const lower = name.toLowerCase();
|
|
82
|
-
return DIR_SIDECAR_NAMES.some((sidecar) => sidecar === lower);
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Whether a directory's already-listed entries carry a .gitignore — the
|
|
86
|
-
* walk opens the file only when readdir saw it, skipping the failing
|
|
87
|
-
* probe open per gitignore-less directory that dominated large-tree scan
|
|
88
|
-
* latency (case-insensitive: a case-insensitive filesystem would have
|
|
89
|
-
* resolved the probe open the same way).
|
|
90
|
-
*/
|
|
91
|
-
function carriesGitignore(entries) {
|
|
92
|
-
return entries.some((entry) => entry.isFile() && entry.name.toLowerCase() === '.gitignore');
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Read the directory's sidecar description from its already-listed entries.
|
|
96
|
-
* Returns undefined when no sidecar exists, when the authoritative one is
|
|
97
|
-
* gitignored (traversal honors the same rules as content), or when it carries
|
|
98
|
-
* no description key — the README chain then fills in. Unreadable or invalid
|
|
99
|
-
* sidecars fire a loud diagnostic and fall through the same way.
|
|
100
|
-
*/
|
|
101
|
-
async function sidecarDescription(absDir, relDir, entries, ctx, gitignoreRules) {
|
|
102
|
-
for (const sidecarName of DIR_SIDECAR_NAMES) {
|
|
103
|
-
const entry = entries.find((candidate) => candidate.name.toLowerCase() === sidecarName && candidate.isFile());
|
|
104
|
-
if (entry === undefined)
|
|
105
|
-
continue;
|
|
106
|
-
const abs = join(absDir, entry.name);
|
|
107
|
-
if (ctx.opts.respectGitignore && isGitignored(abs, false, gitignoreRules))
|
|
108
|
-
return undefined;
|
|
109
|
-
const rel = relDir === '' ? entry.name : `${relDir}/${entry.name}`;
|
|
110
|
-
let content;
|
|
111
|
-
try {
|
|
112
|
-
content = await readFile(abs, 'utf8');
|
|
113
|
-
}
|
|
114
|
-
catch {
|
|
115
|
-
ctx.events.push({
|
|
116
|
-
kind: 'diag',
|
|
117
|
-
diagnostic: {
|
|
118
|
-
code: 'sidecar-unreadable',
|
|
119
|
-
severity: 'warning',
|
|
120
|
-
message: `Unable to read directory description sidecar ${rel}.`,
|
|
121
|
-
path: rel,
|
|
122
|
-
audience: 'maintainer',
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
return undefined;
|
|
126
|
-
}
|
|
127
|
-
const read = extractSidecarDescription(entry.name, content);
|
|
128
|
-
if ('error' in read) {
|
|
129
|
-
ctx.events.push({
|
|
130
|
-
kind: 'diag',
|
|
131
|
-
diagnostic: {
|
|
132
|
-
code: 'sidecar-unreadable',
|
|
133
|
-
severity: 'warning',
|
|
134
|
-
message: `Directory description sidecar ${rel}: ${read.error}.`,
|
|
135
|
-
path: rel,
|
|
136
|
-
audience: 'maintainer',
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
return undefined;
|
|
140
|
-
}
|
|
141
|
-
return read.description !== null && read.description.trim() !== '' ? read.description : undefined;
|
|
142
|
-
}
|
|
143
|
-
return undefined;
|
|
144
|
-
}
|
|
145
|
-
/** Read fan-out ceiling: the 2026-10-20 probe saturated at 8 lanes (~4.3x,
|
|
146
|
-
* 39→9ms over 177 files) with nothing at 16 — the window keeps stragglers
|
|
147
|
-
* from stalling the pipeline and bounds transient memory to the window's
|
|
148
|
-
* in-flight file heads. */
|
|
149
|
-
const MAX_INFLIGHT_READS = 16;
|
|
150
|
-
/** Bounded in-flight read window: kicks never reject (read errors resolve
|
|
151
|
-
* null — the unreadable-file path), and the gate waits for the next settle
|
|
152
|
-
* before kicking past the ceiling. gate() then start() keeps the started
|
|
153
|
-
* promise unwrapped for fire-and-continue callers. */
|
|
154
|
-
class BoundedReads {
|
|
155
|
-
pending = [];
|
|
156
|
-
/** Wait for a window slot (no-op while under the ceiling). */
|
|
157
|
-
async gate() {
|
|
158
|
-
if (this.pending.length >= MAX_INFLIGHT_READS) {
|
|
159
|
-
await Promise.race(this.pending);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
/** Start one read and return its still-running promise. */
|
|
163
|
-
start(abs) {
|
|
164
|
-
const content = readDescriptionInput(abs);
|
|
165
|
-
this.pending.push(content);
|
|
166
|
-
void content.then(() => {
|
|
167
|
-
const index = this.pending.indexOf(content);
|
|
168
|
-
if (index !== -1)
|
|
169
|
-
this.pending.splice(index, 1);
|
|
170
|
-
});
|
|
171
|
-
return content;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
/** First head rung and the extension factor: extraction reads frontmatter
|
|
175
|
-
* plus a 15-line body-head window (fences/HTML comments stripped inside
|
|
176
|
-
* it), so a head closing the frontmatter and showing 16+ open body lines
|
|
177
|
-
* with nothing dangling at the cut is provably equivalent to the full file
|
|
178
|
-
* for the chain — the ladder only climbs for long frontmatter or
|
|
179
|
-
* fence/comment-heavy heads. */
|
|
180
|
-
const DESC_HEAD_BYTES = 16 * 1024;
|
|
181
|
-
const DESC_HEAD_LADDER = 4;
|
|
182
|
-
/**
|
|
183
|
-
* Read the file head the description chain consumes — never more bytes than
|
|
184
|
-
* the chain can read, provably equivalent input or the ladder climbs (the
|
|
185
|
-
* whole file is the terminal rung). Any I/O error resolves null (the
|
|
186
|
-
* unreadable-file path); the full readFile this replaced had the same
|
|
187
|
-
* contract with far more bytes.
|
|
188
|
-
*/
|
|
189
|
-
async function readDescriptionInput(abs) {
|
|
190
|
-
let handle;
|
|
191
|
-
try {
|
|
192
|
-
handle = await open(abs);
|
|
193
|
-
}
|
|
194
|
-
catch {
|
|
195
|
-
return null;
|
|
196
|
-
}
|
|
197
|
-
try {
|
|
198
|
-
let capacity = DESC_HEAD_BYTES;
|
|
199
|
-
for (;;) {
|
|
200
|
-
const bytes = await readUpTo(handle, capacity);
|
|
201
|
-
const text = bytes.toString('utf8');
|
|
202
|
-
if (bytes.length < capacity || headCoversExtraction(text))
|
|
203
|
-
return text;
|
|
204
|
-
capacity *= DESC_HEAD_LADDER;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
catch {
|
|
208
|
-
return null;
|
|
209
|
-
}
|
|
210
|
-
finally {
|
|
211
|
-
await handle.close().catch(() => { });
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
async function readUpTo(handle, capacity) {
|
|
215
|
-
const buffer = Buffer.alloc(capacity);
|
|
216
|
-
let filled = 0;
|
|
217
|
-
while (filled < capacity) {
|
|
218
|
-
const { bytesRead } = await handle.read(buffer, filled, capacity - filled, filled);
|
|
219
|
-
if (bytesRead === 0)
|
|
220
|
-
break;
|
|
221
|
-
filled += bytesRead;
|
|
222
|
-
}
|
|
223
|
-
return filled === capacity ? buffer : buffer.subarray(0, filled);
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Whether a head provably covers every byte extractDescription reads:
|
|
227
|
-
* frontmatter closed when opened; past it, at least BODY_HEAD_LINE_LIMIT + 1
|
|
228
|
-
* open lines (the chain slices 15 — the +1 guarantees the 15th ended with a
|
|
229
|
-
* newline and is complete) with no code fence or HTML comment left dangling
|
|
230
|
-
* at the cut (mirrors stripCodeFences / stripHtmlComments state shapes; a
|
|
231
|
-
* dangling marker means later content could still change the strip).
|
|
232
|
-
*/
|
|
233
|
-
function headCoversExtraction(text) {
|
|
234
|
-
const lines = text.split(/\r?\n/u);
|
|
235
|
-
let start = 0;
|
|
236
|
-
if (lines[0]?.trim() === '---') {
|
|
237
|
-
const end = lines.findIndex((line, index) => index > 0 && line.trim() === '---');
|
|
238
|
-
if (end === -1)
|
|
239
|
-
return false;
|
|
240
|
-
start = end + 1;
|
|
241
|
-
}
|
|
242
|
-
let inFence = false;
|
|
243
|
-
let inComment = false;
|
|
244
|
-
let openLines = 0;
|
|
245
|
-
for (let index = start; index < lines.length; index += 1) {
|
|
246
|
-
const line = lines[index];
|
|
247
|
-
if (/^\s*(`{3,}|~{3,})/u.test(line)) {
|
|
248
|
-
inFence = !inFence;
|
|
249
|
-
continue;
|
|
250
|
-
}
|
|
251
|
-
if (inFence)
|
|
252
|
-
continue;
|
|
253
|
-
let rest = line;
|
|
254
|
-
while (rest.length > 0) {
|
|
255
|
-
if (!inComment) {
|
|
256
|
-
const opens = rest.indexOf('<!--');
|
|
257
|
-
if (opens === -1)
|
|
258
|
-
break;
|
|
259
|
-
rest = rest.slice(opens + 4);
|
|
260
|
-
inComment = true;
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
const closes = rest.indexOf('-->');
|
|
264
|
-
if (closes === -1) {
|
|
265
|
-
rest = '';
|
|
266
|
-
break;
|
|
267
|
-
}
|
|
268
|
-
rest = rest.slice(closes + 3);
|
|
269
|
-
inComment = false;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
openLines += 1;
|
|
273
|
-
}
|
|
274
|
-
return !inFence && !inComment && openLines >= BODY_HEAD_LINE_LIMIT + 1;
|
|
275
|
-
}
|
|
276
|
-
/** Settle one started read: the description lands on the item and any
|
|
277
|
-
* per-file diagnostic (unreadable-file / no-description placeholder) goes
|
|
278
|
-
* to the sink at the caller's position. */
|
|
279
|
-
async function settleDescription(read, provider, sink) {
|
|
280
|
-
const content = await read.content;
|
|
281
|
-
if (content === null) {
|
|
282
|
-
// routes port: an unreadable Markdown file still becomes a bare-path
|
|
283
|
-
// route (diagnostic fires, the entry survives) — it must not silently
|
|
284
|
-
// vanish from navigation, and it still consumes the maxFiles budget.
|
|
285
|
-
sink.push({
|
|
286
|
-
code: 'unreadable-file',
|
|
287
|
-
severity: 'warning',
|
|
288
|
-
message: `Unable to read Markdown file ${read.rel}.`,
|
|
289
|
-
path: read.rel,
|
|
290
|
-
audience: 'maintainer',
|
|
291
|
-
});
|
|
292
|
-
read.item.description = `Undocumented — unreadable file ${read.rel}`;
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
const extracted = await provider.extract({ path: read.rel, content });
|
|
296
|
-
read.item.description =
|
|
297
|
-
extracted !== null && extracted.trim() !== '' ? extracted : placeholder(read.rel, sink);
|
|
298
|
-
}
|
|
299
|
-
/**
|
|
300
|
-
* Post-walk folder descriptions, bottom-up over the assembled tree — the
|
|
301
|
-
* same chain the serial walk computed inline: sidecar first, else the
|
|
302
|
-
* folder's own first README child (children are name-sorted) carrying a
|
|
303
|
-
* real description. Runs after the settle, so file descriptions are final.
|
|
304
|
-
*/
|
|
305
|
-
function assignFolderDescriptions(node, ctx) {
|
|
306
|
-
let readmeDescription;
|
|
307
|
-
for (const child of node.children ?? []) {
|
|
308
|
-
if (child.kind === 'dir')
|
|
309
|
-
assignFolderDescriptions(child, ctx);
|
|
310
|
-
if (readmeDescription === undefined &&
|
|
311
|
-
child.kind === 'file' &&
|
|
312
|
-
child.name.toLowerCase() === 'readme' &&
|
|
313
|
-
child.item !== undefined &&
|
|
314
|
-
!child.item.description.startsWith('Undocumented')) {
|
|
315
|
-
readmeDescription = child.item.description;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
const description = ctx.sidecars.get(node) ?? readmeDescription;
|
|
319
|
-
if (description !== undefined)
|
|
320
|
-
node.description = description;
|
|
321
|
-
}
|
|
322
|
-
async function performWalk(root, options, eager) {
|
|
323
|
-
const opts = options ?? resolveScanOptions();
|
|
324
|
-
const budget = { files: 0, limitHit: opts.maxFiles <= 0 };
|
|
325
|
-
const ctx = {
|
|
326
|
-
opts,
|
|
327
|
-
events: [],
|
|
328
|
-
files: new Map(),
|
|
329
|
-
sidecars: new Map(),
|
|
330
|
-
reads: new BoundedReads(),
|
|
331
|
-
eager,
|
|
332
|
-
countIncompletePaths: [],
|
|
333
|
-
};
|
|
334
|
-
const rootEntries = await sortedEntries(root, ctx);
|
|
335
|
-
// The readdir already says whether the root carries a .gitignore — probe
|
|
336
|
-
// opens for the (common) absent case are pure walk-thread latency, so
|
|
337
|
-
// only real files are opened (the same gate applies per directory below).
|
|
338
|
-
const rootRules = opts.respectGitignore && carriesGitignore(rootEntries)
|
|
339
|
-
? await readGitignoreRules(root)
|
|
340
|
-
: [];
|
|
341
|
-
// Root description: the same chain as any directory — sidecar first, else
|
|
342
|
-
// the root README's own extraction (uniform semantics, no root special case).
|
|
343
|
-
const rootSidecar = await sidecarDescription(root, '', rootEntries, ctx, rootRules);
|
|
344
|
-
const children = [];
|
|
345
|
-
for (const entry of rootEntries) {
|
|
346
|
-
if (isDirSidecarName(entry.name))
|
|
347
|
-
continue; // consumed by rootSidecar above
|
|
348
|
-
const node = await scanEntry(root, root, entry, ctx, rootRules, budget);
|
|
349
|
-
if (node === null)
|
|
350
|
-
continue;
|
|
351
|
-
children.push(node);
|
|
352
|
-
}
|
|
353
|
-
const tree = rootNode(root);
|
|
354
|
-
if (children.length > 0)
|
|
355
|
-
tree.children = children;
|
|
356
|
-
ctx.sidecars.set(tree, rootSidecar);
|
|
357
|
-
return { ctx, tree, itemCount: budget.files, events: ctx.events, limitHit: budget.limitHit };
|
|
358
|
-
}
|
|
359
|
-
function fileLimitDiagnostic(maxFiles) {
|
|
360
|
-
return {
|
|
361
|
-
code: 'file-limit-reached',
|
|
362
|
-
severity: 'warning',
|
|
363
|
-
message: `Markdown file limit (${maxFiles}) reached while scanning; entries past the limit were not examined — folders whose descent was cut carry ≥ counts (a floor, not the total) and later folders are absent. Raise scan.maxFiles for the full tree.`,
|
|
364
|
-
path: '.',
|
|
365
|
-
audience: 'consumer',
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* Per-row disclosure for one floor-count folder (ADR-0010 U12): the budget
|
|
370
|
-
* cut this folder's descent mid-way, so the count a view renders for it is
|
|
371
|
-
* a floor. Consumer audience — it is view fidelity, same class as
|
|
372
|
-
* file-limit-reached.
|
|
373
|
-
*/
|
|
374
|
-
function countTruncatedDiagnostic(rel) {
|
|
375
|
-
return {
|
|
376
|
-
code: 'count-truncated-at-limit',
|
|
377
|
-
severity: 'warning',
|
|
378
|
-
message: `The maxFiles budget cut this folder's descent short; its shown count is a floor (at least that many), and entries past the cut point are absent.`,
|
|
379
|
-
path: rel,
|
|
380
|
-
audience: 'consumer',
|
|
381
|
-
};
|
|
382
|
-
}
|
|
51
|
+
import { stat } from 'node:fs/promises';
|
|
52
|
+
import { fileLimitDiagnostic } from './budget.js';
|
|
53
|
+
import { resolveScanOptions } from './engine-mapping.js';
|
|
54
|
+
import { builtinDescriptionProvider, settleDescription } from './hydration.js';
|
|
55
|
+
import { assignFolderDescriptions, performWalk, rootNode } from './tree-replay.js';
|
|
383
56
|
export async function scanSource(root, provider = builtinDescriptionProvider, options) {
|
|
384
57
|
let rootStat;
|
|
385
58
|
try {
|
|
@@ -475,129 +148,7 @@ function structureError(root, code, message) {
|
|
|
475
148
|
describe: async () => [],
|
|
476
149
|
};
|
|
477
150
|
}
|
|
478
|
-
/**
|
|
479
|
-
* Scan one directory entry into a tree node, or null when it carries no
|
|
480
|
-
* Markdown descendant (empty-directory pruning, ADR-0010; a dir with only
|
|
481
|
-
* pruned subdirs prunes too — a directory with a README is never empty).
|
|
482
|
-
* Eager walks kick reads here and settle at the drain; structure walks
|
|
483
|
-
* record the file for describe(). Either way descriptions finalize before
|
|
484
|
-
* the caller's output contract completes.
|
|
485
|
-
*/
|
|
486
|
-
async function scanEntry(root, absDir, entry, ctx, gitignoreRules, budget) {
|
|
487
|
-
const { opts } = ctx;
|
|
488
|
-
if (budget.files >= opts.maxFiles) {
|
|
489
|
-
budget.limitHit = true;
|
|
490
|
-
return null;
|
|
491
|
-
}
|
|
492
|
-
if (opts.excludeDotEntries && entry.name.startsWith('.'))
|
|
493
|
-
return null;
|
|
494
|
-
const abs = join(absDir, entry.name);
|
|
495
|
-
const rel = relPath(root, abs);
|
|
496
|
-
if (opts.respectGitignore && isGitignored(abs, entry.isDirectory(), gitignoreRules))
|
|
497
|
-
return null;
|
|
498
|
-
if (entry.isDirectory()) {
|
|
499
|
-
if (opts.excludeDirs.includes(entry.name))
|
|
500
|
-
return null;
|
|
501
|
-
const dirEntries = await sortedEntries(abs, ctx);
|
|
502
|
-
// The readdir above already says whether this dir carries a .gitignore
|
|
503
|
-
// — opening the file only then skips the failing probe per
|
|
504
|
-
// gitignore-less directory (the walk-thread latency that dominated
|
|
505
|
-
// large-tree scans; same gate as the root).
|
|
506
|
-
const nestedRules = opts.respectGitignore && carriesGitignore(dirEntries)
|
|
507
|
-
? [...gitignoreRules, ...(await readGitignoreRules(abs))]
|
|
508
|
-
: gitignoreRules;
|
|
509
|
-
const sidecar = await sidecarDescription(abs, rel, dirEntries, ctx, nestedRules);
|
|
510
|
-
const children = [];
|
|
511
|
-
for (const child of dirEntries) {
|
|
512
|
-
if (isDirSidecarName(child.name))
|
|
513
|
-
continue; // consumed by sidecar above
|
|
514
|
-
const node = await scanEntry(root, abs, child, ctx, nestedRules, budget);
|
|
515
|
-
if (node === null)
|
|
516
|
-
continue;
|
|
517
|
-
children.push(node);
|
|
518
|
-
}
|
|
519
|
-
if (children.length === 0)
|
|
520
|
-
return null;
|
|
521
|
-
const node = { name: entry.name, path: rel, kind: 'dir', children };
|
|
522
|
-
ctx.sidecars.set(node, sidecar);
|
|
523
|
-
// Fact-safe cut (ADR-0010 U12): the budget flipped inside this folder's
|
|
524
|
-
// span, so it survives with partial children — as does every surviving
|
|
525
|
-
// ancestor, which marks itself the same way at its own loop's end (the
|
|
526
|
-
// chain of folders whose counts are floors). A partial count must never
|
|
527
|
-
// present as the total: the path joins the floor-count set and the
|
|
528
|
-
// per-row diagnostic fires (consumer audience). Folders never entered
|
|
529
|
-
// after the flip vanish instead — the global file-limit-reached covers
|
|
530
|
-
// those, unchanged.
|
|
531
|
-
if (budget.limitHit) {
|
|
532
|
-
ctx.countIncompletePaths.push(rel);
|
|
533
|
-
ctx.events.push({ kind: 'diag', diagnostic: countTruncatedDiagnostic(rel) });
|
|
534
|
-
}
|
|
535
|
-
return node;
|
|
536
|
-
}
|
|
537
|
-
if (entry.isFile() && extname(entry.name).toLowerCase() === MARKDOWN_EXT) {
|
|
538
|
-
if (isExcludedFileName(entry.name, opts.excludeFiles))
|
|
539
|
-
return null;
|
|
540
|
-
const node = { name: stem(entry.name), path: rel, kind: 'file' };
|
|
541
|
-
// Eager start, deferred settle: the read overlaps the rest of the walk
|
|
542
|
-
// while the budget counts synchronously at kick-off — the cut point
|
|
543
|
-
// (first maxFiles in sorted DFS order) is the serial walk's.
|
|
544
|
-
if (ctx.eager) {
|
|
545
|
-
await ctx.reads.gate();
|
|
546
|
-
const item = { name: node.name, description: '', locator: { kind: 'file', path: rel } };
|
|
547
|
-
node.item = item;
|
|
548
|
-
ctx.events.push({ kind: 'file', read: { rel, content: ctx.reads.start(abs), item } });
|
|
549
|
-
}
|
|
550
|
-
else {
|
|
551
|
-
ctx.files.set(rel, { rel, abs, node });
|
|
552
|
-
}
|
|
553
|
-
budget.files += 1;
|
|
554
|
-
return node;
|
|
555
|
-
}
|
|
556
|
-
return null;
|
|
557
|
-
}
|
|
558
|
-
async function sortedEntries(dir, ctx) {
|
|
559
|
-
let entries;
|
|
560
|
-
try {
|
|
561
|
-
entries = await readdir(dir, { withFileTypes: true });
|
|
562
|
-
}
|
|
563
|
-
catch {
|
|
564
|
-
ctx.events.push({
|
|
565
|
-
kind: 'diag',
|
|
566
|
-
diagnostic: {
|
|
567
|
-
code: 'unreadable-directory',
|
|
568
|
-
severity: 'warning',
|
|
569
|
-
message: `Unable to read directory.`,
|
|
570
|
-
path: dir,
|
|
571
|
-
audience: 'maintainer',
|
|
572
|
-
},
|
|
573
|
-
});
|
|
574
|
-
return [];
|
|
575
|
-
}
|
|
576
|
-
return entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
577
|
-
}
|
|
578
151
|
function rootDiagnostic(code, message) {
|
|
579
152
|
return { code, severity: 'warning', message, path: '.', audience: 'consumer' };
|
|
580
153
|
}
|
|
581
|
-
function placeholder(relPath, diagnostics) {
|
|
582
|
-
diagnostics.push({
|
|
583
|
-
code: 'no-description',
|
|
584
|
-
severity: 'warning',
|
|
585
|
-
// The code states the condition; the message carries only the datum
|
|
586
|
-
// (coggit's WARN | code | source=... convention — no restating sentence).
|
|
587
|
-
message: relPath,
|
|
588
|
-
path: relPath,
|
|
589
|
-
audience: 'maintainer',
|
|
590
|
-
});
|
|
591
|
-
return `Undocumented — add a description to ${relPath}`;
|
|
592
|
-
}
|
|
593
|
-
function rootNode(root) {
|
|
594
|
-
const name = basename(root);
|
|
595
|
-
return { name: name === '' || name === '.' || name === '/' ? 'root' : name, path: '', kind: 'dir' };
|
|
596
|
-
}
|
|
597
|
-
function stem(fileName) {
|
|
598
|
-
return fileName.slice(0, fileName.length - extname(fileName).length);
|
|
599
|
-
}
|
|
600
|
-
function relPath(root, abs) {
|
|
601
|
-
return relative(root, abs).split(sep).join('/');
|
|
602
|
-
}
|
|
603
154
|
//# sourceMappingURL=scan.js.map
|
package/dist/scan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type ResolvedScanOptions } from './engine-mapping.ts';
|
|
2
|
+
import { BoundedReads, type DiagnosticEvent, type FileRecord } from './hydration.ts';
|
|
3
|
+
import type { NavNode } from './types.ts';
|
|
4
|
+
export declare function isExcludedFileName(name: string, excludeFiles: readonly string[]): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Directory description carriers: standardized files a folder
|
|
7
|
+
* may already carry, in descending order of standardization — the npm
|
|
8
|
+
* `package.json` description, then the manifest-authoring `manifest.yml`
|
|
9
|
+
* `metadata.description` gloss. Priority order, per stage: present with a
|
|
10
|
+
* usable value wins; present but empty or key-less falls through to the
|
|
11
|
+
* next stage (never fabricates); unreadable or invalid fires a loud
|
|
12
|
+
* maintainer diagnostic and falls through the same way. The README chain
|
|
13
|
+
* remains the tail after the last carrier. The files are never Markdown so
|
|
14
|
+
* they never enter the tree, and they never consume the maxFiles budget.
|
|
15
|
+
*/
|
|
16
|
+
export declare const DIR_DESCRIPTION_CARRIERS: readonly string[];
|
|
17
|
+
export declare function isDirDescriptionCarrier(name: string): boolean;
|
|
18
|
+
/** Shared mutable walk state (the budget stays out: its arithmetic is
|
|
19
|
+
* synchronous exactly as in the serial walk, which is what keeps the
|
|
20
|
+
* maxFiles cut point identical). */
|
|
21
|
+
export interface WalkContext {
|
|
22
|
+
/** Scan root as given — replay paths join against it. */
|
|
23
|
+
root: string;
|
|
24
|
+
opts: ResolvedScanOptions;
|
|
25
|
+
events: DiagnosticEvent[];
|
|
26
|
+
/** Walked md files by source-relative path, in walk order — the structure
|
|
27
|
+
* walk's describe() index (the eager walk kicks reads inline instead). */
|
|
28
|
+
files: Map<string, FileRecord>;
|
|
29
|
+
/** Directory carrier descriptions captured during the walk; the folder
|
|
30
|
+
* pass folds them with README chains into node descriptions. */
|
|
31
|
+
carrierDescriptions: Map<NavNode, string | undefined>;
|
|
32
|
+
reads: BoundedReads;
|
|
33
|
+
/** Eager walks kick reads at walk positions; structure walks record files
|
|
34
|
+
* only, deferring every content read to describe(). */
|
|
35
|
+
eager: boolean;
|
|
36
|
+
/** Dir paths (walk order) whose descent the maxFiles budget cut short —
|
|
37
|
+
* the floor-count chain; the per-row diagnostics ride the
|
|
38
|
+
* walk events alongside. */
|
|
39
|
+
countIncompletePaths: string[];
|
|
40
|
+
}
|
|
41
|
+
/** The shared walk's result (either entry point assembles its output from
|
|
42
|
+
* this): assembled tree (carrier descriptions captured), budget, and
|
|
43
|
+
* walk-order events (diag events for directory findings; file events in
|
|
44
|
+
* eager mode). */
|
|
45
|
+
export interface WalkOutcome {
|
|
46
|
+
ctx: WalkContext;
|
|
47
|
+
tree: NavNode;
|
|
48
|
+
itemCount: number;
|
|
49
|
+
events: DiagnosticEvent[];
|
|
50
|
+
limitHit: boolean;
|
|
51
|
+
}
|
|
52
|
+
export declare function performWalk(root: string, options: ResolvedScanOptions | undefined, eager: boolean): Promise<WalkOutcome>;
|
|
53
|
+
/**
|
|
54
|
+
* Post-walk folder descriptions, bottom-up over the assembled tree — the
|
|
55
|
+
* same chain the serial walk computed inline: carrier description first
|
|
56
|
+
* (package.json, then manifest.yml), else the folder's own first
|
|
57
|
+
* README child (children are name-sorted) carrying a real description. Runs
|
|
58
|
+
* after the settle, so file descriptions are final.
|
|
59
|
+
*/
|
|
60
|
+
export declare function assignFolderDescriptions(node: NavNode, ctx: WalkContext): void;
|
|
61
|
+
export declare function rootNode(root: string): NavNode;
|