@vibe-agent-toolkit/utils 0.2.0-rc.5 → 0.2.0-rc.7

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.
Files changed (59) hide show
  1. package/README.md +21 -6
  2. package/dist/entrypoint.d.ts +54 -0
  3. package/dist/entrypoint.d.ts.map +1 -0
  4. package/dist/entrypoint.js +71 -0
  5. package/dist/entrypoint.js.map +1 -0
  6. package/dist/env-flag.d.ts +46 -0
  7. package/dist/env-flag.d.ts.map +1 -0
  8. package/dist/env-flag.js +57 -0
  9. package/dist/env-flag.js.map +1 -0
  10. package/dist/file-crawler.d.ts +22 -0
  11. package/dist/file-crawler.d.ts.map +1 -1
  12. package/dist/file-crawler.js +74 -13
  13. package/dist/file-crawler.js.map +1 -1
  14. package/dist/fs-utils.d.ts +406 -199
  15. package/dist/fs-utils.d.ts.map +1 -1
  16. package/dist/fs-utils.js +479 -203
  17. package/dist/fs-utils.js.map +1 -1
  18. package/dist/fs.d.ts +2 -2
  19. package/dist/fs.d.ts.map +1 -1
  20. package/dist/fs.js +4 -7
  21. package/dist/fs.js.map +1 -1
  22. package/dist/git-tracker.d.ts +40 -1
  23. package/dist/git-tracker.d.ts.map +1 -1
  24. package/dist/git-tracker.js +83 -17
  25. package/dist/git-tracker.js.map +1 -1
  26. package/dist/git-utils.d.ts +47 -2
  27. package/dist/git-utils.d.ts.map +1 -1
  28. package/dist/git-utils.js +123 -19
  29. package/dist/git-utils.js.map +1 -1
  30. package/dist/git.d.ts +1 -0
  31. package/dist/git.d.ts.map +1 -1
  32. package/dist/git.js.map +1 -1
  33. package/dist/index.d.ts +4 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +30 -19
  36. package/dist/index.js.map +1 -1
  37. package/dist/listing-refusal.d.ts +111 -0
  38. package/dist/listing-refusal.d.ts.map +1 -0
  39. package/dist/listing-refusal.js +105 -0
  40. package/dist/listing-refusal.js.map +1 -0
  41. package/dist/process.d.ts +7 -0
  42. package/dist/process.d.ts.map +1 -1
  43. package/dist/process.js +7 -0
  44. package/dist/process.js.map +1 -1
  45. package/dist/safe-exec.js +1 -1
  46. package/dist/safe-exec.js.map +1 -1
  47. package/dist/test-helpers.d.ts +20 -0
  48. package/dist/test-helpers.d.ts.map +1 -1
  49. package/dist/test-helpers.js +38 -2
  50. package/dist/test-helpers.js.map +1 -1
  51. package/dist/testing.d.ts +16 -0
  52. package/dist/testing.d.ts.map +1 -1
  53. package/dist/testing.js +17 -0
  54. package/dist/testing.js.map +1 -1
  55. package/eslint/README.md +16 -2
  56. package/eslint/index.cjs +15 -0
  57. package/eslint/index.d.cts +7 -4
  58. package/eslint/rules/no-fragile-entrypoint-guard.cjs +215 -0
  59. package/package.json +3 -3
package/README.md CHANGED
@@ -28,7 +28,7 @@ The last two columns are the ones that matter when choosing. **"Resolves with ze
28
28
  | `./text` | `decodeTextContent` — the one bytes-to-text seam: BOM-announced UTF-8/UTF-16LE/UTF-16BE/UTF-32LE/UTF-32BE, BOM stripped, UTF-8 assumed otherwise; reports the encoding, whether it was a BOM fact or an assumption, and how many U+FFFD the decode substituted | **none** | — | **yes** |
29
29
  | `./zod` | `ZodTypeNames`, `getZodTypeName`, `isZodType`, `unwrapZodType`, `isZodOptional`, `isZodNullable` | **none** | — | **yes** |
30
30
  | `./glob` | `isGlob`, static base extraction, magic remainder | `path` only | — | **yes** |
31
- | `./fs` | `normalizePath`, `normalizedTmpdir`, `mkdirSyncReal`, `resolveFromImportMeta`, `dynamicImportPath`, `copyDirectory`, `fillSiblingNames`, `classifyFilenameCaseFrom`, `FsLookupCache`, `readTextContent`, `readTextContentSync` | `fs`, `fs/promises`, `os`, `path`, `url`, `util` | — | **yes** |
31
+ | `./fs` | `normalizePath`, `normalizedTmpdir`, `mkdirSyncReal`, `resolveFromImportMeta`, `dynamicImportPath`, `copyDirectory`, `fillPathSpellings`, `pathSpellingFrom`, `DirectorySpellingIndex`, `spellingWalkRoot`, `fillRealpaths`, `realpathFrom`, `FsLookupCache`, `readTextContent`, `readTextContentSync` | `fs`, `fs/promises`, `os`, `path`, `url`, `util` | — | **yes** |
32
32
  | `./testing` | `getTestOutputDir`, `getTestOutputBase`, `setupAsyncTempDirSuite`, `setupSyncTempDirSuite`, `removeScratchDir`, `symlinkCapability`, `createSymlink`, `createSymlinkAsync` | `crypto`, `fs`, `fs/promises`, `os`, `path`, `url` | — | **yes** |
33
33
  | `./asset` | `resolveAssetReference` — paths and npm bare specifiers | `fs`, `module`, `os`, `path`, `url` | — | **yes** |
34
34
  | `./yaml` | `updateYamlIn`, `verifyConfinedYamlEdit` — byte-surgical YAML edits | **none** | `yaml` | no — needs `yaml` |
@@ -159,11 +159,19 @@ These return **OS-native** separators, because they resolve real filesystem iden
159
159
  - `resolveFromImportMeta()` - resolve paths relative to an `import.meta.url`
160
160
  - `dynamicImportPath()` - `import()` an absolute path (works on Windows, which rejects bare absolute paths)
161
161
  - `copyDirectory()`
162
- - `fillSiblingNames(filePaths, fsCache)` - pass 1 of the case-exact existence check: list the parent
163
- directory of every path, de-duplicated by directory and issued concurrently. The only I/O in the pair
164
- - `classifyFilenameCaseFrom(table, filePath)` - pass 2: pure judgement against the table pass 1 returned,
165
- reporting the entry actually on disk when only the case differs. Fill **once** over the whole set and
166
- then judge each path — a fill per path reinstates the serialized `readdir` this shape removes
162
+ - `fillPathSpellings(requests, fsCache)` - pass 1 of the case-exact existence check: walk each
163
+ `{ referrer, target }` from the deepest directory the two share, listing every directory on the way
164
+ down exactly once. The only I/O in the pair
165
+ - `pathSpellingFrom(table, referrer, target)` - pass 2: pure judgement against the table pass 1
166
+ returned, reporting the path as disk spells it when the asked-for spelling differs only by case or
167
+ by Unicode normalization. Fill **once** over the whole set and then judge each reference — a fill
168
+ per reference reinstates the serialized `readdir` this shape removes.
169
+ ⚠️ It judges **every component**, not just the basename: judging only the last one hands each
170
+ directory component back to the host filesystem's own folding, so a link that resolves on
171
+ macOS/APFS 404s on a case-sensitive filesystem — and a basename-only correction still leaves the
172
+ author with a broken path
173
+ - `DirectorySpellingIndex` / `spellingWalkRoot(referrer, target)` - the index the pair walks over, and
174
+ the root it walks from, for a caller that cannot enumerate its targets up front
167
175
  - `FsLookupCache` - per-run memo for `realpath`/`readdir`, sharing in-flight promises. Construct one per
168
176
  validation run and let it die with the run — never a module-level singleton, or a long-lived process
169
177
  answers from a stale directory listing.
@@ -211,6 +219,13 @@ They are nonetheless on their own [`./project`](#import-narrowly) entry rather t
211
219
 
212
220
  - `crawlDirectory()` / `crawlDirectorySync()` - gitignore-aware directory walks
213
221
  - `NEVER_CRAWL_GLOBS` / `BUILD_OUTPUT_GLOBS` - the standard exclusion sets
222
+ - `UnreadablePolicy` - the REQUIRED `unreadable` option on every crawl (and on `gitLsFiles` /
223
+ `gitLsOthers` under `./git`): `{ refuse: { root, remedy } }` throws `DirectoryListingRefusedError`
224
+ with an adopter-facing, root-relative sentence when a directory cannot be listed;
225
+ `{ degrade: (refusal) => … }` keeps walking and hands the gap to you to report. There is no
226
+ default — a shorter list nothing can tell from a complete one is the failure this option exists
227
+ to prevent, so the caller states which answer is honest for its lane, and an omitted policy is
228
+ refused up front by name.
214
229
 
215
230
  Glob *pattern inspection* is a separate entry, `./glob`, and stays that way: `./glob` is dependency-free and reaches only `node:path`, whereas crawling reaches the filesystem, `git`, and `picomatch`.
216
231
 
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The one answer to "am I the script Node was asked to run?"
3
+ *
4
+ * Lives here, in the package every other one already depends on, because there
5
+ * has to be exactly one: the question was previously answered three different
6
+ * ways across this monorepo (`import.meta.main`, a raw `pathToFileURL` string
7
+ * compare, and this function), and two of those three answer `false` for the
8
+ * script they guard — which makes the process exit 0 having run nothing.
9
+ */
10
+ /**
11
+ * Was this module invoked as the process entrypoint, rather than imported?
12
+ *
13
+ * ⛔ **Do not reach for `import.meta.main` here.** It shipped in Node 24.2 and
14
+ * 22.18; this repo declares a floor of `>=22.13.0`, and on a real 22.13.0 the
15
+ * property is `undefined`:
16
+ *
17
+ * ```
18
+ * $ node-v22.13.0 --input-type=module -e "console.log(import.meta.main)" -> undefined
19
+ * ```
20
+ *
21
+ * That is not a cosmetic gap. Every `if (import.meta.main)` guard in the
22
+ * dev-tools package was silently dead on the declared floor — running
23
+ * `validate-repo-structure.ts` under 22.13.0 printed nothing and exited 0, so a
24
+ * contributor sitting exactly on the supported Node got a green pre-commit
25
+ * structure gate that had run no rule at all. Raising the floor to 22.18 would
26
+ * have hidden the defect behind the number instead of fixing it.
27
+ *
28
+ * ⛔ **Nor the raw string compare it replaced**, which was the other seven
29
+ * guards in this repo:
30
+ *
31
+ * ```ts
32
+ * import.meta.url === pathToFileURL(process.argv[1]).href // ❌
33
+ * ```
34
+ *
35
+ * A `node_modules/.bin` entry is a SYMLINK to the real script, so `argv[1]` is
36
+ * the link and `import.meta.url` is the resolved target. The two strings differ
37
+ * and the guard is false — measured false through a `.bin`-style symlink on both
38
+ * Node 22.14.0 and 24.13.1, where this function is true.
39
+ *
40
+ * `process.argv[1]` is defined on every Node this repo supports, so the
41
+ * comparison below is the portable form of the same question. The realpath pass
42
+ * covers the case where the script is reached through a symlink on one side of
43
+ * the comparison but not the other.
44
+ *
45
+ * `local/no-fragile-entrypoint-guard` (shipped on this package's `./eslint`
46
+ * subpath) is what keeps either of the two banned spellings from coming back —
47
+ * the prose comments that used to stand in for it did not.
48
+ *
49
+ * @param importMetaUrl - The calling module's `import.meta.url`
50
+ * @param entryPath - The invoked script path; defaults to `process.argv[1]`
51
+ * @returns `true` only when this module is the script Node was asked to run
52
+ */
53
+ export declare function isEntrypoint(importMetaUrl: string, entryPath?: string | undefined): boolean;
54
+ //# sourceMappingURL=entrypoint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,YAAY,CAC1B,aAAa,EAAE,MAAM,EACrB,SAAS,GAAE,MAAM,GAAG,SAA2B,GAC9C,OAAO,CAcT"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * The one answer to "am I the script Node was asked to run?"
3
+ *
4
+ * Lives here, in the package every other one already depends on, because there
5
+ * has to be exactly one: the question was previously answered three different
6
+ * ways across this monorepo (`import.meta.main`, a raw `pathToFileURL` string
7
+ * compare, and this function), and two of those three answer `false` for the
8
+ * script they guard — which makes the process exit 0 having run nothing.
9
+ */
10
+ import { fileURLToPath } from 'node:url';
11
+ import { safePath, toForwardSlash } from './path-core.js';
12
+ import { normalizePath } from './path-utils.js';
13
+ /**
14
+ * Was this module invoked as the process entrypoint, rather than imported?
15
+ *
16
+ * ⛔ **Do not reach for `import.meta.main` here.** It shipped in Node 24.2 and
17
+ * 22.18; this repo declares a floor of `>=22.13.0`, and on a real 22.13.0 the
18
+ * property is `undefined`:
19
+ *
20
+ * ```
21
+ * $ node-v22.13.0 --input-type=module -e "console.log(import.meta.main)" -> undefined
22
+ * ```
23
+ *
24
+ * That is not a cosmetic gap. Every `if (import.meta.main)` guard in the
25
+ * dev-tools package was silently dead on the declared floor — running
26
+ * `validate-repo-structure.ts` under 22.13.0 printed nothing and exited 0, so a
27
+ * contributor sitting exactly on the supported Node got a green pre-commit
28
+ * structure gate that had run no rule at all. Raising the floor to 22.18 would
29
+ * have hidden the defect behind the number instead of fixing it.
30
+ *
31
+ * ⛔ **Nor the raw string compare it replaced**, which was the other seven
32
+ * guards in this repo:
33
+ *
34
+ * ```ts
35
+ * import.meta.url === pathToFileURL(process.argv[1]).href // ❌
36
+ * ```
37
+ *
38
+ * A `node_modules/.bin` entry is a SYMLINK to the real script, so `argv[1]` is
39
+ * the link and `import.meta.url` is the resolved target. The two strings differ
40
+ * and the guard is false — measured false through a `.bin`-style symlink on both
41
+ * Node 22.14.0 and 24.13.1, where this function is true.
42
+ *
43
+ * `process.argv[1]` is defined on every Node this repo supports, so the
44
+ * comparison below is the portable form of the same question. The realpath pass
45
+ * covers the case where the script is reached through a symlink on one side of
46
+ * the comparison but not the other.
47
+ *
48
+ * `local/no-fragile-entrypoint-guard` (shipped on this package's `./eslint`
49
+ * subpath) is what keeps either of the two banned spellings from coming back —
50
+ * the prose comments that used to stand in for it did not.
51
+ *
52
+ * @param importMetaUrl - The calling module's `import.meta.url`
53
+ * @param entryPath - The invoked script path; defaults to `process.argv[1]`
54
+ * @returns `true` only when this module is the script Node was asked to run
55
+ */
56
+ export function isEntrypoint(importMetaUrl, entryPath = process.argv[1]) {
57
+ // An empty argv[1] would resolve to the cwd and could then match a module by
58
+ // accident; `undefined` happens under `node -e`. Neither is an entrypoint.
59
+ if (entryPath === undefined || entryPath === '')
60
+ return false;
61
+ const modulePath = safePath.resolve(fileURLToPath(importMetaUrl));
62
+ const invokedPath = safePath.resolve(entryPath);
63
+ if (modulePath === invokedPath)
64
+ return true;
65
+ // `normalizePath` resolves symlinks and Windows 8.3 short names, and returns
66
+ // the path unchanged when it cannot — which is the right answer here, since
67
+ // the string comparison above has already decided the two differ and an
68
+ // unresolvable path carries no symlink information to compare.
69
+ return toForwardSlash(normalizePath(modulePath)) === toForwardSlash(normalizePath(invokedPath));
70
+ }
71
+ //# sourceMappingURL=entrypoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,UAAU,YAAY,CAC1B,aAAqB,EACrB,YAAgC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAE/C,6EAA6E;IAC7E,2EAA2E;IAC3E,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAE9D,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChD,IAAI,UAAU,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAE5C,6EAA6E;IAC7E,4EAA4E;IAC5E,wEAAwE;IACxE,+DAA+D;IAC/D,OAAO,cAAc,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,KAAK,cAAc,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;AAClG,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Read an environment variable as a boolean.
3
+ *
4
+ * 🔑 **Returns `undefined` for anything it does not recognise, and never
5
+ * guesses.** That is the whole point: the caller — not this function — decides
6
+ * what an unreadable value means, because only the caller knows which way is
7
+ * safe. A token-fetching kill switch wants "deny"; a cache toggle wants
8
+ * "leave the cache on". A parser that folded the unknown case into `false`
9
+ * would have made that choice for both of them.
10
+ *
11
+ * 🚨 **Why this exists at all.** Three switches were each a comparison against
12
+ * the literal string `'0'`, so `=false` turned none of them off — measured for
13
+ * `VAT_LINKAUTH_ALLOW_COMMAND`, which *still spawned subprocesses*. Every
14
+ * spelling a human reaches for (`false`, `no`, `off`, `FALSE`, a value with a
15
+ * stray space) failed open. A switch whose off position is one exact string is
16
+ * not a switch.
17
+ *
18
+ * 📍 **Why it lives in `utils`.** It was written next to its first consumer in
19
+ * `resources`, on the rule that utils takes a utility when a SECOND package
20
+ * needs it rather than speculatively. That second package arrived:
21
+ * `packages/cli`'s `projectionStoreSelected()` reads the same `VAT_CACHE` the
22
+ * `resources` parse cache does, and two independent readings of one variable is
23
+ * the defect, not the fix. The three consumers today:
24
+ *
25
+ * | Caller | Variable | Reads `undefined` as | Why |
26
+ * |---|---|---|---|
27
+ * | `link-auth/resolve-token.ts` | `VAT_LINKAUTH_ALLOW_COMMAND` | **deny** | gates a capability — fail closed |
28
+ * | `resources/parse-cache.ts` | `VAT_CACHE` | cache stays on | gates a cache — an unreadable value must not silently change behaviour |
29
+ * | `cli/utils/projection-store.ts` | `VAT_CACHE` | not a veto | same variable, same reading, one implementation |
30
+ *
31
+ * Same parser, different safe sides, each chosen at its own call site. That is
32
+ * the contract; do not move a default in here.
33
+ */
34
+ /**
35
+ * Parse an env value as a boolean.
36
+ *
37
+ * Case-insensitive and surrounding whitespace is trimmed, because a value that
38
+ * arrived through a shell, a CI YAML block, or a `.env` file routinely carries
39
+ * both. Everything else — including the empty string, which is what an unset
40
+ * shell variable expands to — returns `undefined`.
41
+ *
42
+ * @param raw - The raw env value, or `undefined` when the variable is unset
43
+ * @returns `true` / `false` for a recognised spelling; `undefined` otherwise
44
+ */
45
+ export declare function parseEnvBoolean(raw: string | undefined): boolean | undefined;
46
+ //# sourceMappingURL=env-flag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-flag.d.ts","sourceRoot":"","sources":["../src/env-flag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAKH;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAM5E"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Read an environment variable as a boolean.
3
+ *
4
+ * 🔑 **Returns `undefined` for anything it does not recognise, and never
5
+ * guesses.** That is the whole point: the caller — not this function — decides
6
+ * what an unreadable value means, because only the caller knows which way is
7
+ * safe. A token-fetching kill switch wants "deny"; a cache toggle wants
8
+ * "leave the cache on". A parser that folded the unknown case into `false`
9
+ * would have made that choice for both of them.
10
+ *
11
+ * 🚨 **Why this exists at all.** Three switches were each a comparison against
12
+ * the literal string `'0'`, so `=false` turned none of them off — measured for
13
+ * `VAT_LINKAUTH_ALLOW_COMMAND`, which *still spawned subprocesses*. Every
14
+ * spelling a human reaches for (`false`, `no`, `off`, `FALSE`, a value with a
15
+ * stray space) failed open. A switch whose off position is one exact string is
16
+ * not a switch.
17
+ *
18
+ * 📍 **Why it lives in `utils`.** It was written next to its first consumer in
19
+ * `resources`, on the rule that utils takes a utility when a SECOND package
20
+ * needs it rather than speculatively. That second package arrived:
21
+ * `packages/cli`'s `projectionStoreSelected()` reads the same `VAT_CACHE` the
22
+ * `resources` parse cache does, and two independent readings of one variable is
23
+ * the defect, not the fix. The three consumers today:
24
+ *
25
+ * | Caller | Variable | Reads `undefined` as | Why |
26
+ * |---|---|---|---|
27
+ * | `link-auth/resolve-token.ts` | `VAT_LINKAUTH_ALLOW_COMMAND` | **deny** | gates a capability — fail closed |
28
+ * | `resources/parse-cache.ts` | `VAT_CACHE` | cache stays on | gates a cache — an unreadable value must not silently change behaviour |
29
+ * | `cli/utils/projection-store.ts` | `VAT_CACHE` | not a veto | same variable, same reading, one implementation |
30
+ *
31
+ * Same parser, different safe sides, each chosen at its own call site. That is
32
+ * the contract; do not move a default in here.
33
+ */
34
+ const TRUE_SPELLINGS = new Set(['1', 'true', 'yes', 'y', 'on']);
35
+ const FALSE_SPELLINGS = new Set(['0', 'false', 'no', 'n', 'off']);
36
+ /**
37
+ * Parse an env value as a boolean.
38
+ *
39
+ * Case-insensitive and surrounding whitespace is trimmed, because a value that
40
+ * arrived through a shell, a CI YAML block, or a `.env` file routinely carries
41
+ * both. Everything else — including the empty string, which is what an unset
42
+ * shell variable expands to — returns `undefined`.
43
+ *
44
+ * @param raw - The raw env value, or `undefined` when the variable is unset
45
+ * @returns `true` / `false` for a recognised spelling; `undefined` otherwise
46
+ */
47
+ export function parseEnvBoolean(raw) {
48
+ if (raw === undefined)
49
+ return undefined;
50
+ const normalized = raw.trim().toLowerCase();
51
+ if (TRUE_SPELLINGS.has(normalized))
52
+ return true;
53
+ if (FALSE_SPELLINGS.has(normalized))
54
+ return false;
55
+ return undefined;
56
+ }
57
+ //# sourceMappingURL=env-flag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-flag.js","sourceRoot":"","sources":["../src/env-flag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AACrF,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAEvF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,GAAuB;IACrD,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,IAAI,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAClD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -1,3 +1,6 @@
1
+ import { type UnreadablePolicy } from './listing-refusal.js';
2
+ export type { DirectoryRefusal } from './fs-utils.js';
3
+ export { DirectoryListingRefusedError, type RefuseListingContext, refusedListingMessage, settleRefusal, type UnreadablePolicy, } from './listing-refusal.js';
1
4
  /**
2
5
  * Options for directory crawling
3
6
  */
@@ -35,6 +38,25 @@ export interface CrawlOptions {
35
38
  * committed yet"; `respectGitignore: false` is not, and costs the whole walk.
36
39
  */
37
40
  includeUntracked?: boolean;
41
+ /**
42
+ * What to do with a directory the walk could not LIST. Required, with no
43
+ * default: see {@link UnreadablePolicy} for the two answers and why the
44
+ * caller — not the crawler — is the one who knows which is honest here.
45
+ *
46
+ * A directory that VANISHED between being enumerated and being listed
47
+ * (`ENOENT` / `ENOTDIR`) is not a refusal: it is no longer in the population
48
+ * and is skipped without a call.
49
+ *
50
+ * **Both routes settle it.** The `git ls-files` route walks the working tree
51
+ * whenever {@link CrawlOptions.includeUntracked} is set (`--others`), and a
52
+ * directory git could not open arrives here too — read off git's stderr,
53
+ * where it is the only trace: git exits 0 and lists fewer files. A directory
54
+ * the `exclude` patterns drop is not reported on either route, because the
55
+ * walk never lists one. The tracked-only listing (`includeUntracked: false`)
56
+ * opens no directory at all — the index names every member — so it has no
57
+ * gap to report.
58
+ */
59
+ unreadable: UnreadablePolicy;
38
60
  }
39
61
  /**
40
62
  * Directories no VAT crawl should ever walk into. THE canonical list — any lane
@@ -1 +1 @@
1
- {"version":3,"file":"file-crawler.d.ts","sourceRoot":"","sources":["../src/file-crawler.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,iBAAiB,sJAQpB,CAAC;AAEX;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,yBAA0B,CAAC;AAI1D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAQnC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAE7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,EAAE,CAgQlE"}
1
+ {"version":3,"file":"file-crawler.d.ts","sourceRoot":"","sources":["../src/file-crawler.ts"],"names":[],"mappings":"AAUA,OAAO,EAA0C,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGrG,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,OAAO,EACL,4BAA4B,EAC5B,KAAK,oBAAoB,EACzB,qBAAqB,EACrB,aAAa,EACb,KAAK,gBAAgB,GACtB,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,iBAAiB,sJAQpB,CAAC;AAEX;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,yBAA0B,CAAC;AAI1D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAQnC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAE7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,EAAE,CAuTlE"}
@@ -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
  *
@@ -136,10 +142,30 @@ export async function crawlDirectory(options) {
136
142
  * });
137
143
  */
138
144
  export function crawlDirectorySync(options) {
139
- const { baseDir, include = ['**/*'], exclude = DEFAULT_EXCLUDE, followSymlinks = false, absolute = true, filesOnly = true, respectGitignore = true, includeUntracked = false, } = options;
145
+ const { baseDir, include = ['**/*'], exclude = DEFAULT_EXCLUDE, followSymlinks = false, absolute = true, filesOnly = true, respectGitignore = true, includeUntracked = false, unreadable, } = options;
146
+ requireUnreadablePolicy(unreadable, 'crawlDirectory');
140
147
  const picoOptions = PICOMATCH_OPTIONS;
141
148
  // Resolve base directory to absolute path
142
149
  const resolvedBaseDir = safePath.resolve(baseDir);
150
+ // Compiled once, ahead of the route choice, because BOTH routes ask it: the
151
+ // walk before it lists a directory, the git route before it reports one git
152
+ // could not list. One matcher is what keeps "is this directory excluded?"
153
+ // answered the same way on both sides of the fork.
154
+ const isExcluded = exclude.length > 0 ? picomatch(exclude, picoOptions) : () => false;
155
+ /**
156
+ * Check if a path should be excluded based on patterns
157
+ */
158
+ function shouldExclude(normalizedPath) {
159
+ // Check explicit exclude patterns
160
+ return isExcluded(normalizedPath) || isExcluded(normalizedPath + '/');
161
+ }
162
+ /**
163
+ * A refused listing surfaces under the caller's policy — thrown, or handed
164
+ * over. Never a silent skip, on either route.
165
+ */
166
+ function raiseRefusal(refusal) {
167
+ settleRefusal(unreadable, refusal);
168
+ }
143
169
  // Ensure base directory exists
144
170
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- baseDir is from controlled config, not user input
145
171
  if (!fs.existsSync(resolvedBaseDir)) {
@@ -161,6 +187,24 @@ export function crawlDirectorySync(options) {
161
187
  const gitFiles = gitLsFiles({
162
188
  cwd: resolvedBaseDir,
163
189
  includeUntracked,
190
+ // The SAME decision the walk makes, in the same order: a directory
191
+ // outside this crawl's base or dropped by `exclude` is never listed by
192
+ // the walk, so a refusal on it is not this crawl's gap; anything else
193
+ // is, and goes where the walk's would go.
194
+ // `degrade` from git's side only: the refusal is filtered to this
195
+ // crawl's territory and then settled under the CALLER's policy, which
196
+ // may well be `refuse`.
197
+ unreadable: {
198
+ degrade: (refusal) => {
199
+ // Strictly beneath the base: a repository is often an ancestor of
200
+ // the crawl, and git names every refusal in the whole worktree.
201
+ if (!toForwardSlash(refusal.directory).startsWith(`${toForwardSlash(resolvedBaseDir)}/`))
202
+ return;
203
+ if (shouldExclude(toForwardSlash(safePath.relative(resolvedBaseDir, refusal.directory))))
204
+ return;
205
+ raiseRefusal(refusal);
206
+ },
207
+ },
164
208
  });
165
209
  if (gitFiles !== null) {
166
210
  // ⚠️ KNOWN DIVERGENCE: this branch ignores `followSymlinks`.
@@ -199,7 +243,6 @@ export function crawlDirectorySync(options) {
199
243
  // Fall back to manual directory crawling (not in git repo or git ls-files failed)
200
244
  // Compile glob patterns using picomatch
201
245
  const isIncluded = picomatch(include, picoOptions);
202
- const isExcluded = exclude.length > 0 ? picomatch(exclude, picoOptions) : () => false;
203
246
  const results = [];
204
247
  /**
205
248
  * Real paths of directories already walked, maintained ONLY when following
@@ -218,13 +261,6 @@ export function crawlDirectorySync(options) {
218
261
  * directory cannot be reached twice, so the default path pays no `realpath`.
219
262
  */
220
263
  const visitedRealDirs = new Set();
221
- /**
222
- * Check if a path should be excluded based on patterns
223
- */
224
- function shouldExclude(normalizedPath) {
225
- // Check explicit exclude patterns
226
- return isExcluded(normalizedPath) || isExcluded(normalizedPath + '/');
227
- }
228
264
  /**
229
265
  * Add a path to results if it matches include patterns
230
266
  */
@@ -233,6 +269,27 @@ export function crawlDirectorySync(options) {
233
269
  results.push(absolute ? fullPath : relativePath);
234
270
  }
235
271
  }
272
+ /**
273
+ * What a failed `readdirSync` / `statSync` means for the walk.
274
+ *
275
+ * Absence (`ENOENT` / `ENOTDIR`) is an entry that vanished between being
276
+ * enumerated by its parent and being asked about itself — not in the
277
+ * population, nothing to report. Anything else is a refusal, and a refusal
278
+ * is a GAP: handed to the caller if it asked, thrown otherwise. Never a
279
+ * silent `return` — that is the shorter list this walk used to hand back.
280
+ *
281
+ * @param error - What the filesystem threw
282
+ * @param target - The directory (or link) it was asked about
283
+ * @returns True when the entry is simply gone and the walk should move on
284
+ */
285
+ function reportOrSkip(error, target) {
286
+ const listing = listingFailure(error);
287
+ if (listing.outcome === 'absent')
288
+ return true;
289
+ if (listing.outcome === 'unreadable')
290
+ raiseRefusal(directoryRefusalFor(listing, target));
291
+ return false;
292
+ }
236
293
  /**
237
294
  * Record a directory as walked, reporting whether it had already been seen.
238
295
  *
@@ -272,8 +329,10 @@ export function crawlDirectorySync(options) {
272
329
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated baseDir + entries
273
330
  targetStat = fs.statSync(fullPath);
274
331
  }
275
- catch {
276
- // Skip broken symlinks
332
+ catch (error) {
333
+ // A broken symlink is absence and is skipped; a target the OS refused to
334
+ // stat is a gap, and goes the same way a refused listing does.
335
+ reportOrSkip(error, fullPath);
277
336
  return;
278
337
  }
279
338
  if (targetStat.isDirectory()) {
@@ -312,8 +371,10 @@ export function crawlDirectorySync(options) {
312
371
  // eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated baseDir, recursively walking
313
372
  entries = fs.readdirSync(currentDir, { withFileTypes: true });
314
373
  }
315
- catch {
316
- // Skip directories we don't have permission to read
374
+ catch (error) {
375
+ // 🚨 Not a silent skip. A directory that refused to be listed is a gap in
376
+ // the population this walk defines — see `reportOrSkip`.
377
+ reportOrSkip(error, currentDir);
317
378
  return;
318
379
  }
319
380
  // Two passes, not one: `readdirSync` order is filesystem-defined (see
@@ -1 +1 @@
1
- {"version":3,"file":"file-crawler.js","sourceRoot":"","sources":["../src/file-crawler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file-crawler.js","sourceRoot":"","sources":["../src/file-crawler.ts"],"names":[],"mappings":"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"}