@maxgfr/codeindex 2.13.0 → 2.15.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/README.md +30 -10
- package/docs/MIGRATION.md +170 -36
- package/package.json +1 -1
- package/scripts/engine.d.mts +39 -4
- package/scripts/engine.mjs +1229 -721
- package/src/ast/grammars-pull.ts +178 -0
- package/src/ast/loader.ts +77 -15
- package/src/bm25.ts +16 -6
- package/src/callers.ts +10 -14
- package/src/complexity.ts +7 -1
- package/src/deadcode.ts +5 -4
- package/src/derived.ts +128 -0
- package/src/engine-cli.ts +288 -46
- package/src/engine.ts +20 -3
- package/src/hash.ts +5 -2
- package/src/mcp.ts +323 -24
- package/src/pipeline.ts +16 -5
- package/src/query.ts +8 -5
- package/src/scan.ts +66 -8
- package/src/types.ts +1 -1
- package/src/walk.ts +26 -9
package/src/walk.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readdirSync, statSync, lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
1
|
+
import { readdirSync, statSync, lstatSync, readFileSync, realpathSync, type Dirent } from "node:fs";
|
|
2
2
|
import { join, relative, sep, extname } from "node:path";
|
|
3
3
|
import { parseGitignore, isIgnored, type IgnoreRule } from "./ignore.js";
|
|
4
4
|
|
|
@@ -113,27 +113,44 @@ export function walk(root: string, opts: WalkOptions = {}): WalkResult {
|
|
|
113
113
|
if (seenDirs.has(real)) continue;
|
|
114
114
|
seenDirs.add(real);
|
|
115
115
|
if (!contained(real)) continue; // dir symlink escaping the repo
|
|
116
|
-
let entries:
|
|
116
|
+
let entries: Dirent[];
|
|
117
117
|
try {
|
|
118
118
|
// Sorted so the walk order — and therefore WHICH files survive a
|
|
119
|
-
// maxFiles cap — is identical across filesystems and machines.
|
|
120
|
-
|
|
119
|
+
// maxFiles cap — is identical across filesystems and machines. Dirents
|
|
120
|
+
// sort by .name under the same code-unit comparison the bare-string
|
|
121
|
+
// sort used, so the order is byte-identical to the previous readdir.
|
|
122
|
+
entries = readdirSync(frame.dir, { withFileTypes: true }).sort((a, b) =>
|
|
123
|
+
a.name < b.name ? -1 : a.name > b.name ? 1 : 0,
|
|
124
|
+
);
|
|
121
125
|
} catch {
|
|
122
126
|
continue;
|
|
123
127
|
}
|
|
124
128
|
let rules = frame.rules;
|
|
125
|
-
if (useGitignore && entries.
|
|
129
|
+
if (useGitignore && entries.some((e) => e.name === ".gitignore")) {
|
|
126
130
|
const parsed = parseGitignore(readText(join(frame.dir, ".gitignore")), frame.rel);
|
|
127
131
|
if (parsed.length) rules = [...rules, ...parsed];
|
|
128
132
|
}
|
|
129
|
-
for (const
|
|
133
|
+
for (const entry of entries) {
|
|
134
|
+
const name = entry.name;
|
|
130
135
|
const abs = join(frame.dir, name);
|
|
131
136
|
const rel = frame.rel ? `${frame.rel}/${name}` : name;
|
|
137
|
+
// The dirent type IS the lstat type (Node lstats internally when the
|
|
138
|
+
// filesystem can't supply it), so no lstat is needed to detect links.
|
|
139
|
+
const isLink = entry.isSymbolicLink();
|
|
140
|
+
// Ignored-directory boundary (node_modules, .git…): skip on the dirent
|
|
141
|
+
// type alone — ZERO stat syscalls. A symlink reports isDirectory()
|
|
142
|
+
// false on its dirent and falls through to the stat-based
|
|
143
|
+
// classification below, so a link named node_modules still classifies
|
|
144
|
+
// by its target exactly as before.
|
|
145
|
+
if (entry.isDirectory() && ignoreDirs.has(name)) continue;
|
|
132
146
|
let st;
|
|
133
|
-
let isLink: boolean;
|
|
134
147
|
try {
|
|
135
|
-
|
|
136
|
-
|
|
148
|
+
// Non-links: a single lstatSync supplies isDirectory/isFile/size/
|
|
149
|
+
// mtimeMs — field-for-field what the previous statSync returned,
|
|
150
|
+
// since with no link to follow the two calls are identical. Links:
|
|
151
|
+
// keep the following statSync so the entry classifies by its TARGET;
|
|
152
|
+
// a broken link throws here and is skipped, same as before.
|
|
153
|
+
st = isLink ? statSync(abs) : lstatSync(abs);
|
|
137
154
|
} catch {
|
|
138
155
|
continue;
|
|
139
156
|
}
|