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

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 (102) hide show
  1. package/README.md +6 -3
  2. package/dist/compare-code-units.d.ts +28 -0
  3. package/dist/compare-code-units.d.ts.map +1 -0
  4. package/dist/compare-code-units.js +33 -0
  5. package/dist/compare-code-units.js.map +1 -0
  6. package/dist/crawl-timing.d.ts +680 -0
  7. package/dist/crawl-timing.d.ts.map +1 -0
  8. package/dist/crawl-timing.js +809 -0
  9. package/dist/crawl-timing.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 +31 -7
  13. package/dist/file-crawler.js.map +1 -1
  14. package/dist/fs-utils.d.ts +17 -0
  15. package/dist/fs-utils.d.ts.map +1 -1
  16. package/dist/fs-utils.js +69 -0
  17. package/dist/fs-utils.js.map +1 -1
  18. package/dist/fs.d.ts +3 -1
  19. package/dist/fs.d.ts.map +1 -1
  20. package/dist/fs.js +5 -1
  21. package/dist/fs.js.map +1 -1
  22. package/dist/git-run.d.ts +167 -0
  23. package/dist/git-run.d.ts.map +1 -0
  24. package/dist/git-run.js +154 -0
  25. package/dist/git-run.js.map +1 -0
  26. package/dist/git-snapshot.d.ts +181 -0
  27. package/dist/git-snapshot.d.ts.map +1 -0
  28. package/dist/git-snapshot.js +232 -0
  29. package/dist/git-snapshot.js.map +1 -0
  30. package/dist/git-tracker.d.ts +94 -1
  31. package/dist/git-tracker.d.ts.map +1 -1
  32. package/dist/git-tracker.js +135 -3
  33. package/dist/git-tracker.js.map +1 -1
  34. package/dist/git-utils.d.ts +38 -0
  35. package/dist/git-utils.d.ts.map +1 -1
  36. package/dist/git-utils.js +103 -80
  37. package/dist/git-utils.js.map +1 -1
  38. package/dist/git.d.ts +2 -1
  39. package/dist/git.d.ts.map +1 -1
  40. package/dist/git.js +2 -1
  41. package/dist/git.js.map +1 -1
  42. package/dist/gitignore-checker.d.ts.map +1 -1
  43. package/dist/gitignore-checker.js +6 -3
  44. package/dist/gitignore-checker.js.map +1 -1
  45. package/dist/index.d.ts +8 -1
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +42 -1
  48. package/dist/index.js.map +1 -1
  49. package/dist/link-auth/expand-macro.d.ts.map +1 -1
  50. package/dist/link-auth/expand-macro.js +7 -1
  51. package/dist/link-auth/expand-macro.js.map +1 -1
  52. package/dist/link-auth/resolve-token.d.ts.map +1 -1
  53. package/dist/link-auth/resolve-token.js +15 -1
  54. package/dist/link-auth/resolve-token.js.map +1 -1
  55. package/dist/path-core.d.ts +1 -1
  56. package/dist/path-core.js +1 -1
  57. package/dist/project-utils.d.ts.map +1 -1
  58. package/dist/project-utils.js +6 -3
  59. package/dist/project-utils.js.map +1 -1
  60. package/dist/safe-exec.d.ts +38 -10
  61. package/dist/safe-exec.d.ts.map +1 -1
  62. package/dist/safe-exec.js +88 -19
  63. package/dist/safe-exec.js.map +1 -1
  64. package/dist/skill-test/index.d.ts +1 -1
  65. package/dist/skill-test/index.d.ts.map +1 -1
  66. package/dist/skill-test/index.js +1 -1
  67. package/dist/skill-test/index.js.map +1 -1
  68. package/dist/skill-test/spawn-claude.d.ts +28 -0
  69. package/dist/skill-test/spawn-claude.d.ts.map +1 -1
  70. package/dist/skill-test/spawn-claude.js +51 -2
  71. package/dist/skill-test/spawn-claude.js.map +1 -1
  72. package/dist/skill-test/transcript.d.ts +41 -2
  73. package/dist/skill-test/transcript.d.ts.map +1 -1
  74. package/dist/skill-test/transcript.js +47 -3
  75. package/dist/skill-test/transcript.js.map +1 -1
  76. package/dist/test-helpers.d.ts +185 -13
  77. package/dist/test-helpers.d.ts.map +1 -1
  78. package/dist/test-helpers.js +274 -27
  79. package/dist/test-helpers.js.map +1 -1
  80. package/dist/text-content.d.ts +197 -0
  81. package/dist/text-content.d.ts.map +1 -0
  82. package/dist/text-content.js +348 -0
  83. package/dist/text-content.js.map +1 -0
  84. package/dist/text-file.d.ts +45 -0
  85. package/dist/text-file.d.ts.map +1 -0
  86. package/dist/text-file.js +53 -0
  87. package/dist/text-file.js.map +1 -0
  88. package/dist/text.d.ts +16 -0
  89. package/dist/text.d.ts.map +1 -0
  90. package/dist/text.js +16 -0
  91. package/dist/text.js.map +1 -0
  92. package/dist/timing-dump.d.ts +119 -0
  93. package/dist/timing-dump.d.ts.map +1 -0
  94. package/dist/timing-dump.js +164 -0
  95. package/dist/timing-dump.js.map +1 -0
  96. package/eslint/README.md +105 -3
  97. package/eslint/index.cjs +41 -0
  98. package/eslint/index.d.cts +7 -4
  99. package/eslint/rules/no-bare-symlink-in-tests.cjs +200 -0
  100. package/eslint/rules/no-raw-text-decode.cjs +296 -0
  101. package/eslint/rules/no-self-package-import.cjs +157 -0
  102. package/package.json +9 -2
package/README.md CHANGED
@@ -23,10 +23,11 @@ The last two columns are the ones that matter when choosing. **"Resolves with ze
23
23
  | Subpath | Contents | Node builtins reached | Third-party | Resolves with zero deps installed? |
24
24
  |---|---|---|---|---|
25
25
  | `./path` | `safePath`, `toForwardSlash`, `toNfc`, `isAbsolutePath`, `isAbsoluteAnyPlatform`, `hasParentTraversalSegment`, `toAbsolutePath`, `getRelativePath`, `issueLocation` | `path` only | — | **yes** |
26
+ | `./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** |
26
27
  | `./zod` | `ZodTypeNames`, `getZodTypeName`, `isZodType`, `unwrapZodType`, `isZodOptional`, `isZodNullable` | **none** | — | **yes** |
27
28
  | `./glob` | `isGlob`, static base extraction, magic remainder | `path` only | — | **yes** |
28
- | `./fs` | `normalizePath`, `normalizedTmpdir`, `mkdirSyncReal`, `resolveFromImportMeta`, `dynamicImportPath`, `copyDirectory`, `fillSiblingNames`, `classifyFilenameCaseFrom`, `FsLookupCache` | `fs`, `fs/promises`, `os`, `path`, `url` | — | **yes** |
29
- | `./testing` | `getTestOutputDir`, `getTestOutputBase`, `setupAsyncTempDirSuite`, `setupSyncTempDirSuite` | `crypto`, `fs`, `fs/promises`, `os`, `path`, `url` | — | **yes** |
29
+ | `./fs` | `normalizePath`, `normalizedTmpdir`, `mkdirSyncReal`, `resolveFromImportMeta`, `dynamicImportPath`, `copyDirectory`, `fillSiblingNames`, `classifyFilenameCaseFrom`, `FsLookupCache`, `readTextContent`, `readTextContentSync` | `fs`, `fs/promises`, `os`, `path`, `url` | — | **yes** |
30
+ | `./testing` | `getTestOutputDir`, `getTestOutputBase`, `setupAsyncTempDirSuite`, `setupSyncTempDirSuite`, `removeScratchDir`, `symlinkCapability`, `createSymlink`, `createSymlinkAsync` | `crypto`, `fs`, `fs/promises`, `os`, `path`, `url` | — | **yes** |
30
31
  | `./asset` | `resolveAssetReference` — paths and npm bare specifiers | `fs`, `module`, `os`, `path`, `url` | — | **yes** |
31
32
  | `./yaml` | `updateYamlIn`, `verifyConfinedYamlEdit` — byte-surgical YAML edits | **none** | `yaml` | no — needs `yaml` |
32
33
  | `./template` | `renderTemplate` — cached Handlebars | **none** | `handlebars` | no — needs `handlebars` |
@@ -34,7 +35,7 @@ The last two columns are the ones that matter when choosing. **"Resolves with ze
34
35
  | `./git` | `gitFindRoot`, `gitLsFiles`, `isGitIgnored`, `loadGitignoreRules`, `GitTracker`, `parseGitUrl`, `isGitUrl`, `nonInteractiveGitOverrides` | `child_process`, `fs`, `os`, `path`, `url` | `ignore`, `which` | no — needs `which`, `ignore` |
35
36
  | `./crawl` | `crawlDirectory`, `crawlDirectorySync`, `NEVER_CRAWL_GLOBS`, `BUILD_OUTPUT_GLOBS` | `child_process`, `fs`, `os`, `path`, `url` | `picomatch`, `which` | no — needs `picomatch`, `which` |
36
37
  | `./project` | `findProjectRoot`, `findConfigFile`, `findNodeWorkspaceRoot`, `resetProjectRootCaches` | `fs`, `path` | — | **yes** |
37
- | `./eslint` | the 21 ESLint rules that enforce everything above — see [ESLint rules](#eslint-rules--vibe-agent-toolkitutilseslint) | **none** | — | **yes** |
38
+ | `./eslint` | the 22 ESLint rules that enforce everything above — see [ESLint rules](#eslint-rules--vibe-agent-toolkitutilseslint) | **none** | — | **yes** |
38
39
  | `.` | every runtime entry above (not `./eslint`) | all of the above, plus `stream` | `handlebars`, `ignore`, `picomatch`, `which`, `yaml` | no — needs all of them |
39
40
  | `./package.json` | the manifest itself, for version reporting and resolution assertions | — | — | **yes** |
40
41
 
@@ -183,6 +184,8 @@ These return **OS-native** separators, because they resolve real filesystem iden
183
184
 
184
185
  - `setupAsyncTempDirSuite()` / `setupSyncTempDirSuite()` - per-suite temp directories with cleanup
185
186
  - `getTestOutputDir()` / `getTestOutputBase()` - isolated test output paths
187
+ - `symlinkCapability()` - probes once (memoized per process) whether this host can create symlinks (Windows needs Developer Mode or `SeCreateSymbolicLinkPrivilege`), returning a `SymlinkCapability` token or `null`
188
+ - `createSymlink()` / `createSymlinkAsync()` - the sanctioned way to create a symlink in test code; both require a `SymlinkCapability` from `symlinkCapability()`, so a test cannot reach the raw syscall without first proving the host supports it (or explicitly skipping via vitest's `skip()`)
186
189
 
187
190
  ### Project roots — `@vibe-agent-toolkit/utils` (barrel only)
188
191
 
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Host-independent string ordering, for sorts whose output is hashed or compared
3
+ * across machines.
4
+ *
5
+ * ## Why this is not `localeCompare`
6
+ *
7
+ * `sonarjs/no-alphabetical-sort` fires on a bare `strings.sort()` and its suggested fix is a
8
+ * `localeCompare` comparator. **That fix is wrong for anything whose order feeds a digest, a
9
+ * content key, a serialized document or a golden file.** Collation is locale-dependent, so two
10
+ * machines running the same code over the same corpus can order the same strings differently —
11
+ * destroying exactly the cross-run comparability those artifacts exist to provide. The rule only
12
+ * requires *a* comparator; this is the one to give it.
13
+ *
14
+ * Code-unit order is total, stable and machine-independent. It is not alphabetical in any human
15
+ * sense (uppercase sorts before lowercase, `10` before `2`), which is fine — callers using it are
16
+ * ordering bytes for a machine, not a list for a reader. Sort numbers numerically instead.
17
+ *
18
+ * This lives in `utils` because it had independently grown three identical private copies (in
19
+ * `resources`' projection digest and blob population, and in `claude-marketplace`' plugin extent)
20
+ * and a fourth was nearly written. Three copies of a "never use `localeCompare`" rule is three
21
+ * chances for someone to helpfully replace one of them.
22
+ *
23
+ * @param left - First string
24
+ * @param right - Second string
25
+ * @returns Negative, zero or positive per the `Array.prototype.sort` contract
26
+ */
27
+ export declare function compareCodeUnits(left: string, right: string): number;
28
+ //# sourceMappingURL=compare-code-units.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-code-units.d.ts","sourceRoot":"","sources":["../src/compare-code-units.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKpE"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Host-independent string ordering, for sorts whose output is hashed or compared
3
+ * across machines.
4
+ *
5
+ * ## Why this is not `localeCompare`
6
+ *
7
+ * `sonarjs/no-alphabetical-sort` fires on a bare `strings.sort()` and its suggested fix is a
8
+ * `localeCompare` comparator. **That fix is wrong for anything whose order feeds a digest, a
9
+ * content key, a serialized document or a golden file.** Collation is locale-dependent, so two
10
+ * machines running the same code over the same corpus can order the same strings differently —
11
+ * destroying exactly the cross-run comparability those artifacts exist to provide. The rule only
12
+ * requires *a* comparator; this is the one to give it.
13
+ *
14
+ * Code-unit order is total, stable and machine-independent. It is not alphabetical in any human
15
+ * sense (uppercase sorts before lowercase, `10` before `2`), which is fine — callers using it are
16
+ * ordering bytes for a machine, not a list for a reader. Sort numbers numerically instead.
17
+ *
18
+ * This lives in `utils` because it had independently grown three identical private copies (in
19
+ * `resources`' projection digest and blob population, and in `claude-marketplace`' plugin extent)
20
+ * and a fourth was nearly written. Three copies of a "never use `localeCompare`" rule is three
21
+ * chances for someone to helpfully replace one of them.
22
+ *
23
+ * @param left - First string
24
+ * @param right - Second string
25
+ * @returns Negative, zero or positive per the `Array.prototype.sort` contract
26
+ */
27
+ export function compareCodeUnits(left, right) {
28
+ if (left === right) {
29
+ return 0;
30
+ }
31
+ return left < right ? -1 : 1;
32
+ }
33
+ //# sourceMappingURL=compare-code-units.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-code-units.js","sourceRoot":"","sources":["../src/compare-code-units.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,KAAa;IAC1D,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC"}