@vibe-agent-toolkit/utils 0.2.0-rc.3 → 0.2.0-rc.4

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 (74) hide show
  1. package/README.md +21 -13
  2. package/dist/crawl-timing.d.ts +43 -66
  3. package/dist/crawl-timing.d.ts.map +1 -1
  4. package/dist/crawl-timing.js +35 -79
  5. package/dist/crawl-timing.js.map +1 -1
  6. package/dist/crawl.d.ts +2 -4
  7. package/dist/crawl.d.ts.map +1 -1
  8. package/dist/crawl.js +2 -4
  9. package/dist/crawl.js.map +1 -1
  10. package/dist/git.d.ts +11 -4
  11. package/dist/git.d.ts.map +1 -1
  12. package/dist/git.js +11 -4
  13. package/dist/git.js.map +1 -1
  14. package/dist/index.d.ts +19 -20
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +19 -41
  17. package/dist/index.js.map +1 -1
  18. package/dist/project.d.ts +7 -5
  19. package/dist/project.d.ts.map +1 -1
  20. package/dist/project.js +7 -5
  21. package/dist/project.js.map +1 -1
  22. package/dist/testing.d.ts +73 -3
  23. package/dist/testing.d.ts.map +1 -1
  24. package/dist/testing.js +93 -3
  25. package/dist/testing.js.map +1 -1
  26. package/dist/timing-dump.d.ts +22 -5
  27. package/dist/timing-dump.d.ts.map +1 -1
  28. package/dist/timing-dump.js +89 -23
  29. package/dist/timing-dump.js.map +1 -1
  30. package/eslint/index.cjs +9 -0
  31. package/eslint/index.d.cts +14 -7
  32. package/eslint/rules/no-process-exit-in-phase.cjs +117 -0
  33. package/package.json +5 -7
  34. package/dist/link-auth/build-headers.d.ts +0 -34
  35. package/dist/link-auth/build-headers.d.ts.map +0 -1
  36. package/dist/link-auth/build-headers.js +0 -58
  37. package/dist/link-auth/build-headers.js.map +0 -1
  38. package/dist/link-auth/expand-macro.d.ts +0 -38
  39. package/dist/link-auth/expand-macro.d.ts.map +0 -1
  40. package/dist/link-auth/expand-macro.js +0 -139
  41. package/dist/link-auth/expand-macro.js.map +0 -1
  42. package/dist/link-auth/macros.yaml +0 -50
  43. package/dist/link-auth/resolve-token.d.ts +0 -83
  44. package/dist/link-auth/resolve-token.d.ts.map +0 -1
  45. package/dist/link-auth/resolve-token.js +0 -115
  46. package/dist/link-auth/resolve-token.js.map +0 -1
  47. package/dist/link-auth/resolve.d.ts +0 -102
  48. package/dist/link-auth/resolve.d.ts.map +0 -1
  49. package/dist/link-auth/resolve.js +0 -66
  50. package/dist/link-auth/resolve.js.map +0 -1
  51. package/dist/link-auth/rewrite.d.ts +0 -52
  52. package/dist/link-auth/rewrite.d.ts.map +0 -1
  53. package/dist/link-auth/rewrite.js +0 -102
  54. package/dist/link-auth/rewrite.js.map +0 -1
  55. package/dist/link-auth/select-provider.d.ts +0 -30
  56. package/dist/link-auth/select-provider.d.ts.map +0 -1
  57. package/dist/link-auth/select-provider.js +0 -55
  58. package/dist/link-auth/select-provider.js.map +0 -1
  59. package/dist/link-auth/template.d.ts +0 -40
  60. package/dist/link-auth/template.d.ts.map +0 -1
  61. package/dist/link-auth/template.js +0 -89
  62. package/dist/link-auth/template.js.map +0 -1
  63. package/dist/link-auth/transforms.d.ts +0 -46
  64. package/dist/link-auth/transforms.d.ts.map +0 -1
  65. package/dist/link-auth/transforms.js +0 -52
  66. package/dist/link-auth/transforms.js.map +0 -1
  67. package/dist/template-entry.d.ts +0 -10
  68. package/dist/template-entry.d.ts.map +0 -1
  69. package/dist/template-entry.js +0 -10
  70. package/dist/template-entry.js.map +0 -1
  71. package/dist/template.d.ts +0 -7
  72. package/dist/template.d.ts.map +0 -1
  73. package/dist/template.js +0 -18
  74. package/dist/template.js.map +0 -1
package/README.md CHANGED
@@ -16,7 +16,9 @@ bun add @vibe-agent-toolkit/utils
16
16
 
17
17
  Every area has its own subpath. Import the one you need.
18
18
 
19
- The package sets `"sideEffects": false`, so a modern bundler will tree-shake unused code out of the `.` barrel — importing `safePath` from `.` and from `./path` produce near-identical bundles. **Subpaths are not primarily a size optimization.** What they control is what your build has to *resolve* and what your module graph *reaches*: the `.` barrel reaches `yaml`, `handlebars`, and `node:fs` no matter what you destructure from it, so it cannot be bundled for a browser target and requires every dependency to be installed. A narrow entry reaches only what it needs.
19
+ The package sets `"sideEffects": false`, so a modern bundler will tree-shake unused code out of the `.` barrel — importing `safePath` from `.` and from `./path` produce near-identical bundles. **Subpaths are not primarily a size optimization.** What they control is what your build has to *resolve* and what your module graph *reaches*. A narrow entry reaches only what it needs.
20
+
21
+ **The `.` barrel reaches no third-party package at all.** Every domain that carries a dependency — directly or transitively — is a subpath: `./crawl`, `./git`, `./process`, `./skill-test`, `./yaml`. That is asserted by equality in `test/subpath-purity.test.ts`, so the barrel cannot silently regain one. It still reaches `node:fs` and friends, so it is Node-only; what it does not do is make a consumer of `safePath` install a template engine.
20
22
 
21
23
  The last two columns are the ones that matter when choosing. **"Resolves with zero deps installed?"** is the sharper of the two: it separates an entry that is merely *heavy* from one that is *unbuildable* in an environment where the package's third-party dependencies are absent or unresolvable.
22
24
 
@@ -26,29 +28,35 @@ The last two columns are the ones that matter when choosing. **"Resolves with ze
26
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** |
27
29
  | `./zod` | `ZodTypeNames`, `getZodTypeName`, `isZodType`, `unwrapZodType`, `isZodOptional`, `isZodNullable` | **none** | — | **yes** |
28
30
  | `./glob` | `isGlob`, static base extraction, magic remainder | `path` only | — | **yes** |
29
- | `./fs` | `normalizePath`, `normalizedTmpdir`, `mkdirSyncReal`, `resolveFromImportMeta`, `dynamicImportPath`, `copyDirectory`, `fillSiblingNames`, `classifyFilenameCaseFrom`, `FsLookupCache`, `readTextContent`, `readTextContentSync` | `fs`, `fs/promises`, `os`, `path`, `url` | — | **yes** |
31
+ | `./fs` | `normalizePath`, `normalizedTmpdir`, `mkdirSyncReal`, `resolveFromImportMeta`, `dynamicImportPath`, `copyDirectory`, `fillSiblingNames`, `classifyFilenameCaseFrom`, `FsLookupCache`, `readTextContent`, `readTextContentSync` | `fs`, `fs/promises`, `os`, `path`, `url`, `util` | — | **yes** |
30
32
  | `./testing` | `getTestOutputDir`, `getTestOutputBase`, `setupAsyncTempDirSuite`, `setupSyncTempDirSuite`, `removeScratchDir`, `symlinkCapability`, `createSymlink`, `createSymlinkAsync` | `crypto`, `fs`, `fs/promises`, `os`, `path`, `url` | — | **yes** |
31
33
  | `./asset` | `resolveAssetReference` — paths and npm bare specifiers | `fs`, `module`, `os`, `path`, `url` | — | **yes** |
32
34
  | `./yaml` | `updateYamlIn`, `verifyConfinedYamlEdit` — byte-surgical YAML edits | **none** | `yaml` | no — needs `yaml` |
33
- | `./template` | `renderTemplate` cached Handlebars | **none** | `handlebars` | no — needs `handlebars` |
34
- | `./process` | `safeExecSync`, `safeExecResult`, `safeExecFromString`, `isToolAvailable`, `getToolVersion`, `hasShellSyntax`, `CommandExecutionError`, `spawnHardened`, `shouldUseShell`, `windowsShellQuote`, `buildWindowsShellLine`, `resolveShellCommandToken`, `isPathLike`, `makeStdioBlocking`, `describeStdioBlocking` | `child_process`, `path` | `which` | no — needs `which` |
35
- | `./git` | `gitFindRoot`, `gitLsFiles`, `isGitIgnored`, `loadGitignoreRules`, `GitTracker`, `parseGitUrl`, `isGitUrl`, `nonInteractiveGitOverrides` | `child_process`, `fs`, `os`, `path`, `url` | `ignore`, `which` | no — needs `which`, `ignore` |
36
- | `./crawl` | `crawlDirectory`, `crawlDirectorySync`, `NEVER_CRAWL_GLOBS`, `BUILD_OUTPUT_GLOBS` | `child_process`, `fs`, `os`, `path`, `url` | `picomatch`, `which` | no — needs `picomatch`, `which` |
37
- | `./project` | `findProjectRoot`, `findConfigFile`, `findNodeWorkspaceRoot`, `resetProjectRootCaches` | `fs`, `path` | — | **yes** |
35
+ | `./process` | `safeExecSync`, `safeExecResult`, `safeExecFromString`, `isToolAvailable`, `getToolVersion`, `hasShellSyntax`, `CommandExecutionError`, `spawnHardened`, `shouldUseShell`, `windowsShellQuote`, `buildWindowsShellLine`, `resolveShellCommandToken`, `isPathLike`, `makeStdioBlocking`, `describeStdioBlocking` | `child_process`, `path` | `@vibe-validate/git`, `which` | no — needs both |
36
+ | `./git` | `runGit`, `runGitOrThrow`, `gitFindRoot`, `gitLsFiles`, `gitLsOthers`, `isGitIgnored`, `loadGitignoreRules`, `GitTracker`, `gitTreeSnapshot`, `peekGitTreeSnapshot`, `withGitSnapshotCache`, `parseGitUrl`, `isGitUrl`, `nonInteractiveGitOverrides` | `async_hooks`, `fs`, `fs/promises`, `os`, `path`, `url` | `@vibe-validate/git`, `ignore` | no — needs both |
37
+ | `./crawl` | `crawlDirectory`, `crawlDirectorySync`, `crawlPathFilter`, `NEVER_CRAWL_GLOBS`, `BUILD_OUTPUT_GLOBS` | `fs`, `os`, `path`, `url` | `@vibe-validate/git`, `picomatch` | no — needs both |
38
+ | `./skill-test` | `spawnHeadlessClaude`, `assembleClaudeArgs`, `killAllActiveClaudeChildren`, `resolveAuth`, `probeAuthStatus`, `AuthPreflightError`, `applyDeclaredEnv`, `buildForwardedEnv`, `formatForwardedEnvLine`, `isProtectedName`, `protectedEnvNames`, `parseStreamJsonTranscript`, `detectInvocationFromTranscript` | `child_process`, `path`, `stream` | `@vibe-validate/git`, `which` | no — needs both |
39
+ | `./project` | `findProjectRoot`, `findConfigFile`, `findNodeWorkspaceRoot`, `resetProjectRootCaches` | `fs`, `fs/promises`, `os`, `path`, `url` | — | **yes** |
38
40
  | `./eslint` | the 22 ESLint rules that enforce everything above — see [ESLint rules](#eslint-rules--vibe-agent-toolkitutilseslint) | **none** | — | **yes** |
39
- | `.` | every runtime entry above (not `./eslint`) | all of the above, plus `stream` | `handlebars`, `ignore`, `picomatch`, `which`, `yaml` | no needs all of them |
41
+ | `.` | the dependency-free entries above path, text, fs, asset, project, testing, zod, glob, plus the crawl-timing seam | `async_hooks`, `crypto`, `fs`, `fs/promises`, `module`, `os`, `path`, `url`, `util` | — | **yes** |
40
42
  | `./package.json` | the manifest itself, for version reporting and resolution assertions | — | — | **yes** |
41
43
 
42
44
  Note `./zod` reaches nothing at all: it detects Zod types by duck-typing `_def.typeName` rather than importing Zod, which is exactly why it works across Zod v3 and v4.
43
45
 
44
- `./crawl` is the only *subpath* that reaches `picomatch` (the `.` barrel also reaches it, via linkAuth's host-pattern matching), and it is deliberately *not* folded into `./glob` — `./glob` is guarded as portable (`node:path`, no third-party), and directory crawling would break both halves of that guarantee.
46
+ `./crawl` is the only entry that reaches `picomatch`, and it is deliberately *not* folded into `./glob` — `./glob` is guarded as portable (`node:path`, no third-party), and directory crawling would break both halves of that guarantee.
47
+
48
+ `./skill-test` declares no dependency of its own; it is a separate entry because of what it *reaches*. Spawning a headless agent goes through `./process`, which costs `which` and — because `safeExecSync` refuses the `git` binary and delegates — `@vibe-validate/git`. Reachability is the criterion, not the import a module happens to write.
49
+
50
+ `./git` is the only published route to `runGit`. `safeExecSync` and `safeExecResult` on `./process` refuse `git` outright and point here, so a caller that wants git gets the scrubbed environment by construction rather than by remembering to ask.
45
51
 
46
52
  ```typescript
47
53
  // Reaches node:path and nothing else
48
54
  import { safePath, toForwardSlash } from '@vibe-agent-toolkit/utils/path';
55
+
56
+ // Reaches `which` and @vibe-validate/git — a real install cost, so it is its own entry
49
57
  import { safeExecSync, spawnHardened } from '@vibe-agent-toolkit/utils/process';
50
58
 
51
- // Reaches yaml, handlebars, and node:fs regardless of what you destructure
59
+ // Reaches node builtins only no third-party package, whatever you destructure
52
60
  import { safePath } from '@vibe-agent-toolkit/utils';
53
61
  ```
54
62
 
@@ -62,8 +70,8 @@ This package targets **Node >= 22** and is not published for browsers. Most entr
62
70
 
63
71
  A guard test in `test/subpath-purity.test.ts` walks each entry's transitive source graph and enforces **both** of the table's last two columns:
64
72
 
65
- - **Third-party reach** — the "Resolves with zero deps installed?" column. Every entry's expected third-party set is asserted exactly, so every **yes** row above is a tested claim rather than a documented intention, and adding a dependency to any entry is a deliberate, reviewed edit.
66
- - **Builtin reach** — five entries are held to a stricter contract still: `./zod`, `./yaml`, `./template` reach **no Node builtin at all**, and `./path`, `./glob` reach **`node:path` and nothing else** — the one builtin every bundler shims.
73
+ - **Third-party reach** — the "Resolves with zero deps installed?" column. Every entry's expected third-party set is asserted exactly, so every **yes** row above is a tested claim rather than a documented intention, and adding a dependency to any entry is a deliberate, reviewed edit. The `.` row asserts `[]`, which is the load-bearing one: a dependency arriving on the barrel — through any module it exports, at any depth — reddens that assertion, and the fix is a new subpath rather than a longer expected list.
74
+ - **Builtin reach** — five entries are held to a stricter contract still: `./zod`, `./yaml`, `./text` reach **no Node builtin at all**, and `./path`, `./glob` reach **`node:path` and nothing else** — the one builtin every bundler shims.
67
75
 
68
76
  That is an enforced invariant, not a browser-support commitment: there are no browser export conditions and no browser test lane. The guard exists so the property can't regress silently — it fails loudly if it cannot resolve a module, so it can't pass vacuously; `test/fixtures/dangling-import/` exercises that failure so the guarantee is demonstrated, not just claimed. If you add a new entry, add it to that test or nothing protects it.
69
77
 
@@ -197,7 +205,7 @@ These are CLI-boundary functions: inner libraries should take a root as a parame
197
205
 
198
206
  **These four are VAT-shaped — read this before reaching for them.** `findProjectRoot()` looks for `vibe-agent-toolkit.config.yaml` and then `.git/`; if your repo's notion of "root" is a `pnpm-workspace.yaml`, a `turbo.json`, or a lockfile, that ladder is not your ladder — and for a *published* package, keying anything on `.git/` is a bug, since it will not be there at install time. `findNodeWorkspaceRoot()` is narrower still: it needs a `package.json` carrying a `"workspaces"` key, which pnpm and Bun workspaces do not have. `findConfigFile()` hardcodes VAT's config filename. If you want a git root, take `gitFindRoot()` from [`./git`](#git--vibe-agent-toolkitutilsgit); if you want your own marker, a six-line walk-up is more honest than a helper whose ladder you have to work around.
199
207
 
200
- They are nonetheless on their own [`./project`](#import-narrowly) entry rather than the barrel alone. The entry was briefly withdrawn on the grounds that the functions fit few repos — which is true, and is what the paragraph above says — but that answered the wrong question. What decides whether an *entry* exists is how heavy the only remaining door is: barrel-only, these four cost `handlebars`, `yaml`, `picomatch`, `ignore` and `which` to reach, while their own code imports nothing but `node:fs` and `node:path`. Publishing the entry is not a claim that the ladder fits you — only that finding out shouldn't cost five dependencies.
208
+ They are nonetheless on their own [`./project`](#import-narrowly) entry rather than the barrel alone. The entry was briefly withdrawn on the grounds that the functions fit few repos — which is true, and is what the paragraph above says — but that answered the wrong question. What decides whether an *entry* exists is how heavy the only remaining door is, and barrel-only these four once cost five third-party packages to reach while their own code imports nothing but `node:fs` and `node:path`. Publishing the entry is not a claim that the ladder fits you — only that finding out shouldn't cost a dependency graph. The barrel is dependency-free now, which is that same rule applied everywhere rather than a reason to fold `./project` back in.
201
209
 
202
210
  ### Directory crawling — `@vibe-agent-toolkit/utils/crawl`
203
211
 
@@ -87,7 +87,7 @@
87
87
  * crawl.
88
88
  *
89
89
  * So the registry's own work is charged under `crawl` too
90
- * ({@link CRAWL_REGISTRY_ENUMERATE_ID}, {@link CRAWL_REGISTRY_ADD_RESOURCE_ID},
90
+ * ({@link CRAWL_REGISTRY_ENUMERATE_ID}, {@link CRAWL_REGISTRY_ADMIT_ID},
91
91
  * {@link CRAWL_REGISTRY_RESOLVE_LINKS_ID}), and the brackets live INSIDE
92
92
  * `ResourceRegistry` rather than at the six sites that construct one. Six copies
93
93
  * of the same bracket is six chances to disagree, and a seventh construction site
@@ -303,7 +303,7 @@ export declare const CRAWL_REGISTRY_ID_PREFIX = "resource-registry:";
303
303
  * the `crawlDirectory` call, and nothing that follows it.
304
304
  *
305
305
  * Only the enumeration, so that this row and
306
- * {@link CRAWL_REGISTRY_ADD_RESOURCE_ID} are additive rather than nested:
306
+ * {@link CRAWL_REGISTRY_ADMIT_ID} are additive rather than nested:
307
307
  * `crawl()` is enumeration THEN admission, and bracketing the whole method would
308
308
  * have produced a row that contains the admission row.
309
309
  *
@@ -323,20 +323,38 @@ export declare const CRAWL_REGISTRY_ID_PREFIX = "resource-registry:";
323
323
  */
324
324
  export declare const CRAWL_REGISTRY_ENUMERATE_ID = "resource-registry:enumerate";
325
325
  /**
326
- * Synthetic contributor id for one `ResourceRegistry.addResource` the read, the
327
- * content key, the parse, the stat, the checksum and the four index writes for
328
- * one file.
326
+ * Synthetic contributor id for one `ResourceRegistry.addResources` (or one
327
+ * standalone `addResource`) the reads, the content keys, the parses, the
328
+ * stats, the checksums and the index writes for every file in that call.
329
329
  *
330
- * The per-file grain is deliberate. It is the only grain every construction route
331
- * shares (`crawl` and a direct `addResources` both funnel through it), and it is
332
- * the one that makes the row's ms/call comparable to a projection contributor's:
333
- * this is what admitting a document costs the incumbent.
334
- *
335
- * Charged even when the admission FAILS — a duplicate-id drop and an unreadable
330
+ * Charged even when an admission FAILS a duplicate-id drop and an unreadable
336
331
  * file both cost the read and the parse before they are refused, and a seam that
337
332
  * charged only successes would report a corpus of collisions as nearly free.
333
+ *
334
+ * ## 🚨 Why this is a per-CALL row, and why it was renamed to say so
335
+ *
336
+ * It used to be `resource-registry:add-resource`, bracketing ONE FILE, and that
337
+ * was correct for exactly as long as the lane was sequential. It is not any
338
+ * more: reads and parses now happen with a bounded fan-out
339
+ * (`driveInOrder` in `@vibe-agent-toolkit/resources`), and {@link recordRegistryPass}
340
+ * SUMS each bracket's elapsed time. Overlapping per-file brackets would
341
+ * therefore total up to `width ×` the wall clock they claim to measure — the
342
+ * same shape as the instrument artifact that once reported a 6.5× parse-pool
343
+ * regression that did not exist, where nine worker dumps were summed for one
344
+ * process.
345
+ *
346
+ * ⇒ **One bracket per admission call**, which is the grain
347
+ * {@link CRAWL_BLOB_POPULATE_ID} already uses on the projection arm, so the two
348
+ * arms of the comparison are now measured the same way rather than differently.
349
+ * `calls` reads as "how many times admission ran" and stays divisible.
350
+ *
351
+ * ⭐ **The id changed because the MEANING changed while the shape did not.** A
352
+ * stored dump taken before the split carries per-file milliseconds under the old
353
+ * name; comparing it against a per-call number would be silently wrong in
354
+ * exactly the way no schema catches. With a new name the old row is simply
355
+ * absent, which a reader cannot miss.
338
356
  */
339
- export declare const CRAWL_REGISTRY_ADD_RESOURCE_ID = "resource-registry:add-resource";
357
+ export declare const CRAWL_REGISTRY_ADMIT_ID = "resource-registry:admit";
340
358
  /** Synthetic contributor id for one whole `ResourceRegistry.resolveLinks` call. */
341
359
  export declare const CRAWL_REGISTRY_RESOLVE_LINKS_ID = "resource-registry:resolve-links";
342
360
  /**
@@ -344,7 +362,7 @@ export declare const CRAWL_REGISTRY_RESOLVE_LINKS_ID = "resource-registry:resolv
344
362
  * `populateBlobs`, which reads and parses every path the base contributors keyed
345
363
  * and derives the four blob-keyed tables from it.
346
364
  *
347
- * **This is the projection's analogue of {@link CRAWL_REGISTRY_ADD_RESOURCE_ID},
365
+ * **This is the projection's analogue of {@link CRAWL_REGISTRY_ADMIT_ID},
348
366
  * and it went uncharged while that one was charged.** The asymmetry is why the
349
367
  * bracket exists: the seam's whole purpose is "which of the two crawlers costs
350
368
  * more to do its own work", and an omission on ONE arm biases exactly that
@@ -431,8 +449,8 @@ export declare const CRAWL_SHARED_GIT_TRACKER_ID = "git-tracker:initialize";
431
449
  * arm's total contains, which is a widening read as a movement; the second means
432
450
  * the arms agree and the work genuinely did not happen.
433
451
  *
434
- * {@link CRAWL_SEAM_DUMP_VERSION} was the previous answer and it is a poor one.
435
- * An integer says "different", never "different how", so the remedy for a real
452
+ * A hand-bumped dump version was the previous answer and it is a poor one. An
453
+ * integer says "different", never "different how", so the remedy for a real
436
454
  * widening and for a typo'd field is the same blunt refusal — and, worse, it only
437
455
  * fires if a human remembers to bump it. The `shared` stratum shipped without a
438
456
  * bump on an argument that was correct about rows and wrong about totals; nothing
@@ -476,9 +494,17 @@ export interface CrawlTimingEntry {
476
494
  }
477
495
  /** See {@link TimingProcess}. Lifetime figures, never a crawl duration. */
478
496
  export type CrawlTimingProcess = TimingProcess;
479
- /** The on-disk dump shape. Versioned so a reader can refuse an unknown layout. */
497
+ /**
498
+ * The on-disk dump shape.
499
+ *
500
+ * ⚠️ **There is no version field, and adding one back is a defect.** A reader
501
+ * refuses an unknown layout by validating against its own strict schema, which
502
+ * moves the instant a field here is added, renamed or retyped — where an integer
503
+ * moved only when a human remembered. See {@link CRAWL_CHARGEABLE_IDS} for the
504
+ * half of this that layout validation cannot do, and `lab`'s
505
+ * `harness/dumps.ts` for the reading side.
506
+ */
480
507
  export interface CrawlTimingDump {
481
- dumpVersion: number;
482
508
  pid: number;
483
509
  /** See {@link CrawlTimingProcess}. Never summed across processes by any reader. */
484
510
  process: CrawlTimingProcess;
@@ -504,55 +530,6 @@ export interface CrawlTimingDump {
504
530
  */
505
531
  entries: CrawlTimingEntry[];
506
532
  }
507
- /**
508
- * Bumped whenever the dump's layout — **or the meaning of a row already in it** —
509
- * changes in a way a reader must notice.
510
- *
511
- * The meaning half is not pedantry. A reader that refuses an unknown layout but
512
- * accepts a silently redefined row is worse than one that refuses both: it
513
- * produces numbers, and nobody can state what they are of.
514
- *
515
- * 1 — first version.
516
- * 2 — the `crawl` stratum gained the incumbent's PREPARATION
517
- * (`resource-registry:*`). No field changed. What changed is what a `crawl`
518
- * total is a total OF: traversal alone at v1, the registry build plus the
519
- * traversal at v2. Holding a v1 dump against a v2 one reads that widening as
520
- * a several-hundred-fold regression in the walker — see this module's header.
521
- *
522
- * 3 — the `shared` stratum, and the projection's blob stage
523
- * ({@link CRAWL_BLOB_POPULATE_ID}). No field changed here either, and that
524
- * is exactly why the first attempt at this entry argued no bump was needed:
525
- * `shared` holds work previously charged NOWHERE, so nothing moved out of an
526
- * existing row, and a reader predating it buckets the rows in
527
- * `unclassified`. That argument was **right about rows and wrong about the
528
- * dump**, because the rule above says "the meaning of a row" and the values a
529
- * reader actually publishes are DERIVED:
530
- *
531
- * - a command TOTAL sums every additive row across every stratum, so it grew
532
- * by the whole `git ls-files` spawn — 27% to 100% of the crawl budget
533
- * depending on the corpus. An A/B across the boundary sees that as a real,
534
- * and perfectly STABLE, regression: every pair says `changed` for the same
535
- * reason, which reads as agreement rather than as the tool refusing.
536
- * - `attribution` flips from `nothing-crawled` to `measured` for a command
537
- * that reached no crawler at all, because one shared row is now present.
538
- *
539
- * Both are precisely the v1 -> v2 failure — a widening read as a movement —
540
- * so both get the same remedy. A reader that refuses the dump and says so is
541
- * the loud failure; a reader that publishes a confident false delta is the
542
- * quiet one, and the quiet one is what shipped between these two versions.
543
- * 4 — the dump gained {@link CrawlTimingDump.charges}, and this number stops
544
- * being the mechanism. A layout change, so it costs one last bump; after it,
545
- * a reader diffs what two builds can CHARGE instead of comparing an integer,
546
- * and a widening announces itself without anyone remembering to bump
547
- * anything. Read {@link CRAWL_CHARGEABLE_IDS} for why the integer could never
548
- * have done that job — it says "different", never "different how", and the
549
- * v3 entry above exists precisely because a human did not notice in time.
550
- *
551
- * ⚠️ Keep bumping this for LAYOUT changes; it is still the only thing that can
552
- * refuse a dump whose fields moved. What it is no longer responsible for is
553
- * meaning, which the dump now states for itself.
554
- */
555
- export declare const CRAWL_SEAM_DUMP_VERSION = 4;
556
533
  /**
557
534
  * Start a bracket.
558
535
  *
@@ -1 +1 @@
1
- {"version":3,"file":"crawl-timing.d.ts","sourceRoot":"","sources":["../src/crawl-timing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crawl-timing.d.ts","sourceRoot":"","sources":["../src/crawl-timing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgOG;AAIH,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,YAAY,EAA2C,CAAC;AAE5F;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAAC;AAEpD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,mEAAmE;AACnE,eAAO,MAAM,eAAe,yBAAyB,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AAErE;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,8BAA8B,CAAC;AAEvE,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,qCAAqC,CAAC;AAE3E;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AAEjE,mFAAmF;AACnF,eAAO,MAAM,+BAA+B,oCAAoC,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAcpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAYjD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,0DAA0D;IAC1D,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAED,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,2EAA2E;AAC3E,MAAM,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAE/C;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,mFAAmF;IACnF,OAAO,EAAE,kBAAkB,CAAC;IAC5B;;;;;;;OAOG;IACH,OAAO,EAAE,kBAAkB,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAqID;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,IAAI,CAGN;AAiCD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAGjF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAG/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,OAAO,EAAE,kBAAkB,EAC3B,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACpB,OAAO,CAAC,CAAC,CAAC,CAGZ;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,GAAG,IAAI,CAGP;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAKtE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,eAAe,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,GAAG,IAAI,CAE7D"}
@@ -87,7 +87,7 @@
87
87
  * crawl.
88
88
  *
89
89
  * So the registry's own work is charged under `crawl` too
90
- * ({@link CRAWL_REGISTRY_ENUMERATE_ID}, {@link CRAWL_REGISTRY_ADD_RESOURCE_ID},
90
+ * ({@link CRAWL_REGISTRY_ENUMERATE_ID}, {@link CRAWL_REGISTRY_ADMIT_ID},
91
91
  * {@link CRAWL_REGISTRY_RESOLVE_LINKS_ID}), and the brackets live INSIDE
92
92
  * `ResourceRegistry` rather than at the six sites that construct one. Six copies
93
93
  * of the same bracket is six chances to disagree, and a seventh construction site
@@ -279,7 +279,7 @@ export const CRAWL_REGISTRY_ID_PREFIX = 'resource-registry:';
279
279
  * the `crawlDirectory` call, and nothing that follows it.
280
280
  *
281
281
  * Only the enumeration, so that this row and
282
- * {@link CRAWL_REGISTRY_ADD_RESOURCE_ID} are additive rather than nested:
282
+ * {@link CRAWL_REGISTRY_ADMIT_ID} are additive rather than nested:
283
283
  * `crawl()` is enumeration THEN admission, and bracketing the whole method would
284
284
  * have produced a row that contains the admission row.
285
285
  *
@@ -299,20 +299,38 @@ export const CRAWL_REGISTRY_ID_PREFIX = 'resource-registry:';
299
299
  */
300
300
  export const CRAWL_REGISTRY_ENUMERATE_ID = 'resource-registry:enumerate';
301
301
  /**
302
- * Synthetic contributor id for one `ResourceRegistry.addResource` the read, the
303
- * content key, the parse, the stat, the checksum and the four index writes for
304
- * one file.
302
+ * Synthetic contributor id for one `ResourceRegistry.addResources` (or one
303
+ * standalone `addResource`) the reads, the content keys, the parses, the
304
+ * stats, the checksums and the index writes for every file in that call.
305
305
  *
306
- * The per-file grain is deliberate. It is the only grain every construction route
307
- * shares (`crawl` and a direct `addResources` both funnel through it), and it is
308
- * the one that makes the row's ms/call comparable to a projection contributor's:
309
- * this is what admitting a document costs the incumbent.
310
- *
311
- * Charged even when the admission FAILS — a duplicate-id drop and an unreadable
306
+ * Charged even when an admission FAILS a duplicate-id drop and an unreadable
312
307
  * file both cost the read and the parse before they are refused, and a seam that
313
308
  * charged only successes would report a corpus of collisions as nearly free.
314
- */
315
- export const CRAWL_REGISTRY_ADD_RESOURCE_ID = 'resource-registry:add-resource';
309
+ *
310
+ * ## 🚨 Why this is a per-CALL row, and why it was renamed to say so
311
+ *
312
+ * It used to be `resource-registry:add-resource`, bracketing ONE FILE, and that
313
+ * was correct for exactly as long as the lane was sequential. It is not any
314
+ * more: reads and parses now happen with a bounded fan-out
315
+ * (`driveInOrder` in `@vibe-agent-toolkit/resources`), and {@link recordRegistryPass}
316
+ * SUMS each bracket's elapsed time. Overlapping per-file brackets would
317
+ * therefore total up to `width ×` the wall clock they claim to measure — the
318
+ * same shape as the instrument artifact that once reported a 6.5× parse-pool
319
+ * regression that did not exist, where nine worker dumps were summed for one
320
+ * process.
321
+ *
322
+ * ⇒ **One bracket per admission call**, which is the grain
323
+ * {@link CRAWL_BLOB_POPULATE_ID} already uses on the projection arm, so the two
324
+ * arms of the comparison are now measured the same way rather than differently.
325
+ * `calls` reads as "how many times admission ran" and stays divisible.
326
+ *
327
+ * ⭐ **The id changed because the MEANING changed while the shape did not.** A
328
+ * stored dump taken before the split carries per-file milliseconds under the old
329
+ * name; comparing it against a per-call number would be silently wrong in
330
+ * exactly the way no schema catches. With a new name the old row is simply
331
+ * absent, which a reader cannot miss.
332
+ */
333
+ export const CRAWL_REGISTRY_ADMIT_ID = 'resource-registry:admit';
316
334
  /** Synthetic contributor id for one whole `ResourceRegistry.resolveLinks` call. */
317
335
  export const CRAWL_REGISTRY_RESOLVE_LINKS_ID = 'resource-registry:resolve-links';
318
336
  /**
@@ -320,7 +338,7 @@ export const CRAWL_REGISTRY_RESOLVE_LINKS_ID = 'resource-registry:resolve-links'
320
338
  * `populateBlobs`, which reads and parses every path the base contributors keyed
321
339
  * and derives the four blob-keyed tables from it.
322
340
  *
323
- * **This is the projection's analogue of {@link CRAWL_REGISTRY_ADD_RESOURCE_ID},
341
+ * **This is the projection's analogue of {@link CRAWL_REGISTRY_ADMIT_ID},
324
342
  * and it went uncharged while that one was charged.** The asymmetry is why the
325
343
  * bracket exists: the seam's whole purpose is "which of the two crawlers costs
326
344
  * more to do its own work", and an omission on ONE arm biases exactly that
@@ -418,8 +436,8 @@ const contributorStratum = new AsyncLocalStorage();
418
436
  * arm's total contains, which is a widening read as a movement; the second means
419
437
  * the arms agree and the work genuinely did not happen.
420
438
  *
421
- * {@link CRAWL_SEAM_DUMP_VERSION} was the previous answer and it is a poor one.
422
- * An integer says "different", never "different how", so the remedy for a real
439
+ * A hand-bumped dump version was the previous answer and it is a poor one. An
440
+ * integer says "different", never "different how", so the remedy for a real
423
441
  * widening and for a typo'd field is the same blunt refusal — and, worse, it only
424
442
  * fires if a human remembers to bump it. The `shared` stratum shipped without a
425
443
  * bump on an argument that was correct about rows and wrong about totals; nothing
@@ -439,7 +457,7 @@ export const CRAWL_CHARGEABLE_IDS = [
439
457
  CRAWL_BLOB_POPULATE_ID,
440
458
  CRAWL_CLOSURE_CONTRIBUTE_ID,
441
459
  CRAWL_CLOSURE_RESOLVE_ID,
442
- CRAWL_REGISTRY_ADD_RESOURCE_ID,
460
+ CRAWL_REGISTRY_ADMIT_ID,
443
461
  CRAWL_REGISTRY_ENUMERATE_ID,
444
462
  CRAWL_REGISTRY_RESOLVE_LINKS_ID,
445
463
  CRAWL_SHARED_GIT_TRACKER_ID,
@@ -448,67 +466,6 @@ export const CRAWL_CHARGEABLE_IDS = [
448
466
  CRAWL_WALKER_GITIGNORE_ID,
449
467
  CRAWL_WALKER_ID,
450
468
  ];
451
- /**
452
- * Bumped whenever the dump's layout — **or the meaning of a row already in it** —
453
- * changes in a way a reader must notice.
454
- *
455
- * The meaning half is not pedantry. A reader that refuses an unknown layout but
456
- * accepts a silently redefined row is worse than one that refuses both: it
457
- * produces numbers, and nobody can state what they are of.
458
- *
459
- * 1 — first version.
460
- * 2 — the `crawl` stratum gained the incumbent's PREPARATION
461
- * (`resource-registry:*`). No field changed. What changed is what a `crawl`
462
- * total is a total OF: traversal alone at v1, the registry build plus the
463
- * traversal at v2. Holding a v1 dump against a v2 one reads that widening as
464
- * a several-hundred-fold regression in the walker — see this module's header.
465
- *
466
- * 3 — the `shared` stratum, and the projection's blob stage
467
- * ({@link CRAWL_BLOB_POPULATE_ID}). No field changed here either, and that
468
- * is exactly why the first attempt at this entry argued no bump was needed:
469
- * `shared` holds work previously charged NOWHERE, so nothing moved out of an
470
- * existing row, and a reader predating it buckets the rows in
471
- * `unclassified`. That argument was **right about rows and wrong about the
472
- * dump**, because the rule above says "the meaning of a row" and the values a
473
- * reader actually publishes are DERIVED:
474
- *
475
- * - a command TOTAL sums every additive row across every stratum, so it grew
476
- * by the whole `git ls-files` spawn — 27% to 100% of the crawl budget
477
- * depending on the corpus. An A/B across the boundary sees that as a real,
478
- * and perfectly STABLE, regression: every pair says `changed` for the same
479
- * reason, which reads as agreement rather than as the tool refusing.
480
- * - `attribution` flips from `nothing-crawled` to `measured` for a command
481
- * that reached no crawler at all, because one shared row is now present.
482
- *
483
- * Both are precisely the v1 -> v2 failure — a widening read as a movement —
484
- * so both get the same remedy. A reader that refuses the dump and says so is
485
- * the loud failure; a reader that publishes a confident false delta is the
486
- * quiet one, and the quiet one is what shipped between these two versions.
487
- * 4 — the dump gained {@link CrawlTimingDump.charges}, and this number stops
488
- * being the mechanism. A layout change, so it costs one last bump; after it,
489
- * a reader diffs what two builds can CHARGE instead of comparing an integer,
490
- * and a widening announces itself without anyone remembering to bump
491
- * anything. Read {@link CRAWL_CHARGEABLE_IDS} for why the integer could never
492
- * have done that job — it says "different", never "different how", and the
493
- * v3 entry above exists precisely because a human did not notice in time.
494
- *
495
- * ⚠️ Keep bumping this for LAYOUT changes; it is still the only thing that can
496
- * refuse a dump whose fields moved. What it is no longer responsible for is
497
- * meaning, which the dump now states for itself.
498
- */
499
- export const CRAWL_SEAM_DUMP_VERSION = 4;
500
- /**
501
- * Alias kept for this module's own readability at the write site.
502
- *
503
- * ⚠️ The exported spelling above exists so the READER can pin itself against the
504
- * writer. `@vibe-agent-toolkit/lab`'s `CRAWL_DUMP_VERSION` refuses any dump whose
505
- * version it does not recognise, and the two used to be unrelated literals in
506
- * two packages — drift was silent, and its symptom is not a subtly wrong number
507
- * but **every dump getting refused**, which a reader would sooner blame on their
508
- * own invocation than on a constant. Now the lab pins equality against this
509
- * export, so a bump here that is not mirrored there fails a test instead.
510
- */
511
- const DUMP_VERSION = CRAWL_SEAM_DUMP_VERSION;
512
469
  /** Basename stem of a dump file; the pid (and any collision counter) follow. */
513
470
  const DUMP_BASENAME = 'crawl-timing';
514
471
  /** What this seam is called in a failure line. */
@@ -595,7 +552,6 @@ function compareEntries(left, right) {
595
552
  */
596
553
  function buildDump() {
597
554
  return {
598
- dumpVersion: DUMP_VERSION,
599
555
  pid: process.pid,
600
556
  process: readTimingProcess(),
601
557
  charges: { strata: [...CRAWL_STRATA], syntheticIds: [...CRAWL_CHARGEABLE_IDS] },
@@ -1 +1 @@
1
- {"version":3,"file":"crawl-timing.js","sourceRoot":"","sources":["../src/crawl-timing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crawl-timing.js","sourceRoot":"","sources":["../src/crawl-timing.ts"],"names":[],"mappings":"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"}
package/dist/crawl.d.ts CHANGED
@@ -6,10 +6,8 @@
6
6
  * and shells out to `git` for the gitignore-aware fast path.
7
7
  *
8
8
  * This is the only *subpath* entry that reaches `picomatch` — `./crawl` is
9
- * therefore the narrow entry that makes `picomatch` a required install. It is
10
- * not the package's only consumer of it: `link-auth/select-provider.ts` uses
11
- * `picomatch.isMatch` for host-pattern matching, and that is reachable from the
12
- * `.` barrel.
9
+ * therefore the narrow entry that makes `picomatch` a required install. The `.`
10
+ * barrel reaches it too, through this same `file-crawler` route.
13
11
  *
14
12
  * Deliberately NOT folded into `./glob`. `./glob` is guarded as portable —
15
13
  * `node:path` and no third-party dependency (see `test/subpath-purity.test.ts`)
@@ -1 +1 @@
1
- {"version":3,"file":"crawl.d.ts","sourceRoot":"","sources":["../src/crawl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"crawl.d.ts","sourceRoot":"","sources":["../src/crawl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,mBAAmB,CAAC"}
package/dist/crawl.js CHANGED
@@ -6,10 +6,8 @@
6
6
  * and shells out to `git` for the gitignore-aware fast path.
7
7
  *
8
8
  * This is the only *subpath* entry that reaches `picomatch` — `./crawl` is
9
- * therefore the narrow entry that makes `picomatch` a required install. It is
10
- * not the package's only consumer of it: `link-auth/select-provider.ts` uses
11
- * `picomatch.isMatch` for host-pattern matching, and that is reachable from the
12
- * `.` barrel.
9
+ * therefore the narrow entry that makes `picomatch` a required install. The `.`
10
+ * barrel reaches it too, through this same `file-crawler` route.
13
11
  *
14
12
  * Deliberately NOT folded into `./glob`. `./glob` is guarded as portable —
15
13
  * `node:path` and no third-party dependency (see `test/subpath-purity.test.ts`)
package/dist/crawl.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"crawl.js","sourceRoot":"","sources":["../src/crawl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"crawl.js","sourceRoot":"","sources":["../src/crawl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc,mBAAmB,CAAC"}
package/dist/git.d.ts CHANGED
@@ -1,9 +1,15 @@
1
1
  /**
2
2
  * @vibe-agent-toolkit/utils/git
3
3
  *
4
- * Git primitives for build guards and gates: root discovery, tracked-file
5
- * enumeration, gitignore evaluation, and git URL parsing. Node-only —
6
- * shells out to `git` and reads the filesystem.
4
+ * Git primitives for build guards and gates: command execution, root discovery,
5
+ * tracked-file enumeration, tree snapshots, gitignore evaluation, and git URL
6
+ * parsing. Node-only — shells out to `git` and reads the filesystem.
7
+ *
8
+ * This is the ONLY published route to `runGit`. `safeExecSync`/`safeExecResult`
9
+ * on `./process` refuse the `git` binary outright and point here, so a caller
10
+ * that wants git gets the scrubbed environment rather than the ambient one by
11
+ * construction. The scrub itself, and dirty-corrected tree snapshots, come from
12
+ * `@vibe-validate/git`.
7
13
  *
8
14
  * The re-exports below are explicit rather than `export *` on purpose. A
9
15
  * blanket re-export surfaced TWO root finders under two names — `gitFindRoot`
@@ -16,8 +22,9 @@
16
22
  * old code rather than maintain two APIs). `gitFindRoot` is the only root
17
23
  * finder in the package.
18
24
  */
25
+ export { runGit, runGitOrThrow, type GitRunOptions, type GitRunResult, } from './git-run.js';
19
26
  export { gitFindRoot, gitLsFiles, gitLsOthers, isGitIgnored } from './git-utils.js';
20
- export { gitTreeSnapshot, withGitSnapshotCache, type GitSnapshotEntry, type GitTreeSnapshot, } from './git-snapshot.js';
27
+ export { gitTreeSnapshot, peekGitTreeSnapshot, withGitSnapshotCache, type GitSnapshotEntry, type GitTreeSnapshot, } from './git-snapshot.js';
21
28
  export { loadGitignoreRules } from './gitignore-checker.js';
22
29
  export { GitTracker, type GitTrackerInitOptions } from './git-tracker.js';
23
30
  export { isGitUrl, nonInteractiveGitOverrides, parseGitUrl, type NonInteractiveGitOverrides, type ParsedGitUrl, } from './git-url.js';
package/dist/git.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,WAAW,EACX,KAAK,0BAA0B,EAC/B,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACL,MAAM,EACN,aAAa,EACb,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,WAAW,EACX,KAAK,0BAA0B,EAC/B,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC"}
package/dist/git.js CHANGED
@@ -1,9 +1,15 @@
1
1
  /**
2
2
  * @vibe-agent-toolkit/utils/git
3
3
  *
4
- * Git primitives for build guards and gates: root discovery, tracked-file
5
- * enumeration, gitignore evaluation, and git URL parsing. Node-only —
6
- * shells out to `git` and reads the filesystem.
4
+ * Git primitives for build guards and gates: command execution, root discovery,
5
+ * tracked-file enumeration, tree snapshots, gitignore evaluation, and git URL
6
+ * parsing. Node-only — shells out to `git` and reads the filesystem.
7
+ *
8
+ * This is the ONLY published route to `runGit`. `safeExecSync`/`safeExecResult`
9
+ * on `./process` refuse the `git` binary outright and point here, so a caller
10
+ * that wants git gets the scrubbed environment rather than the ambient one by
11
+ * construction. The scrub itself, and dirty-corrected tree snapshots, come from
12
+ * `@vibe-validate/git`.
7
13
  *
8
14
  * The re-exports below are explicit rather than `export *` on purpose. A
9
15
  * blanket re-export surfaced TWO root finders under two names — `gitFindRoot`
@@ -16,8 +22,9 @@
16
22
  * old code rather than maintain two APIs). `gitFindRoot` is the only root
17
23
  * finder in the package.
18
24
  */
25
+ export { runGit, runGitOrThrow, } from './git-run.js';
19
26
  export { gitFindRoot, gitLsFiles, gitLsOthers, isGitIgnored } from './git-utils.js';
20
- export { gitTreeSnapshot, withGitSnapshotCache, } from './git-snapshot.js';
27
+ export { gitTreeSnapshot, peekGitTreeSnapshot, withGitSnapshotCache, } from './git-snapshot.js';
21
28
  export { loadGitignoreRules } from './gitignore-checker.js';
22
29
  export { GitTracker } from './git-tracker.js';
23
30
  export { isGitUrl, nonInteractiveGitOverrides, parseGitUrl, } from './git-url.js';
package/dist/git.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EACL,eAAe,EACf,oBAAoB,GAGrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAA8B,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,WAAW,GAGZ,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACL,MAAM,EACN,aAAa,GAGd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GAGrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAA8B,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,WAAW,GAGZ,MAAM,cAAc,CAAC"}