@vibe-agent-toolkit/utils 0.1.42 → 0.2.0-rc.10
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 +81 -19
- package/dist/asset-reference.js +3 -11
- package/dist/asset-reference.js.map +1 -1
- package/dist/compare-code-units.d.ts +28 -0
- package/dist/compare-code-units.d.ts.map +1 -0
- package/dist/compare-code-units.js +33 -0
- package/dist/compare-code-units.js.map +1 -0
- package/dist/crawl-timing.d.ts +657 -0
- package/dist/crawl-timing.d.ts.map +1 -0
- package/dist/crawl-timing.js +765 -0
- package/dist/crawl-timing.js.map +1 -0
- package/dist/crawl.d.ts +2 -4
- package/dist/crawl.d.ts.map +1 -1
- package/dist/crawl.js +2 -4
- package/dist/crawl.js.map +1 -1
- package/dist/dirent-kind.d.ts +83 -0
- package/dist/dirent-kind.d.ts.map +1 -0
- package/dist/dirent-kind.js +129 -0
- package/dist/dirent-kind.js.map +1 -0
- package/dist/entrypoint.d.ts +54 -0
- package/dist/entrypoint.d.ts.map +1 -0
- package/dist/entrypoint.js +71 -0
- package/dist/entrypoint.js.map +1 -0
- package/dist/env-flag.d.ts +51 -0
- package/dist/env-flag.d.ts.map +1 -0
- package/dist/env-flag.js +62 -0
- package/dist/env-flag.js.map +1 -0
- package/dist/errors/errno.d.ts +51 -0
- package/dist/errors/errno.d.ts.map +1 -0
- package/dist/errors/errno.js +112 -0
- package/dist/errors/errno.js.map +1 -0
- package/dist/errors/vat-error.d.ts +60 -0
- package/dist/errors/vat-error.d.ts.map +1 -0
- package/dist/errors/vat-error.js +86 -0
- package/dist/errors/vat-error.js.map +1 -0
- package/dist/file-crawler.d.ts +60 -0
- package/dist/file-crawler.d.ts.map +1 -1
- package/dist/file-crawler.js +214 -24
- package/dist/file-crawler.js.map +1 -1
- package/dist/fs/file-hash.d.ts.map +1 -1
- package/dist/fs/file-hash.js +0 -1
- package/dist/fs/file-hash.js.map +1 -1
- package/dist/fs-utils.d.ts +628 -38
- package/dist/fs-utils.d.ts.map +1 -1
- package/dist/fs-utils.js +770 -71
- package/dist/fs-utils.js.map +1 -1
- package/dist/fs.d.ts +5 -1
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +9 -1
- package/dist/fs.js.map +1 -1
- package/dist/git-root-cache.d.ts +44 -0
- package/dist/git-root-cache.d.ts.map +1 -0
- package/dist/git-root-cache.js +68 -0
- package/dist/git-root-cache.js.map +1 -0
- package/dist/git-run.d.ts +167 -0
- package/dist/git-run.d.ts.map +1 -0
- package/dist/git-run.js +154 -0
- package/dist/git-run.js.map +1 -0
- package/dist/git-snapshot.d.ts +199 -0
- package/dist/git-snapshot.d.ts.map +1 -0
- package/dist/git-snapshot.js +250 -0
- package/dist/git-snapshot.js.map +1 -0
- package/dist/git-tracker.d.ts +166 -3
- package/dist/git-tracker.d.ts.map +1 -1
- package/dist/git-tracker.js +250 -22
- package/dist/git-tracker.js.map +1 -1
- package/dist/git-utils.d.ts +95 -1
- package/dist/git-utils.d.ts.map +1 -1
- package/dist/git-utils.js +227 -81
- package/dist/git-utils.js.map +1 -1
- package/dist/git.d.ts +13 -4
- package/dist/git.d.ts.map +1 -1
- package/dist/git.js +12 -4
- package/dist/git.js.map +1 -1
- package/dist/gitignore-checker.d.ts.map +1 -1
- package/dist/gitignore-checker.js +15 -6
- package/dist/gitignore-checker.js.map +1 -1
- package/dist/glob/glob-pattern.js +5 -5
- package/dist/glob/glob-pattern.js.map +1 -1
- package/dist/index.d.ts +33 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +113 -33
- package/dist/index.js.map +1 -1
- package/dist/listing-refusal.d.ts +112 -0
- package/dist/listing-refusal.d.ts.map +1 -0
- package/dist/listing-refusal.js +105 -0
- package/dist/listing-refusal.js.map +1 -0
- package/dist/numeric-args.d.ts +24 -0
- package/dist/numeric-args.d.ts.map +1 -0
- package/dist/numeric-args.js +37 -0
- package/dist/numeric-args.js.map +1 -0
- package/dist/path-containment.d.ts +64 -0
- package/dist/path-containment.d.ts.map +1 -0
- package/dist/path-containment.js +111 -0
- package/dist/path-containment.js.map +1 -0
- package/dist/path-core.d.ts +143 -18
- package/dist/path-core.d.ts.map +1 -1
- package/dist/path-core.js +171 -23
- package/dist/path-core.js.map +1 -1
- package/dist/path-utils.d.ts.map +1 -1
- package/dist/path-utils.js +42 -47
- package/dist/path-utils.js.map +1 -1
- package/dist/path.d.ts +1 -1
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +1 -1
- package/dist/path.js.map +1 -1
- package/dist/process.d.ts +7 -0
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +7 -0
- package/dist/process.js.map +1 -1
- package/dist/project-utils.d.ts +7 -1
- package/dist/project-utils.d.ts.map +1 -1
- package/dist/project-utils.js +24 -10
- package/dist/project-utils.js.map +1 -1
- package/dist/project.d.ts +7 -5
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +7 -5
- package/dist/project.js.map +1 -1
- package/dist/safe-exec.d.ts +40 -11
- package/dist/safe-exec.d.ts.map +1 -1
- package/dist/safe-exec.js +111 -25
- package/dist/safe-exec.js.map +1 -1
- package/dist/skill-targets.d.ts +2 -2
- package/dist/skill-targets.js +2 -2
- package/dist/skill-test/auth-resolver.d.ts +10 -2
- package/dist/skill-test/auth-resolver.d.ts.map +1 -1
- package/dist/skill-test/auth-resolver.js +26 -11
- package/dist/skill-test/auth-resolver.js.map +1 -1
- package/dist/skill-test/index.d.ts +1 -1
- package/dist/skill-test/index.d.ts.map +1 -1
- package/dist/skill-test/index.js +1 -1
- package/dist/skill-test/index.js.map +1 -1
- package/dist/skill-test/spawn-claude.d.ts +30 -1
- package/dist/skill-test/spawn-claude.d.ts.map +1 -1
- package/dist/skill-test/spawn-claude.js +71 -5
- package/dist/skill-test/spawn-claude.js.map +1 -1
- package/dist/skill-test/transcript.d.ts +41 -2
- package/dist/skill-test/transcript.d.ts.map +1 -1
- package/dist/skill-test/transcript.js +55 -10
- package/dist/skill-test/transcript.js.map +1 -1
- package/dist/spawn-hardened.js +0 -1
- package/dist/spawn-hardened.js.map +1 -1
- package/dist/stdio-blocking.js +13 -14
- package/dist/stdio-blocking.js.map +1 -1
- package/dist/test-helpers.d.ts +130 -79
- package/dist/test-helpers.d.ts.map +1 -1
- package/dist/test-helpers.js +229 -124
- package/dist/test-helpers.js.map +1 -1
- package/dist/testing/executables.d.ts +32 -0
- package/dist/testing/executables.d.ts.map +1 -0
- package/dist/testing/executables.js +70 -0
- package/dist/testing/executables.js.map +1 -0
- package/dist/testing/hostile-tree.d.ts +79 -0
- package/dist/testing/hostile-tree.d.ts.map +1 -0
- package/dist/testing/hostile-tree.js +164 -0
- package/dist/testing/hostile-tree.js.map +1 -0
- package/dist/testing/platform-gates.d.ts +31 -0
- package/dist/testing/platform-gates.d.ts.map +1 -0
- package/dist/testing/platform-gates.js +31 -0
- package/dist/testing/platform-gates.js.map +1 -0
- package/dist/testing/temp-dir.d.ts +255 -0
- package/dist/testing/temp-dir.d.ts.map +1 -0
- package/dist/testing/temp-dir.js +363 -0
- package/dist/testing/temp-dir.js.map +1 -0
- package/dist/testing.d.ts +94 -3
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +119 -3
- package/dist/testing.js.map +1 -1
- package/dist/text-content.d.ts +197 -0
- package/dist/text-content.d.ts.map +1 -0
- package/dist/text-content.js +354 -0
- package/dist/text-content.js.map +1 -0
- package/dist/text-file.d.ts +45 -0
- package/dist/text-file.d.ts.map +1 -0
- package/dist/text-file.js +51 -0
- package/dist/text-file.js.map +1 -0
- package/dist/text.d.ts +16 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +16 -0
- package/dist/text.js.map +1 -0
- package/dist/timing-dump.d.ts +136 -0
- package/dist/timing-dump.d.ts.map +1 -0
- package/dist/timing-dump.js +229 -0
- package/dist/timing-dump.js.map +1 -0
- package/dist/windows-shell.d.ts +0 -1
- package/dist/windows-shell.d.ts.map +1 -1
- package/dist/windows-shell.js +0 -1
- package/dist/windows-shell.js.map +1 -1
- package/dist/zod-introspection.js +2 -2
- package/dist/zod-introspection.js.map +1 -1
- package/eslint/README.md +224 -50
- package/eslint/index.cjs +111 -97
- package/eslint/index.d.cts +16 -6
- package/eslint/rules/callee-name.cjs +23 -0
- package/eslint/rules/commands-import-boundary.cjs +148 -0
- package/eslint/rules/dead-import.cjs +62 -12
- package/eslint/rules/dirent-type-needs-symlink-check.cjs +282 -0
- package/eslint/rules/eslint-rule-factory.cjs +21 -3
- package/eslint/rules/exempt-path-matcher.cjs +2 -1
- package/eslint/rules/explicit-zod-strictness.cjs +120 -0
- package/eslint/rules/no-bare-dynamic-import-path.cjs +5 -1
- package/eslint/rules/no-bare-executable-spawn.cjs +70 -0
- package/eslint/rules/no-bare-symlink-in-tests.cjs +213 -0
- package/eslint/rules/no-blind-catch.cjs +171 -0
- package/eslint/rules/no-child-process-execSync.cjs +8 -0
- package/eslint/rules/no-decaying-referent.cjs +217 -0
- package/eslint/rules/no-dotdot-containment.cjs +160 -0
- package/eslint/rules/no-file-url-string-concat.cjs +4 -1
- package/eslint/rules/no-fragile-entrypoint-guard.cjs +228 -0
- package/eslint/rules/no-fs-mkdirSync.cjs +8 -0
- package/eslint/rules/no-fs-promises-cp.cjs +7 -0
- package/eslint/rules/no-fs-realpathSync.cjs +8 -0
- package/eslint/rules/no-hardcoded-path-split.cjs +29 -18
- package/eslint/rules/no-io-in-unit-tier.cjs +129 -0
- package/eslint/rules/no-literal-process-exit.cjs +129 -0
- package/eslint/rules/no-manual-path-normalize.cjs +146 -96
- package/eslint/rules/no-os-tmpdir.cjs +8 -0
- package/eslint/rules/no-path-operations-in-comparisons.cjs +7 -2
- package/eslint/rules/no-path-sep-in-strings.cjs +7 -2
- package/eslint/rules/no-path-startswith.cjs +7 -2
- package/eslint/rules/no-process-exit-in-phase.cjs +127 -0
- package/eslint/rules/no-raw-node-path.cjs +563 -0
- package/eslint/rules/no-raw-text-decode.cjs +305 -0
- package/eslint/rules/no-registry-count-pin.cjs +255 -0
- package/eslint/rules/no-self-package-import.cjs +168 -0
- package/eslint/rules/no-test-scoped-functions.cjs +10 -3
- package/eslint/rules/no-unix-shell-commands.cjs +6 -2
- package/eslint/rules/no-unsafe-root-join.cjs +23 -2
- package/eslint/rules/no-url-pathname-for-fs.cjs +5 -1
- package/eslint/rules/no-version-literal.cjs +151 -0
- package/eslint/rules/prefer-startswith-over-regex.cjs +33 -1
- package/eslint/rules/require-justified-skip.cjs +8 -2
- package/eslint/rules/safe-import.cjs +1 -1
- package/package.json +16 -16
- package/dist/link-auth/build-headers.d.ts +0 -34
- package/dist/link-auth/build-headers.d.ts.map +0 -1
- package/dist/link-auth/build-headers.js +0 -58
- package/dist/link-auth/build-headers.js.map +0 -1
- package/dist/link-auth/expand-macro.d.ts +0 -38
- package/dist/link-auth/expand-macro.d.ts.map +0 -1
- package/dist/link-auth/expand-macro.js +0 -133
- package/dist/link-auth/expand-macro.js.map +0 -1
- package/dist/link-auth/macros.yaml +0 -50
- package/dist/link-auth/resolve-token.d.ts +0 -83
- package/dist/link-auth/resolve-token.d.ts.map +0 -1
- package/dist/link-auth/resolve-token.js +0 -101
- package/dist/link-auth/resolve-token.js.map +0 -1
- package/dist/link-auth/resolve.d.ts +0 -102
- package/dist/link-auth/resolve.d.ts.map +0 -1
- package/dist/link-auth/resolve.js +0 -66
- package/dist/link-auth/resolve.js.map +0 -1
- package/dist/link-auth/rewrite.d.ts +0 -52
- package/dist/link-auth/rewrite.d.ts.map +0 -1
- package/dist/link-auth/rewrite.js +0 -102
- package/dist/link-auth/rewrite.js.map +0 -1
- package/dist/link-auth/select-provider.d.ts +0 -30
- package/dist/link-auth/select-provider.d.ts.map +0 -1
- package/dist/link-auth/select-provider.js +0 -55
- package/dist/link-auth/select-provider.js.map +0 -1
- package/dist/link-auth/template.d.ts +0 -40
- package/dist/link-auth/template.d.ts.map +0 -1
- package/dist/link-auth/template.js +0 -89
- package/dist/link-auth/template.js.map +0 -1
- package/dist/link-auth/transforms.d.ts +0 -46
- package/dist/link-auth/transforms.d.ts.map +0 -1
- package/dist/link-auth/transforms.js +0 -52
- package/dist/link-auth/transforms.js.map +0 -1
- package/dist/template-entry.d.ts +0 -10
- package/dist/template-entry.d.ts.map +0 -1
- package/dist/template-entry.js +0 -10
- package/dist/template-entry.js.map +0 -1
- package/dist/template.d.ts +0 -7
- package/dist/template.d.ts.map +0 -1
- package/dist/template.js +0 -18
- package/dist/template.js.map +0 -1
- package/eslint/rules/no-path-join.cjs +0 -14
- package/eslint/rules/no-path-relative.cjs +0 -14
- package/eslint/rules/no-path-resolve.cjs +0 -14
- package/eslint/rules/path-function-rule-factory.cjs +0 -417
package/dist/file-crawler.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import picomatch from 'picomatch';
|
|
3
|
+
import { directoryRefusalFor, listingFailure, } from './fs-utils.js';
|
|
3
4
|
import { gitFindRoot, gitLsFiles } from './git-utils.js';
|
|
5
|
+
import { requireUnreadablePolicy, settleRefusal } from './listing-refusal.js';
|
|
4
6
|
import { toForwardSlash, safePath } from './path-utils.js';
|
|
7
|
+
// The refusal vocabulary lives in `listing-refusal.ts` so `git-utils.ts` can
|
|
8
|
+
// share it without importing this module (which imports that one). Re-exported
|
|
9
|
+
// here because `./crawl` is where every caller of the walk already looks.
|
|
10
|
+
export { DirectoryListingRefusedError, refusedListingMessage, settleRefusal, } from './listing-refusal.js';
|
|
5
11
|
/**
|
|
6
12
|
* Glob options shared by every pattern this module compiles.
|
|
7
13
|
*
|
|
@@ -71,6 +77,35 @@ export const NEVER_CRAWL_GLOBS = [
|
|
|
71
77
|
*/
|
|
72
78
|
export const BUILD_OUTPUT_GLOBS = ['**/dist/**'];
|
|
73
79
|
const DEFAULT_EXCLUDE = [...NEVER_CRAWL_GLOBS, ...BUILD_OUTPUT_GLOBS];
|
|
80
|
+
/**
|
|
81
|
+
* THE include/exclude decision, compiled once — "is this base-relative path a
|
|
82
|
+
* member of the crawl?"
|
|
83
|
+
*
|
|
84
|
+
* Extracted because it is asked from three places that must never drift: the
|
|
85
|
+
* `git ls-files` branch below, the manual walk below it, and — since the
|
|
86
|
+
* projection-backed lane landed — a population that arrives already enumerated
|
|
87
|
+
* and still has to be narrowed to what the caller's globs admit. A lane that
|
|
88
|
+
* approximated this with its own picomatch call would be measuring the corpus
|
|
89
|
+
* with a different matcher than the one that ships, which is how a "clean" A/B
|
|
90
|
+
* comes to compare two different questions.
|
|
91
|
+
*
|
|
92
|
+
* The `+ '/'` retry is the load-bearing subtlety, not a defensive extra: a
|
|
93
|
+
* directory-shaped exclude like `docs/legacy/**` does not match the bare path
|
|
94
|
+
* `docs/legacy`, so without it an excluded directory is admitted as a member
|
|
95
|
+
* whenever a caller enumerates directories as well as files.
|
|
96
|
+
*
|
|
97
|
+
* @param include - Include globs, base-relative, forward-slashed
|
|
98
|
+
* @param exclude - Exclude globs, same basis; an empty list excludes nothing
|
|
99
|
+
* @returns A predicate over base-relative, forward-slashed paths
|
|
100
|
+
*/
|
|
101
|
+
export function crawlPathFilter(include, exclude) {
|
|
102
|
+
const isIncluded = picomatch([...include], PICOMATCH_OPTIONS);
|
|
103
|
+
const isExcluded = exclude.length > 0 ? picomatch([...exclude], PICOMATCH_OPTIONS) : () => false;
|
|
104
|
+
return (relativePath) => {
|
|
105
|
+
const normalized = toForwardSlash(relativePath);
|
|
106
|
+
return isIncluded(normalized) && !isExcluded(normalized) && !isExcluded(`${normalized}/`);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
74
109
|
/**
|
|
75
110
|
* Crawl a directory tree and return matching files (async)
|
|
76
111
|
*
|
|
@@ -90,6 +125,21 @@ const DEFAULT_EXCLUDE = [...NEVER_CRAWL_GLOBS, ...BUILD_OUTPUT_GLOBS];
|
|
|
90
125
|
export async function crawlDirectory(options) {
|
|
91
126
|
return crawlDirectorySync(options);
|
|
92
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Refuse a symlink observer on the `git ls-files` route.
|
|
130
|
+
*
|
|
131
|
+
* That route admits links as members and declines none, so the observer would
|
|
132
|
+
* compile, be accepted, and never be called. Refused up front rather than only
|
|
133
|
+
* when a git root happens to be found, so the contract is static.
|
|
134
|
+
*
|
|
135
|
+
* @param observer - The caller's `onSymlinkNotFollowed`
|
|
136
|
+
* @param respectGitignore - Whether the git route may be taken
|
|
137
|
+
*/
|
|
138
|
+
function requireWalkForSymlinkObserver(observer, respectGitignore) {
|
|
139
|
+
if (observer !== undefined && respectGitignore) {
|
|
140
|
+
throw new TypeError('crawlDirectory: onSymlinkNotFollowed requires respectGitignore: false — the git ls-files route declines no link');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
93
143
|
/**
|
|
94
144
|
* Crawl a directory tree and return matching files (synchronous)
|
|
95
145
|
*
|
|
@@ -107,17 +157,36 @@ export async function crawlDirectory(options) {
|
|
|
107
157
|
* });
|
|
108
158
|
*/
|
|
109
159
|
export function crawlDirectorySync(options) {
|
|
110
|
-
const { baseDir, include = ['**/*'], exclude = DEFAULT_EXCLUDE, followSymlinks = false, absolute = true, filesOnly = true, respectGitignore = true, includeUntracked = false, } = options;
|
|
160
|
+
const { baseDir, include = ['**/*'], exclude = DEFAULT_EXCLUDE, followSymlinks = false, absolute = true, filesOnly = true, respectGitignore = true, includeUntracked = false, unreadable, onSymlinkNotFollowed, } = options;
|
|
161
|
+
requireUnreadablePolicy(unreadable, 'crawlDirectory');
|
|
162
|
+
requireWalkForSymlinkObserver(onSymlinkNotFollowed, respectGitignore);
|
|
111
163
|
const picoOptions = PICOMATCH_OPTIONS;
|
|
112
164
|
// Resolve base directory to absolute path
|
|
113
165
|
const resolvedBaseDir = safePath.resolve(baseDir);
|
|
166
|
+
// Compiled once, ahead of the route choice, because BOTH routes ask it: the
|
|
167
|
+
// walk before it lists a directory, the git route before it reports one git
|
|
168
|
+
// could not list. One matcher is what keeps "is this directory excluded?"
|
|
169
|
+
// answered the same way on both sides of the fork.
|
|
170
|
+
const isExcluded = exclude.length > 0 ? picomatch(exclude, picoOptions) : () => false;
|
|
171
|
+
/**
|
|
172
|
+
* Check if a path should be excluded based on patterns
|
|
173
|
+
*/
|
|
174
|
+
function shouldExclude(normalizedPath) {
|
|
175
|
+
// Check explicit exclude patterns
|
|
176
|
+
return isExcluded(normalizedPath) || isExcluded(normalizedPath + '/');
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* A refused listing surfaces under the caller's policy — thrown, or handed
|
|
180
|
+
* over. Never a silent skip, on either route.
|
|
181
|
+
*/
|
|
182
|
+
function raiseRefusal(refusal) {
|
|
183
|
+
settleRefusal(unreadable, refusal);
|
|
184
|
+
}
|
|
114
185
|
// Ensure base directory exists
|
|
115
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- baseDir is from controlled config, not user input
|
|
116
186
|
if (!fs.existsSync(resolvedBaseDir)) {
|
|
117
187
|
throw new Error(`Base directory does not exist: ${resolvedBaseDir}`);
|
|
118
188
|
}
|
|
119
189
|
// Ensure base directory is actually a directory
|
|
120
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- resolved path validated above
|
|
121
190
|
const baseStat = fs.statSync(resolvedBaseDir);
|
|
122
191
|
if (!baseStat.isDirectory()) {
|
|
123
192
|
throw new Error(`Base path is not a directory: ${resolvedBaseDir}`);
|
|
@@ -132,17 +201,51 @@ export function crawlDirectorySync(options) {
|
|
|
132
201
|
const gitFiles = gitLsFiles({
|
|
133
202
|
cwd: resolvedBaseDir,
|
|
134
203
|
includeUntracked,
|
|
204
|
+
// The SAME decision the walk makes, in the same order: a directory
|
|
205
|
+
// outside this crawl's base or dropped by `exclude` is never listed by
|
|
206
|
+
// the walk, so a refusal on it is not this crawl's gap; anything else
|
|
207
|
+
// is, and goes where the walk's would go.
|
|
208
|
+
// `degrade` from git's side only: the refusal is filtered to this
|
|
209
|
+
// crawl's territory and then settled under the CALLER's policy, which
|
|
210
|
+
// may well be `refuse`.
|
|
211
|
+
unreadable: {
|
|
212
|
+
degrade: (refusal) => {
|
|
213
|
+
// Strictly beneath the base: a repository is often an ancestor of
|
|
214
|
+
// the crawl, and git names every refusal in the whole worktree.
|
|
215
|
+
if (!toForwardSlash(refusal.directory).startsWith(`${toForwardSlash(resolvedBaseDir)}/`))
|
|
216
|
+
return;
|
|
217
|
+
if (shouldExclude(toForwardSlash(safePath.relative(resolvedBaseDir, refusal.directory))))
|
|
218
|
+
return;
|
|
219
|
+
raiseRefusal(refusal);
|
|
220
|
+
},
|
|
221
|
+
},
|
|
135
222
|
});
|
|
136
223
|
if (gitFiles !== null) {
|
|
224
|
+
// ⚠️ KNOWN DIVERGENCE: this branch ignores `followSymlinks`.
|
|
225
|
+
//
|
|
226
|
+
// `git ls-files` returns symlinks as mode-120000 entries like any other
|
|
227
|
+
// path, and nothing below filters them out — whereas the manual walk
|
|
228
|
+
// (see `processSymlink`) returns early unless `followSymlinks` is set.
|
|
229
|
+
// So the SAME tree with the SAME options has a different population
|
|
230
|
+
// depending only on whether a `.git` exists above it.
|
|
231
|
+
//
|
|
232
|
+
// A committed dangling `*.md` symlink returned from here no longer
|
|
233
|
+
// terminates the command: `ResourceRegistry.addResources` records the
|
|
234
|
+
// read failure and reports it as RESOURCE_UNREADABLE. The population
|
|
235
|
+
// divergence itself is still live.
|
|
236
|
+
//
|
|
237
|
+
// Pinned (as today's behaviour, deliberately) by
|
|
238
|
+
// packages/cli/test/integration/enumeration-symlink-divergence.integration.test.ts.
|
|
239
|
+
// Making the two routes agree changes enumeration on real corpora — in
|
|
240
|
+
// one of two opposite directions, since excluding symlinks here drops
|
|
241
|
+
// committed content while including them in the walk grows the off-git
|
|
242
|
+
// population — so it is a product decision with its own changelog
|
|
243
|
+
// entry, not a drive-by fix here.
|
|
244
|
+
//
|
|
137
245
|
// Git ls-files succeeded - filter using glob patterns
|
|
138
|
-
const
|
|
139
|
-
const isExcluded = exclude.length > 0 ? picomatch(exclude, picoOptions) : () => false;
|
|
246
|
+
const isMember = crawlPathFilter(include, exclude);
|
|
140
247
|
return gitFiles
|
|
141
|
-
.filter((relativePath) =>
|
|
142
|
-
const normalizedPath = toForwardSlash(relativePath);
|
|
143
|
-
// Check both include and exclude patterns
|
|
144
|
-
return isIncluded(normalizedPath) && !isExcluded(normalizedPath) && !isExcluded(normalizedPath + '/');
|
|
145
|
-
})
|
|
248
|
+
.filter((relativePath) => isMember(relativePath))
|
|
146
249
|
.map((relativePath) => {
|
|
147
250
|
// git ls-files returns paths relative to cwd
|
|
148
251
|
return absolute ? safePath.resolve(resolvedBaseDir, relativePath) : relativePath;
|
|
@@ -154,15 +257,24 @@ export function crawlDirectorySync(options) {
|
|
|
154
257
|
// Fall back to manual directory crawling (not in git repo or git ls-files failed)
|
|
155
258
|
// Compile glob patterns using picomatch
|
|
156
259
|
const isIncluded = picomatch(include, picoOptions);
|
|
157
|
-
const isExcluded = exclude.length > 0 ? picomatch(exclude, picoOptions) : () => false;
|
|
158
260
|
const results = [];
|
|
159
261
|
/**
|
|
160
|
-
*
|
|
262
|
+
* Real paths of directories already walked, maintained ONLY when following
|
|
263
|
+
* symlinks — it is what makes a directory symlink safe to traverse.
|
|
264
|
+
*
|
|
265
|
+
* A symlinked directory can be re-entered without limit (`a/loop -> a`) and
|
|
266
|
+
* can be reached under two names (`alias-one -> real`, `alias-two -> real`).
|
|
267
|
+
* Both enumerate one blob many times under distinct paths, so each row gets
|
|
268
|
+
* its own generated id and its own bundle entry. The loop terminated before
|
|
269
|
+
* this guard existed, but only because the kernel eventually refuses to
|
|
270
|
+
* resolve further symlinks — a limit that is 32 on macOS and 40 on Linux, so
|
|
271
|
+
* the POPULATION depended on the operating system, and the walk ended inside
|
|
272
|
+
* `processSymlink`'s catch for BROKEN links, which reported nothing.
|
|
273
|
+
*
|
|
274
|
+
* Left empty when `followSymlinks` is false: without symlink traversal a
|
|
275
|
+
* directory cannot be reached twice, so the default path pays no `realpath`.
|
|
161
276
|
*/
|
|
162
|
-
|
|
163
|
-
// Check explicit exclude patterns
|
|
164
|
-
return isExcluded(normalizedPath) || isExcluded(normalizedPath + '/');
|
|
165
|
-
}
|
|
277
|
+
const visitedRealDirs = new Set();
|
|
166
278
|
/**
|
|
167
279
|
* Add a path to results if it matches include patterns
|
|
168
280
|
*/
|
|
@@ -171,21 +283,76 @@ export function crawlDirectorySync(options) {
|
|
|
171
283
|
results.push(absolute ? fullPath : relativePath);
|
|
172
284
|
}
|
|
173
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* What a failed `readdirSync` / `statSync` means for the walk.
|
|
288
|
+
*
|
|
289
|
+
* Absence (`ENOENT` / `ENOTDIR`) is an entry that vanished between being
|
|
290
|
+
* enumerated by its parent and being asked about itself — not in the
|
|
291
|
+
* population, nothing to report. Anything else is a refusal, and a refusal
|
|
292
|
+
* is a GAP: handed to the caller if it asked, thrown otherwise. Never a
|
|
293
|
+
* silent `return` — that is the shorter list this walk used to hand back.
|
|
294
|
+
*
|
|
295
|
+
* @param error - What the filesystem threw
|
|
296
|
+
* @param target - The directory (or link) it was asked about
|
|
297
|
+
* @returns True when the entry is simply gone and the walk should move on
|
|
298
|
+
*/
|
|
299
|
+
function reportOrSkip(error, target) {
|
|
300
|
+
const listing = listingFailure(error);
|
|
301
|
+
if (listing.outcome === 'absent')
|
|
302
|
+
return true;
|
|
303
|
+
if (listing.outcome === 'unreadable')
|
|
304
|
+
raiseRefusal(directoryRefusalFor(listing, target));
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Record a directory as walked, reporting whether it had already been seen.
|
|
309
|
+
*
|
|
310
|
+
* Identity is `realpathSync.native`, not the traversal path: two names for
|
|
311
|
+
* one directory must collide here or the alias is enumerated twice. A
|
|
312
|
+
* directory whose real path cannot be read is not descended into — refusing
|
|
313
|
+
* to walk something we cannot identify is the safe side of a guard whose
|
|
314
|
+
* whole job is bounding traversal — but it is NOT silently "already walked":
|
|
315
|
+
* a directory that vanished is skipped like any other absence, and one the
|
|
316
|
+
* OS refused to canonicalise is a gap, surfaced under the caller's policy
|
|
317
|
+
* exactly as a refused listing is (see `reportOrSkip`).
|
|
318
|
+
*
|
|
319
|
+
* @param dir - Directory about to be walked
|
|
320
|
+
* @returns True when this directory must not be walked (seen before, gone, or refused)
|
|
321
|
+
*/
|
|
322
|
+
function alreadyWalked(dir) {
|
|
323
|
+
let realPath;
|
|
324
|
+
try {
|
|
325
|
+
realPath = fs.realpathSync.native(dir);
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
reportOrSkip(error, dir);
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
if (visitedRealDirs.has(realPath)) {
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
visitedRealDirs.add(realPath);
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
174
337
|
/**
|
|
175
338
|
* Process a symbolic link entry
|
|
176
339
|
*/
|
|
177
340
|
function processSymlink(fullPath, normalizedPath, relativePath) {
|
|
178
341
|
if (!followSymlinks) {
|
|
342
|
+
if (onSymlinkNotFollowed !== undefined && isIncluded(normalizedPath)) {
|
|
343
|
+
onSymlinkNotFollowed(absolute ? fullPath : relativePath);
|
|
344
|
+
}
|
|
179
345
|
return;
|
|
180
346
|
}
|
|
181
347
|
// Resolve symlink and check if it's a directory or file
|
|
182
348
|
let targetStat;
|
|
183
349
|
try {
|
|
184
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated baseDir + entries
|
|
185
350
|
targetStat = fs.statSync(fullPath);
|
|
186
351
|
}
|
|
187
|
-
catch {
|
|
188
|
-
//
|
|
352
|
+
catch (error) {
|
|
353
|
+
// A broken symlink is absence and is skipped; a target the OS refused to
|
|
354
|
+
// stat is a gap, and goes the same way a refused listing does.
|
|
355
|
+
reportOrSkip(error, fullPath);
|
|
189
356
|
return;
|
|
190
357
|
}
|
|
191
358
|
if (targetStat.isDirectory()) {
|
|
@@ -216,15 +383,32 @@ export function crawlDirectorySync(options) {
|
|
|
216
383
|
* Recursively walk directory tree
|
|
217
384
|
*/
|
|
218
385
|
function walkDirectory(currentDir) {
|
|
386
|
+
if (followSymlinks && alreadyWalked(currentDir)) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
219
389
|
let entries;
|
|
220
390
|
try {
|
|
221
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated baseDir, recursively walking
|
|
222
391
|
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
223
392
|
}
|
|
224
|
-
catch {
|
|
225
|
-
//
|
|
393
|
+
catch (error) {
|
|
394
|
+
// 🚨 Not a silent skip. A directory that refused to be listed is a gap in
|
|
395
|
+
// the population this walk defines — see `reportOrSkip`.
|
|
396
|
+
reportOrSkip(error, currentDir);
|
|
226
397
|
return;
|
|
227
398
|
}
|
|
399
|
+
// Two passes, not one: `readdirSync` order is filesystem-defined (see
|
|
400
|
+
// the comment on `alreadyWalked`), and both a real directory and a
|
|
401
|
+
// symlink alias pointing at it go through the same `alreadyWalked` gate,
|
|
402
|
+
// keyed only on realpath. Whichever spelling is dispatched FIRST claims
|
|
403
|
+
// that realpath in `visitedRealDirs`, and the second is then skipped as
|
|
404
|
+
// "already walked" — so if the alias happened to sort first, the
|
|
405
|
+
// directory's contents would be recorded under the alias's name and the
|
|
406
|
+
// real directory would be skipped entirely. Walking every non-symlink
|
|
407
|
+
// entry to completion before any symlink entry guarantees a real
|
|
408
|
+
// directory always claims its own realpath first; an alias reaching the
|
|
409
|
+
// same realpath afterward is correctly skipped by `alreadyWalked`. Only
|
|
410
|
+
// the ORDER of dispatch changes here — per-entry logic is unchanged.
|
|
411
|
+
const symlinkEntries = [];
|
|
228
412
|
for (const entry of entries) {
|
|
229
413
|
const fullPath = safePath.join(currentDir, entry.name);
|
|
230
414
|
const relativePath = safePath.relative(resolvedBaseDir, fullPath);
|
|
@@ -233,9 +417,9 @@ export function crawlDirectorySync(options) {
|
|
|
233
417
|
if (shouldExclude(normalizedPath)) {
|
|
234
418
|
continue;
|
|
235
419
|
}
|
|
236
|
-
//
|
|
420
|
+
// Defer symlinks to the second pass; dispatch everything else now.
|
|
237
421
|
if (entry.isSymbolicLink()) {
|
|
238
|
-
|
|
422
|
+
symlinkEntries.push(entry);
|
|
239
423
|
}
|
|
240
424
|
else if (entry.isDirectory()) {
|
|
241
425
|
processDirectory(fullPath, normalizedPath, relativePath);
|
|
@@ -244,6 +428,12 @@ export function crawlDirectorySync(options) {
|
|
|
244
428
|
processFile(normalizedPath, fullPath, relativePath);
|
|
245
429
|
}
|
|
246
430
|
}
|
|
431
|
+
for (const entry of symlinkEntries) {
|
|
432
|
+
const fullPath = safePath.join(currentDir, entry.name);
|
|
433
|
+
const relativePath = safePath.relative(resolvedBaseDir, fullPath);
|
|
434
|
+
const normalizedPath = toForwardSlash(relativePath);
|
|
435
|
+
processSymlink(fullPath, normalizedPath, relativePath);
|
|
436
|
+
}
|
|
247
437
|
}
|
|
248
438
|
// Start recursive walk from base directory
|
|
249
439
|
walkDirectory(resolvedBaseDir);
|
package/dist/file-crawler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-crawler.js","sourceRoot":"","sources":["../src/file-crawler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"file-crawler.js","sourceRoot":"","sources":["../src/file-crawler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-hash.d.ts","sourceRoot":"","sources":["../../src/fs/file-hash.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"file-hash.d.ts","sourceRoot":"","sources":["../../src/fs/file-hash.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpD"}
|
package/dist/fs/file-hash.js
CHANGED
|
@@ -16,7 +16,6 @@ import { readFileSync } from 'node:fs';
|
|
|
16
16
|
* // '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
|
|
17
17
|
*/
|
|
18
18
|
export function fileContentHash(path) {
|
|
19
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename -- path is caller-supplied; callers are responsible for path safety
|
|
20
19
|
const bytes = readFileSync(path);
|
|
21
20
|
return createHash('sha256').update(bytes).digest('hex');
|
|
22
21
|
}
|
package/dist/fs/file-hash.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-hash.js","sourceRoot":"","sources":["../../src/fs/file-hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,
|
|
1
|
+
{"version":3,"file":"file-hash.js","sourceRoot":"","sources":["../../src/fs/file-hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC"}
|