@vibe-agent-toolkit/utils 0.2.0-rc.11 → 0.2.0-rc.12

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 (322) hide show
  1. package/README.md +111 -9
  2. package/dist/archive/archive.d.ts +129 -0
  3. package/dist/archive/archive.d.ts.map +1 -0
  4. package/dist/archive/archive.js +223 -0
  5. package/dist/archive/archive.js.map +1 -0
  6. package/dist/archive/entries.d.ts +132 -0
  7. package/dist/archive/entries.d.ts.map +1 -0
  8. package/dist/archive/entries.js +223 -0
  9. package/dist/archive/entries.js.map +1 -0
  10. package/dist/archive/limits.d.ts +39 -0
  11. package/dist/archive/limits.d.ts.map +1 -0
  12. package/dist/archive/limits.js +59 -0
  13. package/dist/archive/limits.js.map +1 -0
  14. package/dist/archive/records.d.ts +14 -0
  15. package/dist/archive/records.d.ts.map +1 -0
  16. package/dist/archive/records.js +3 -0
  17. package/dist/archive/records.js.map +1 -0
  18. package/dist/archive/tar-reader.d.ts +18 -0
  19. package/dist/archive/tar-reader.d.ts.map +1 -0
  20. package/dist/archive/tar-reader.js +173 -0
  21. package/dist/archive/tar-reader.js.map +1 -0
  22. package/dist/archive/zip-reader.d.ts +76 -0
  23. package/dist/archive/zip-reader.d.ts.map +1 -0
  24. package/dist/archive/zip-reader.js +376 -0
  25. package/dist/archive/zip-reader.js.map +1 -0
  26. package/dist/archive.d.ts +14 -0
  27. package/dist/archive.d.ts.map +1 -0
  28. package/dist/archive.js +12 -0
  29. package/dist/archive.js.map +1 -0
  30. package/dist/asset-reference.d.ts +17 -1
  31. package/dist/asset-reference.d.ts.map +1 -1
  32. package/dist/asset-reference.js +31 -7
  33. package/dist/asset-reference.js.map +1 -1
  34. package/dist/dirent-kind.d.ts +13 -40
  35. package/dist/dirent-kind.d.ts.map +1 -1
  36. package/dist/dirent-kind.js +21 -69
  37. package/dist/dirent-kind.js.map +1 -1
  38. package/dist/entrypoint.d.ts +2 -2
  39. package/dist/entrypoint.d.ts.map +1 -1
  40. package/dist/entrypoint.js +4 -3
  41. package/dist/entrypoint.js.map +1 -1
  42. package/dist/env-flag.d.ts +2 -0
  43. package/dist/env-flag.d.ts.map +1 -1
  44. package/dist/env-flag.js +2 -0
  45. package/dist/env-flag.js.map +1 -1
  46. package/dist/errors/confirmed-absent.d.ts +41 -0
  47. package/dist/errors/confirmed-absent.d.ts.map +1 -0
  48. package/dist/errors/confirmed-absent.js +43 -0
  49. package/dist/errors/confirmed-absent.js.map +1 -0
  50. package/dist/errors/errno-table.d.ts +177 -0
  51. package/dist/errors/errno-table.d.ts.map +1 -0
  52. package/dist/errors/errno-table.js +343 -0
  53. package/dist/errors/errno-table.js.map +1 -0
  54. package/dist/errors/fs-boundary.d.ts +36 -0
  55. package/dist/errors/fs-boundary.d.ts.map +1 -0
  56. package/dist/errors/fs-boundary.js +121 -0
  57. package/dist/errors/fs-boundary.js.map +1 -0
  58. package/dist/errors/fs-fault.d.ts +176 -0
  59. package/dist/errors/fs-fault.d.ts.map +1 -0
  60. package/dist/errors/fs-fault.js +215 -0
  61. package/dist/errors/fs-fault.js.map +1 -0
  62. package/dist/errors/git-errno.d.ts +13 -0
  63. package/dist/errors/git-errno.d.ts.map +1 -0
  64. package/dist/errors/git-errno.js +45 -0
  65. package/dist/errors/git-errno.js.map +1 -0
  66. package/dist/errors/path-present.d.ts +72 -0
  67. package/dist/errors/path-present.d.ts.map +1 -0
  68. package/dist/errors/path-present.js +110 -0
  69. package/dist/errors/path-present.js.map +1 -0
  70. package/dist/errors/rag-index-empty.d.ts +16 -0
  71. package/dist/errors/rag-index-empty.d.ts.map +1 -0
  72. package/dist/errors/rag-index-empty.js +16 -0
  73. package/dist/errors/rag-index-empty.js.map +1 -0
  74. package/dist/errors/suppressed-faults.d.ts +34 -0
  75. package/dist/errors/suppressed-faults.d.ts.map +1 -0
  76. package/dist/errors/suppressed-faults.js +66 -0
  77. package/dist/errors/suppressed-faults.js.map +1 -0
  78. package/dist/file-crawler.d.ts +13 -18
  79. package/dist/file-crawler.d.ts.map +1 -1
  80. package/dist/file-crawler.js +140 -24
  81. package/dist/file-crawler.js.map +1 -1
  82. package/dist/fs-utils.d.ts +75 -50
  83. package/dist/fs-utils.d.ts.map +1 -1
  84. package/dist/fs-utils.js +148 -158
  85. package/dist/fs-utils.js.map +1 -1
  86. package/dist/fs.d.ts +4 -4
  87. package/dist/fs.d.ts.map +1 -1
  88. package/dist/fs.js +4 -4
  89. package/dist/fs.js.map +1 -1
  90. package/dist/git-snapshot.d.ts +25 -17
  91. package/dist/git-snapshot.d.ts.map +1 -1
  92. package/dist/git-snapshot.js +65 -11
  93. package/dist/git-snapshot.js.map +1 -1
  94. package/dist/git-tracker.d.ts +11 -3
  95. package/dist/git-tracker.d.ts.map +1 -1
  96. package/dist/git-tracker.js +29 -6
  97. package/dist/git-tracker.js.map +1 -1
  98. package/dist/git-utils.d.ts.map +1 -1
  99. package/dist/git-utils.js +7 -35
  100. package/dist/git-utils.js.map +1 -1
  101. package/dist/git.d.ts +1 -1
  102. package/dist/git.d.ts.map +1 -1
  103. package/dist/git.js +1 -1
  104. package/dist/git.js.map +1 -1
  105. package/dist/gitignore-checker.d.ts.map +1 -1
  106. package/dist/gitignore-checker.js +5 -4
  107. package/dist/gitignore-checker.js.map +1 -1
  108. package/dist/in-order.d.ts +93 -0
  109. package/dist/in-order.d.ts.map +1 -0
  110. package/dist/in-order.js +165 -0
  111. package/dist/in-order.js.map +1 -0
  112. package/dist/index.d.ts +20 -4
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +30 -4
  115. package/dist/index.js.map +1 -1
  116. package/dist/kill-process-tree.d.ts +43 -0
  117. package/dist/kill-process-tree.d.ts.map +1 -0
  118. package/dist/kill-process-tree.js +48 -0
  119. package/dist/kill-process-tree.js.map +1 -0
  120. package/dist/link-following.d.ts +115 -0
  121. package/dist/link-following.d.ts.map +1 -0
  122. package/dist/link-following.js +283 -0
  123. package/dist/link-following.js.map +1 -0
  124. package/dist/listing-refusal.d.ts +44 -0
  125. package/dist/listing-refusal.d.ts.map +1 -1
  126. package/dist/listing-refusal.js +79 -2
  127. package/dist/listing-refusal.js.map +1 -1
  128. package/dist/name-fold.d.ts +25 -0
  129. package/dist/name-fold.d.ts.map +1 -0
  130. package/dist/name-fold.js +40 -0
  131. package/dist/name-fold.js.map +1 -0
  132. package/dist/path-containment.d.ts +3 -1
  133. package/dist/path-containment.d.ts.map +1 -1
  134. package/dist/path-containment.js +13 -7
  135. package/dist/path-containment.js.map +1 -1
  136. package/dist/path-utils.d.ts +14 -17
  137. package/dist/path-utils.d.ts.map +1 -1
  138. package/dist/path-utils.js +37 -55
  139. package/dist/path-utils.js.map +1 -1
  140. package/dist/process.d.ts +2 -0
  141. package/dist/process.d.ts.map +1 -1
  142. package/dist/process.js +2 -0
  143. package/dist/process.js.map +1 -1
  144. package/dist/project-utils.d.ts.map +1 -1
  145. package/dist/project-utils.js +8 -9
  146. package/dist/project-utils.js.map +1 -1
  147. package/dist/safe-exec.d.ts +6 -2
  148. package/dist/safe-exec.d.ts.map +1 -1
  149. package/dist/safe-exec.js +1 -1
  150. package/dist/safe-exec.js.map +1 -1
  151. package/dist/skill-targets.d.ts.map +1 -1
  152. package/dist/skill-targets.js +3 -1
  153. package/dist/skill-targets.js.map +1 -1
  154. package/dist/skill-test/spawn-claude.d.ts +0 -15
  155. package/dist/skill-test/spawn-claude.d.ts.map +1 -1
  156. package/dist/skill-test/spawn-claude.js +11 -50
  157. package/dist/skill-test/spawn-claude.js.map +1 -1
  158. package/dist/special-file.d.ts +18 -0
  159. package/dist/special-file.d.ts.map +1 -0
  160. package/dist/special-file.js +21 -0
  161. package/dist/special-file.js.map +1 -0
  162. package/dist/terminating-signals.d.ts +129 -0
  163. package/dist/terminating-signals.d.ts.map +1 -0
  164. package/dist/terminating-signals.js +210 -0
  165. package/dist/terminating-signals.js.map +1 -0
  166. package/dist/test-helpers.d.ts +9 -5
  167. package/dist/test-helpers.d.ts.map +1 -1
  168. package/dist/test-helpers.js +18 -21
  169. package/dist/test-helpers.js.map +1 -1
  170. package/dist/test-scratch-guard.d.ts +34 -0
  171. package/dist/test-scratch-guard.d.ts.map +1 -0
  172. package/dist/test-scratch-guard.js +45 -0
  173. package/dist/test-scratch-guard.js.map +1 -0
  174. package/dist/testing/archive-fixtures.d.ts +147 -0
  175. package/dist/testing/archive-fixtures.d.ts.map +1 -0
  176. package/dist/testing/archive-fixtures.js +449 -0
  177. package/dist/testing/archive-fixtures.js.map +1 -0
  178. package/dist/testing/executables.d.ts +6 -0
  179. package/dist/testing/executables.d.ts.map +1 -1
  180. package/dist/testing/executables.js +20 -9
  181. package/dist/testing/executables.js.map +1 -1
  182. package/dist/testing/fault-fs-preload.d.ts +16 -0
  183. package/dist/testing/fault-fs-preload.d.ts.map +1 -0
  184. package/dist/testing/fault-fs-preload.js +22 -0
  185. package/dist/testing/fault-fs-preload.js.map +1 -0
  186. package/dist/testing/fault-fs.d.ts +115 -0
  187. package/dist/testing/fault-fs.d.ts.map +1 -0
  188. package/dist/testing/fault-fs.js +411 -0
  189. package/dist/testing/fault-fs.js.map +1 -0
  190. package/dist/testing/fault-spec.d.ts +83 -0
  191. package/dist/testing/fault-spec.d.ts.map +1 -0
  192. package/dist/testing/fault-spec.js +132 -0
  193. package/dist/testing/fault-spec.js.map +1 -0
  194. package/dist/testing/hostile-tree.d.ts.map +1 -1
  195. package/dist/testing/hostile-tree.js +3 -4
  196. package/dist/testing/hostile-tree.js.map +1 -1
  197. package/dist/testing/platform-gates.d.ts +8 -0
  198. package/dist/testing/platform-gates.d.ts.map +1 -1
  199. package/dist/testing/platform-gates.js +24 -0
  200. package/dist/testing/platform-gates.js.map +1 -1
  201. package/dist/testing/temp-dir.d.ts +31 -0
  202. package/dist/testing/temp-dir.d.ts.map +1 -1
  203. package/dist/testing/temp-dir.js +63 -0
  204. package/dist/testing/temp-dir.js.map +1 -1
  205. package/dist/testing/tier-timeout.d.ts +34 -0
  206. package/dist/testing/tier-timeout.d.ts.map +1 -0
  207. package/dist/testing/tier-timeout.js +45 -0
  208. package/dist/testing/tier-timeout.js.map +1 -0
  209. package/dist/testing/tree-snapshot.d.ts +71 -0
  210. package/dist/testing/tree-snapshot.d.ts.map +1 -0
  211. package/dist/testing/tree-snapshot.js +163 -0
  212. package/dist/testing/tree-snapshot.js.map +1 -0
  213. package/dist/testing.d.ts +6 -0
  214. package/dist/testing.d.ts.map +1 -1
  215. package/dist/testing.js +8 -1
  216. package/dist/testing.js.map +1 -1
  217. package/dist/text-file.d.ts +14 -1
  218. package/dist/text-file.d.ts.map +1 -1
  219. package/dist/text-file.js +41 -8
  220. package/dist/text-file.js.map +1 -1
  221. package/dist/timing-dump.d.ts.map +1 -1
  222. package/dist/timing-dump.js +2 -10
  223. package/dist/timing-dump.js.map +1 -1
  224. package/dist/tree-change/apply-decisions.d.ts +101 -0
  225. package/dist/tree-change/apply-decisions.d.ts.map +1 -0
  226. package/dist/tree-change/apply-decisions.js +139 -0
  227. package/dist/tree-change/apply-decisions.js.map +1 -0
  228. package/dist/tree-change/apply.d.ts +98 -0
  229. package/dist/tree-change/apply.d.ts.map +1 -0
  230. package/dist/tree-change/apply.js +364 -0
  231. package/dist/tree-change/apply.js.map +1 -0
  232. package/dist/tree-change/copy-decisions.d.ts +58 -0
  233. package/dist/tree-change/copy-decisions.d.ts.map +1 -0
  234. package/dist/tree-change/copy-decisions.js +66 -0
  235. package/dist/tree-change/copy-decisions.js.map +1 -0
  236. package/dist/tree-change/copy-tree.d.ts +125 -0
  237. package/dist/tree-change/copy-tree.d.ts.map +1 -0
  238. package/dist/tree-change/copy-tree.js +279 -0
  239. package/dist/tree-change/copy-tree.js.map +1 -0
  240. package/dist/tree-change/files.d.ts +167 -0
  241. package/dist/tree-change/files.d.ts.map +1 -0
  242. package/dist/tree-change/files.js +423 -0
  243. package/dist/tree-change/files.js.map +1 -0
  244. package/dist/tree-change/followed-walk.d.ts +54 -0
  245. package/dist/tree-change/followed-walk.d.ts.map +1 -0
  246. package/dist/tree-change/followed-walk.js +81 -0
  247. package/dist/tree-change/followed-walk.js.map +1 -0
  248. package/dist/tree-change/host-chain.d.ts +48 -0
  249. package/dist/tree-change/host-chain.d.ts.map +1 -0
  250. package/dist/tree-change/host-chain.js +85 -0
  251. package/dist/tree-change/host-chain.js.map +1 -0
  252. package/dist/tree-change/identity-compare.d.ts +61 -0
  253. package/dist/tree-change/identity-compare.d.ts.map +1 -0
  254. package/dist/tree-change/identity-compare.js +115 -0
  255. package/dist/tree-change/identity-compare.js.map +1 -0
  256. package/dist/tree-change/identity.d.ts +62 -0
  257. package/dist/tree-change/identity.d.ts.map +1 -0
  258. package/dist/tree-change/identity.js +152 -0
  259. package/dist/tree-change/identity.js.map +1 -0
  260. package/dist/tree-change/index.d.ts +24 -0
  261. package/dist/tree-change/index.d.ts.map +1 -0
  262. package/dist/tree-change/index.js +14 -0
  263. package/dist/tree-change/index.js.map +1 -0
  264. package/dist/tree-change/link-chain.d.ts +180 -0
  265. package/dist/tree-change/link-chain.d.ts.map +1 -0
  266. package/dist/tree-change/link-chain.js +377 -0
  267. package/dist/tree-change/link-chain.js.map +1 -0
  268. package/dist/tree-change/link-containment.d.ts +105 -0
  269. package/dist/tree-change/link-containment.d.ts.map +1 -0
  270. package/dist/tree-change/link-containment.js +196 -0
  271. package/dist/tree-change/link-containment.js.map +1 -0
  272. package/dist/tree-change/link-walk.d.ts +49 -0
  273. package/dist/tree-change/link-walk.d.ts.map +1 -0
  274. package/dist/tree-change/link-walk.js +69 -0
  275. package/dist/tree-change/link-walk.js.map +1 -0
  276. package/dist/tree-change/plan.d.ts +206 -0
  277. package/dist/tree-change/plan.d.ts.map +1 -0
  278. package/dist/tree-change/plan.js +320 -0
  279. package/dist/tree-change/plan.js.map +1 -0
  280. package/dist/tree-change/readable-tree.d.ts +44 -0
  281. package/dist/tree-change/readable-tree.d.ts.map +1 -0
  282. package/dist/tree-change/readable-tree.js +52 -0
  283. package/dist/tree-change/readable-tree.js.map +1 -0
  284. package/dist/tree-change/rollback-error.d.ts +29 -0
  285. package/dist/tree-change/rollback-error.d.ts.map +1 -0
  286. package/dist/tree-change/rollback-error.js +31 -0
  287. package/dist/tree-change/rollback-error.js.map +1 -0
  288. package/dist/tree-change/staging-names.d.ts +27 -0
  289. package/dist/tree-change/staging-names.d.ts.map +1 -0
  290. package/dist/tree-change/staging-names.js +40 -0
  291. package/dist/tree-change/staging-names.js.map +1 -0
  292. package/dist/tree-change/tree-walk.d.ts +81 -0
  293. package/dist/tree-change/tree-walk.d.ts.map +1 -0
  294. package/dist/tree-change/tree-walk.js +212 -0
  295. package/dist/tree-change/tree-walk.js.map +1 -0
  296. package/dist/win32-namespace.d.ts +24 -0
  297. package/dist/win32-namespace.d.ts.map +1 -0
  298. package/dist/win32-namespace.js +31 -0
  299. package/dist/win32-namespace.js.map +1 -0
  300. package/dist/yaml/surgical-yaml.d.ts +12 -3
  301. package/dist/yaml/surgical-yaml.d.ts.map +1 -1
  302. package/dist/yaml/surgical-yaml.js +16 -6
  303. package/dist/yaml/surgical-yaml.js.map +1 -1
  304. package/eslint/README.md +12 -4
  305. package/eslint/rules/fs-binding-scan.cjs +278 -0
  306. package/eslint/rules/no-adhoc-errno.cjs +364 -0
  307. package/eslint/rules/no-bare-symlink-in-tests.cjs +2 -3
  308. package/eslint/rules/no-blind-catch.cjs +1 -1
  309. package/eslint/rules/no-destructive-fs.cjs +359 -0
  310. package/eslint/rules/no-existssync.cjs +70 -0
  311. package/eslint/rules/no-fragile-entrypoint-guard.cjs +3 -2
  312. package/eslint/rules/no-link-following-fs.cjs +68 -0
  313. package/eslint/rules/no-literal-process-exit.cjs +3 -16
  314. package/eslint/rules/no-literal-test-timeout.cjs +214 -0
  315. package/eslint/rules/no-raw-signal-listener.cjs +224 -0
  316. package/eslint/rules/no-stdout-outside-writer.cjs +135 -0
  317. package/package.json +10 -2
  318. package/dist/errors/errno.d.ts +0 -51
  319. package/dist/errors/errno.d.ts.map +0 -1
  320. package/dist/errors/errno.js +0 -112
  321. package/dist/errors/errno.js.map +0 -1
  322. package/eslint/rules/no-fs-promises-cp.cjs +0 -43
@@ -0,0 +1,81 @@
1
+ /**
2
+ * The one walk over a tree that is about to be read whole: `proveTreeReadable`
3
+ * runs it to prove a source before anything is written, and `copyTree` runs it to
4
+ * copy that source. One walk, so the proof and the copy can never disagree about
5
+ * which entries exist, which links are followed, or which entries are refused.
6
+ *
7
+ * Every entry is judged by one special-file policy, in this order:
8
+ *
9
+ * - A name the caller's `filter` excludes is skipped before anything touches it:
10
+ * no `stat`, no `open`, and a directory's subtree is never listed.
11
+ * - A link under `links: 'preserve'` is handed over as a link; its target is never
12
+ * examined.
13
+ * - A link under `links: 'refuse'` refuses the walk, naming it ({@link linkRefused}): the policy
14
+ * of a tree that holds none by construction, so one found there is never followed or copied.
15
+ * - A link under `links: 'follow-contained'` is answered by its target (`stat`, so
16
+ * a dangling link is an absent source). A directory target is entered first, so a
17
+ * link back into the walk is named as the loop it is
18
+ * ({@link DirectoryWalkRevisitedError}); then a target outside the root is refused
19
+ * ({@link CopyLinkEscapesSourceError}).
20
+ * - A named pipe, socket or device (or a link to one) is refused unopened, as the
21
+ * `EFTYPE` errno `refuseSpecialFile` raises.
22
+ * - A regular file is opened without blocking and judged again by `fstat` on that
23
+ * handle, which is the one the visitor reads: a pipe swapped in after the listing
24
+ * is refused there, never waited on.
25
+ *
26
+ * The ROOT is an entry like any other: it is `lstat`-ed, and a root that is a link is handed over
27
+ * (`preserve`) or refused (`refuse`) exactly as a link under it would be. Only `follow-contained`
28
+ * takes a root link for the directory it points at — the root is what containment is judged
29
+ * against, so it cannot be outside itself.
30
+ *
31
+ * Every READ the walk makes (list, `stat`, `open`, `fstat`, `realpath`) that the OS
32
+ * refuses is a classified fault on the caller's `side`, origin `content`, naming the
33
+ * entry. What a visitor WRITES is the visitor's: the walk never classifies it.
34
+ */
35
+ import type { Stats } from 'node:fs';
36
+ import { type FileHandle } from 'node:fs/promises';
37
+ import { type FsSide } from '../errors/fs-fault.js';
38
+ /** How a walk treats a symlink: follow it, contained to the root; keep it as a link; or refuse the tree that holds it. */
39
+ export type LinkPolicy = 'follow-contained' | 'preserve' | 'refuse';
40
+ /** What every walk over a tree is told. */
41
+ export interface TreeWalkOptions {
42
+ /** `follow-contained`: a link is what it points at, inside the root only. `preserve`: a link is a link. `refuse`: a link refuses the walk. */
43
+ readonly links: LinkPolicy;
44
+ /** Keep the entry at this forward-slash path relative to the root; an excluded one is never touched. Omitted: keep everything. */
45
+ readonly filter?: (relative: string) => boolean;
46
+ }
47
+ /** One entry the walk accepted: where it is, and where it is relative to the root (`''` for the root). */
48
+ interface WalkedEntry {
49
+ readonly path: string;
50
+ readonly relative: string;
51
+ }
52
+ /** What the walk hands each accepted entry to. */
53
+ export interface TreeVisitor {
54
+ /** A directory, before any of its entries. */
55
+ directory(entry: WalkedEntry, stats: Stats): Promise<void>;
56
+ /** A regular file, through the handle `fstat` judged; the walk closes it. */
57
+ file(entry: WalkedEntry, handle: FileHandle, stats: Stats): Promise<void>;
58
+ /** A link under `links: 'preserve'`, never followed by the walk: the visitor decides what to read of it. */
59
+ link(entry: WalkedEntry): Promise<void>;
60
+ }
61
+ /**
62
+ * A refusal by the OS while reading the tree, as a fault on `side` (origin
63
+ * `content`) naming `entry` when the OS named no path. A coded refusal and a defect
64
+ * come back as they are. The one classification every read of the tree goes through.
65
+ */
66
+ export declare function treeReadFault(side: FsSide, entry: string, error: unknown): unknown;
67
+ /** Run one read of the tree; a refusal is rethrown by {@link treeReadFault}. */
68
+ export declare function readingTree<T>(side: FsSide, entry: string, read: () => Promise<T>): Promise<T>;
69
+ /**
70
+ * Walk the directory `root` under `options`, handing each accepted entry to
71
+ * `visitor` in listing order, the root first (relative `''`).
72
+ *
73
+ * @param root - The directory to walk; one that is not a directory is refused by its listing, and one
74
+ * that is a link is judged by `options.links` like any link under it
75
+ * @param options - The link policy and the filter
76
+ * @param side - The side every read of the walk is classified on
77
+ * @param visitor - What to do with each entry
78
+ */
79
+ export declare function walkTree(root: string, options: TreeWalkOptions, side: FsSide, visitor: TreeVisitor): Promise<void>;
80
+ export {};
81
+ //# sourceMappingURL=tree-walk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-walk.d.ts","sourceRoot":"","sources":["../../src/tree-change/tree-walk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAU,KAAK,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAW,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAiC,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAUnF,0HAA0H;AAC1H,MAAM,MAAM,UAAU,GAAG,kBAAkB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEpE,2CAA2C;AAC3C,MAAM,WAAW,eAAe;IAC9B,8IAA8I;IAC9I,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,kIAAkI;IAClI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;CACjD;AAED,0GAA0G;AAC1G,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,SAAS,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,6EAA6E;IAC7E,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,4GAA4G;IAC5G,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAElF;AAmBD,gFAAgF;AAChF,wBAAsB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAMpG;AAkID;;;;;;;;;GASG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAExH"}
@@ -0,0 +1,212 @@
1
+ /**
2
+ * The one walk over a tree that is about to be read whole: `proveTreeReadable`
3
+ * runs it to prove a source before anything is written, and `copyTree` runs it to
4
+ * copy that source. One walk, so the proof and the copy can never disagree about
5
+ * which entries exist, which links are followed, or which entries are refused.
6
+ *
7
+ * Every entry is judged by one special-file policy, in this order:
8
+ *
9
+ * - A name the caller's `filter` excludes is skipped before anything touches it:
10
+ * no `stat`, no `open`, and a directory's subtree is never listed.
11
+ * - A link under `links: 'preserve'` is handed over as a link; its target is never
12
+ * examined.
13
+ * - A link under `links: 'refuse'` refuses the walk, naming it ({@link linkRefused}): the policy
14
+ * of a tree that holds none by construction, so one found there is never followed or copied.
15
+ * - A link under `links: 'follow-contained'` is answered by its target (`stat`, so
16
+ * a dangling link is an absent source). A directory target is entered first, so a
17
+ * link back into the walk is named as the loop it is
18
+ * ({@link DirectoryWalkRevisitedError}); then a target outside the root is refused
19
+ * ({@link CopyLinkEscapesSourceError}).
20
+ * - A named pipe, socket or device (or a link to one) is refused unopened, as the
21
+ * `EFTYPE` errno `refuseSpecialFile` raises.
22
+ * - A regular file is opened without blocking and judged again by `fstat` on that
23
+ * handle, which is the one the visitor reads: a pipe swapped in after the listing
24
+ * is refused there, never waited on.
25
+ *
26
+ * The ROOT is an entry like any other: it is `lstat`-ed, and a root that is a link is handed over
27
+ * (`preserve`) or refused (`refuse`) exactly as a link under it would be. Only `follow-contained`
28
+ * takes a root link for the directory it points at — the root is what containment is judged
29
+ * against, so it cannot be outside itself.
30
+ *
31
+ * Every READ the walk makes (list, `stat`, `open`, `fstat`, `realpath`) that the OS
32
+ * refuses is a classified fault on the caller's `side`, origin `content`, naming the
33
+ * entry. What a visitor WRITES is the visitor's: the walk never classifies it.
34
+ */
35
+ import fs from 'node:fs/promises';
36
+ import { classifyFsFault, FsFaultError } from '../errors/fs-fault.js';
37
+ import { forEachInOrder } from '../in-order.js';
38
+ import { requireFollowedStat } from '../link-following.js';
39
+ import { isUnderRoot } from '../path-containment.js';
40
+ import { safePath } from '../path-core.js';
41
+ import { refuseSpecialFile } from '../special-file.js';
42
+ import { openForReading } from '../text-file.js';
43
+ import { CopyLinkEscapesSourceError, FollowedWalk } from './followed-walk.js';
44
+ /**
45
+ * A refusal by the OS while reading the tree, as a fault on `side` (origin
46
+ * `content`) naming `entry` when the OS named no path. A coded refusal and a defect
47
+ * come back as they are. The one classification every read of the tree goes through.
48
+ */
49
+ export function treeReadFault(side, entry, error) {
50
+ return classifyFsFault(error, { side, origin: 'content', action: `read ${entry}`, path: entry });
51
+ }
52
+ /**
53
+ * The refusal of a link in a tree walked with `links: 'refuse'`: a `wrong-type` fault on `side`
54
+ * (origin `content`) naming the link, under the errno a special file is refused with — an entry
55
+ * of a kind the read does not take — so the one refusal table decides what the caller publishes.
56
+ */
57
+ function linkRefused(side, link) {
58
+ return new FsFaultError({
59
+ side,
60
+ faultClass: 'wrong-type',
61
+ errno: 'EFTYPE',
62
+ path: link,
63
+ origin: 'content',
64
+ action: `read ${link}: it is a symbolic link, and this tree may hold none`,
65
+ cause: undefined,
66
+ });
67
+ }
68
+ /** Run one read of the tree; a refusal is rethrown by {@link treeReadFault}. */
69
+ export async function readingTree(side, entry, read) {
70
+ try {
71
+ return await read();
72
+ }
73
+ catch (error) {
74
+ throw treeReadFault(side, entry, error);
75
+ }
76
+ }
77
+ /** {@link readingTree}, synchronously: the walk guard and the containment check resolve real paths. */
78
+ function readingTreeSync(side, entry, read) {
79
+ try {
80
+ return read();
81
+ }
82
+ catch (error) {
83
+ throw treeReadFault(side, entry, error);
84
+ }
85
+ }
86
+ /**
87
+ * Open `path` without blocking and judge it by `fstat` on that handle; hand the
88
+ * handle to `use` and close it after. A special file is refused (`EFTYPE`) and its
89
+ * handle closed before `use` runs. When `use` fails, ITS error is the one reported:
90
+ * the handle is still released, but a close that also fails must not replace a
91
+ * write the visitor failed (a source fault hiding a destination one).
92
+ */
93
+ async function withRegularFile(side, path, use) {
94
+ const handle = await readingTree(side, path, () => openForReading(path));
95
+ try {
96
+ const stats = await readingTree(side, path, () => handle.stat());
97
+ await use(handle, stats);
98
+ }
99
+ catch (error) {
100
+ await Promise.allSettled([handle.close()]);
101
+ throw error;
102
+ }
103
+ // Closing the source's handle is a read of the source: a refused close is the source's fault too.
104
+ await readingTree(side, path, () => handle.close());
105
+ }
106
+ /** One walk: its root, its policy, the guard a following walk holds, and the visitor. */
107
+ class TreeWalk {
108
+ #root;
109
+ #options;
110
+ #side;
111
+ #visitor;
112
+ #guard;
113
+ constructor(root, options, side, visitor) {
114
+ this.#root = root;
115
+ this.#options = options;
116
+ this.#side = side;
117
+ this.#visitor = visitor;
118
+ this.#guard = options.links === 'follow-contained' ? new FollowedWalk(side, root) : undefined;
119
+ }
120
+ /**
121
+ * Walk from the root: judged by `lstat`, as every entry under it is by its listing. A root that is
122
+ * a link is the policy's to decide — except under `follow-contained`, where the root is the
123
+ * directory it points at.
124
+ */
125
+ async root(entry) {
126
+ if (this.#options.links !== 'follow-contained') {
127
+ const stats = await readingTree(this.#side, entry.path, () => fs.lstat(entry.path));
128
+ if (stats.isSymbolicLink()) {
129
+ await this.#link(entry);
130
+ return;
131
+ }
132
+ }
133
+ await this.directory(entry);
134
+ }
135
+ /** Enter the directory `entry` and visit it and everything under it, in listing order. */
136
+ async directory(entry) {
137
+ // Listed first: a root that is not a directory is refused by the listing (`ENOTDIR`), never opened.
138
+ const listing = await this.#list(entry.path);
139
+ const stats = await readingTree(this.#side, entry.path, () => requireFollowedStat(entry.path, this.#root));
140
+ this.#enter(entry.path);
141
+ await this.#visitDirectory(entry, listing, stats);
142
+ }
143
+ #list(dir) {
144
+ return readingTree(this.#side, dir, () => fs.readdir(dir, { withFileTypes: true }));
145
+ }
146
+ /** Visit an entered directory, then its entries in order: the guard must see each directory entered before the walk recurses, and the first refusal names the first offending entry in listing order. */
147
+ async #visitDirectory(entry, listing, stats) {
148
+ await this.#visitor.directory(entry, stats);
149
+ await forEachInOrder(listing, (dirent) => this.#entry(entry, dirent));
150
+ }
151
+ async #entry(parent, dirent) {
152
+ const entry = {
153
+ path: safePath.join(parent.path, dirent.name),
154
+ relative: parent.relative === '' ? dirent.name : `${parent.relative}/${dirent.name}`,
155
+ };
156
+ if (this.#options.filter !== undefined && !this.#options.filter(entry.relative))
157
+ return;
158
+ if (dirent.isSymbolicLink()) {
159
+ await this.#link(entry);
160
+ return;
161
+ }
162
+ if (dirent.isDirectory()) {
163
+ await this.directory(entry);
164
+ return;
165
+ }
166
+ await this.#nonDirectory(entry, dirent);
167
+ }
168
+ async #link(entry) {
169
+ if (this.#options.links === 'preserve') {
170
+ await this.#visitor.link(entry);
171
+ return;
172
+ }
173
+ if (this.#options.links === 'refuse')
174
+ throw linkRefused(this.#side, entry.path);
175
+ const target = await readingTree(this.#side, entry.path, () => requireFollowedStat(entry.path, this.#root));
176
+ // Revisit first, so a link back into the tree is named as the loop it is; then
177
+ // containment, so a link out is named as the escape it is.
178
+ if (target.isDirectory())
179
+ this.#enter(entry.path);
180
+ const contained = readingTreeSync(this.#side, entry.path, () => isUnderRoot(this.#root, entry.path));
181
+ if (contained !== 'inside')
182
+ throw new CopyLinkEscapesSourceError(entry.path, this.#root);
183
+ if (target.isDirectory()) {
184
+ await this.#visitDirectory(entry, await this.#list(entry.path), target);
185
+ return;
186
+ }
187
+ await this.#nonDirectory(entry, target);
188
+ }
189
+ /** A file by its listing or its link's target: a special one is refused unopened, a regular one opened. */
190
+ async #nonDirectory(entry, kind) {
191
+ readingTreeSync(this.#side, entry.path, () => refuseSpecialFile(kind, entry.path));
192
+ await withRegularFile(this.#side, entry.path, (handle, stats) => this.#visitor.file(entry, handle, stats));
193
+ }
194
+ #enter(dir) {
195
+ const guard = this.#guard;
196
+ guard?.enter(dir);
197
+ }
198
+ }
199
+ /**
200
+ * Walk the directory `root` under `options`, handing each accepted entry to
201
+ * `visitor` in listing order, the root first (relative `''`).
202
+ *
203
+ * @param root - The directory to walk; one that is not a directory is refused by its listing, and one
204
+ * that is a link is judged by `options.links` like any link under it
205
+ * @param options - The link policy and the filter
206
+ * @param side - The side every read of the walk is classified on
207
+ * @param visitor - What to do with each entry
208
+ */
209
+ export async function walkTree(root, options, side, visitor) {
210
+ await new TreeWalk(root, options, side, visitor).root({ path: root, relative: '' });
211
+ }
212
+ //# sourceMappingURL=tree-walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-walk.js","sourceRoot":"","sources":["../../src/tree-change/tree-walk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The win32 namespace prefix Node may report a path with. A leaf that imports NOTHING, so the
3
+ * errno table — itself a leaf, for the reason its header gives — can read every errno's path
4
+ * through it, once.
5
+ *
6
+ * Module-internal to `utils`: no barrel and no subpath re-exports it; its two callers are the
7
+ * errno table and the tree-change apply.
8
+ */
9
+ /**
10
+ * A path without the win32 namespace prefix Node may report it with. Under win32 Node hands the OS
11
+ * a namespaced path (`\\?\C:\…`, `\\?\UNC\server\share\…`) and reports some paths back in
12
+ * that form — the first directory a recursive `mkdir` made, an errno's `path` and `dest`. Held
13
+ * against a plain `C:\…` path such a report reads as another root, and displayed it names
14
+ * `//?/C:/…`. Pure and the same on every host; every other path is returned as it is.
15
+ *
16
+ * @param reported - A native path, as Node reported it
17
+ * @returns The path in the spelling the caller's own paths have (native separators kept)
18
+ *
19
+ * @example
20
+ * withoutWin32Namespace('\\\\?\\C:\\a') // 'C:\\a'
21
+ * withoutWin32Namespace('\\\\?\\UNC\\host\\share') // '\\\\host\\share'
22
+ */
23
+ export declare function withoutWin32Namespace(reported: string): string;
24
+ //# sourceMappingURL=win32-namespace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"win32-namespace.d.ts","sourceRoot":"","sources":["../src/win32-namespace.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI9D"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The win32 namespace prefix Node may report a path with. A leaf that imports NOTHING, so the
3
+ * errno table — itself a leaf, for the reason its header gives — can read every errno's path
4
+ * through it, once.
5
+ *
6
+ * Module-internal to `utils`: no barrel and no subpath re-exports it; its two callers are the
7
+ * errno table and the tree-change apply.
8
+ */
9
+ const WIN32_NAMESPACE = String.raw `\\?` + '\\';
10
+ const WIN32_UNC_NAMESPACE = `${WIN32_NAMESPACE}UNC\\`;
11
+ /**
12
+ * A path without the win32 namespace prefix Node may report it with. Under win32 Node hands the OS
13
+ * a namespaced path (`\\?\C:\…`, `\\?\UNC\server\share\…`) and reports some paths back in
14
+ * that form — the first directory a recursive `mkdir` made, an errno's `path` and `dest`. Held
15
+ * against a plain `C:\…` path such a report reads as another root, and displayed it names
16
+ * `//?/C:/…`. Pure and the same on every host; every other path is returned as it is.
17
+ *
18
+ * @param reported - A native path, as Node reported it
19
+ * @returns The path in the spelling the caller's own paths have (native separators kept)
20
+ *
21
+ * @example
22
+ * withoutWin32Namespace('\\\\?\\C:\\a') // 'C:\\a'
23
+ * withoutWin32Namespace('\\\\?\\UNC\\host\\share') // '\\\\host\\share'
24
+ */
25
+ export function withoutWin32Namespace(reported) {
26
+ // Matched on the NATIVE spelling, before any separator conversion: the prefix exists only there.
27
+ if (reported.startsWith(WIN32_UNC_NAMESPACE))
28
+ return `\\\\${reported.slice(WIN32_UNC_NAMESPACE.length)}`;
29
+ return reported.startsWith(WIN32_NAMESPACE) ? reported.slice(WIN32_NAMESPACE.length) : reported;
30
+ }
31
+ //# sourceMappingURL=win32-namespace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"win32-namespace.js","sourceRoot":"","sources":["../src/win32-namespace.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAA,KAAK,GAAG,IAAI,CAAC;AAC/C,MAAM,mBAAmB,GAAG,GAAG,eAAe,OAAO,CAAC;AAEtD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,iGAAiG;IACjG,IAAI,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC;QAAE,OAAO,OAAO,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC;IACzG,OAAO,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClG,CAAC"}
@@ -22,6 +22,14 @@
22
22
  *
23
23
  * No filesystem access — these are pure string transforms.
24
24
  */
25
+ /**
26
+ * The code {@link updateYamlIn} throws when the INPUT document cannot take the
27
+ * edit — it is not YAML, or the path lands on a collection or runs through a
28
+ * scalar. The input's shape, not a defect: a caller editing an adopter's file
29
+ * reports it as that file's problem. Its other throws (an empty path, a failed
30
+ * post-condition) stay uncoded — they are the caller's or this module's bug.
31
+ */
32
+ export declare const YAML_EDIT_INPUT_REFUSED_CODE = "YAML_EDIT_INPUT_REFUSED";
25
33
  /** A path into a YAML document: map keys (strings) and/or sequence indices. */
26
34
  export type YamlPath = (string | number)[];
27
35
  /** A scalar value this module knows how to serialize as a single YAML token. */
@@ -42,9 +50,10 @@ export type YamlScalarValue = string | number | boolean | null;
42
50
  * @param path - Key/index path to the scalar to set.
43
51
  * @param value - The scalar value to write (string, number, boolean, or null).
44
52
  * @returns The updated document text.
45
- * @throws If `text` is not valid YAML, if `path` is empty, or if `path` resolves
46
- * to a collection that would be clobbered by a scalar (or an intermediate
47
- * ancestor is a scalar that cannot hold a child).
53
+ * @throws A `VatError` coded {@link YAML_EDIT_INPUT_REFUSED_CODE} if `text` is
54
+ * not valid YAML, or `path` resolves to a collection that would be clobbered
55
+ * by a scalar (or an intermediate ancestor is a scalar that cannot hold a
56
+ * child); a plain `Error` if `path` is empty.
48
57
  *
49
58
  * @example
50
59
  * updateYamlIn('model: haiku # note\n', ['model'], 'opus')
@@ -1 +1 @@
1
- {"version":3,"file":"surgical-yaml.d.ts","sourceRoot":"","sources":["../../src/yaml/surgical-yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAcH,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;AAE3C,gFAAgF;AAChF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAK/D;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CA2BzF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,QAAQ,EAAE,GACvB,IAAI,CAYN"}
1
+ {"version":3,"file":"surgical-yaml.d.ts","sourceRoot":"","sources":["../../src/yaml/surgical-yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAgBH;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,4BAA4B,CAAC;AAEtE,+EAA+E;AAC/E,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;AAE3C,gFAAgF;AAChF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAK/D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CA4BzF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,QAAQ,EAAE,GACvB,IAAI,CAYN"}
@@ -23,6 +23,15 @@
23
23
  * No filesystem access — these are pure string transforms.
24
24
  */
25
25
  import { Document, isCollection, isMap, isScalar, parseDocument, visit, } from 'yaml';
26
+ import { VatError } from '../errors/vat-error.js';
27
+ /**
28
+ * The code {@link updateYamlIn} throws when the INPUT document cannot take the
29
+ * edit — it is not YAML, or the path lands on a collection or runs through a
30
+ * scalar. The input's shape, not a defect: a caller editing an adopter's file
31
+ * reports it as that file's problem. Its other throws (an empty path, a failed
32
+ * post-condition) stay uncoded — they are the caller's or this module's bug.
33
+ */
34
+ export const YAML_EDIT_INPUT_REFUSED_CODE = 'YAML_EDIT_INPUT_REFUSED';
26
35
  /** yaml's `toString` options — `lineWidth: 0` disables line-wrapping/folding. */
27
36
  const NO_WRAP = { lineWidth: 0 };
28
37
  /**
@@ -41,9 +50,10 @@ const NO_WRAP = { lineWidth: 0 };
41
50
  * @param path - Key/index path to the scalar to set.
42
51
  * @param value - The scalar value to write (string, number, boolean, or null).
43
52
  * @returns The updated document text.
44
- * @throws If `text` is not valid YAML, if `path` is empty, or if `path` resolves
45
- * to a collection that would be clobbered by a scalar (or an intermediate
46
- * ancestor is a scalar that cannot hold a child).
53
+ * @throws A `VatError` coded {@link YAML_EDIT_INPUT_REFUSED_CODE} if `text` is
54
+ * not valid YAML, or `path` resolves to a collection that would be clobbered
55
+ * by a scalar (or an intermediate ancestor is a scalar that cannot hold a
56
+ * child); a plain `Error` if `path` is empty.
47
57
  *
48
58
  * @example
49
59
  * updateYamlIn('model: haiku # note\n', ['model'], 'opus')
@@ -56,7 +66,7 @@ export function updateYamlIn(text, path, value) {
56
66
  const eol = detectEol(text);
57
67
  const doc = parseDocument(text, { prettyErrors: true });
58
68
  if (doc.errors.length > 0) {
59
- throw new Error(`updateYamlIn: input is not valid YAML: ${doc.errors[0]?.message ?? 'unknown'}`);
69
+ throw new VatError(YAML_EDIT_INPUT_REFUSED_CODE, `updateYamlIn: input is not valid YAML: ${doc.errors[0]?.message ?? 'unknown'}`);
60
70
  }
61
71
  const existing = doc.getIn(path, true);
62
72
  let result;
@@ -64,7 +74,7 @@ export function updateYamlIn(text, path, value) {
64
74
  result = replaceScalarToken(text, existing.range, value, eol);
65
75
  }
66
76
  else if (isCollection(existing)) {
67
- throw new Error(`updateYamlIn: refusing to overwrite the collection at [${path.join(', ')}] with a scalar`);
77
+ throw new VatError(YAML_EDIT_INPUT_REFUSED_CODE, `updateYamlIn: refusing to overwrite the collection at [${path.join(', ')}] with a scalar`);
68
78
  }
69
79
  else {
70
80
  result = insertNewKey(text, doc, path, value, eol);
@@ -142,7 +152,7 @@ function findInsertionTarget(doc, path) {
142
152
  if (isMap(node)) {
143
153
  return { map: node, remaining: path.slice(i) };
144
154
  }
145
- throw new Error(`updateYamlIn: cannot insert at [${path.join(', ')}] — ancestor [${prefix.join(', ')}] is not a map`);
155
+ throw new VatError(YAML_EDIT_INPUT_REFUSED_CODE, `updateYamlIn: cannot insert at [${path.join(', ')}] — ancestor [${prefix.join(', ')}] is not a map`);
146
156
  }
147
157
  return { map: null, remaining: path };
148
158
  }
@@ -1 +1 @@
1
- {"version":3,"file":"surgical-yaml.js","sourceRoot":"","sources":["../../src/yaml/surgical-yaml.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"surgical-yaml.js","sourceRoot":"","sources":["../../src/yaml/surgical-yaml.ts"],"names":[],"mappings":"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"}
package/eslint/README.md CHANGED
@@ -64,7 +64,7 @@ Taken to its limit, a **bare filename with no `/` exempts that filename everywhe
64
64
 
65
65
  The option **replaces** any default rather than merging with it, and unknown option keys are a config error — a typo'd `exemptFile` must fail loudly rather than quietly exempt nothing.
66
66
 
67
- The rules taking `exemptFiles` are `no-raw-node-path`, `no-os-tmpdir`, `no-fs-mkdirSync`, `no-fs-realpathSync`, `no-child-process-execSync`, `no-fs-promises-cp`, `no-raw-text-decode` and `no-bare-symlink-in-tests`.
67
+ The rules taking `exemptFiles` are `no-raw-node-path`, `no-os-tmpdir`, `no-fs-mkdirSync`, `no-fs-realpathSync`, `no-child-process-execSync`, `no-raw-text-decode`, `no-bare-symlink-in-tests`, `no-adhoc-errno` and `no-destructive-fs` (the last takes directory entries too: a trailing `/` makes an entry a directory).
68
68
 
69
69
  ## Rules
70
70
 
@@ -73,7 +73,7 @@ The table is **generated** from each rule's `meta.docs` by `bun run generate:cla
73
73
  **The auto-fix writes the import to the subpath in that column**, not to the barrel — `--fix` on a raw `path.join()` inserts `import { safePath } from '@vibe-agent-toolkit/utils/path'`. A file that already reaches the helper through the barrel keeps its existing import and only has the call rewritten: adding a second binding of the same name is a `SyntaxError`, not a redundant import.
74
74
 
75
75
  <!-- gen:eslint-rules -->
76
- 35 rules; 7 auto-fix. `configs.recommended` enables 18 of them (16 at `error`, 2 at `warn`); `—` in the last column means the rule ships but must be enabled by name.
76
+ 41 rules; 6 auto-fix. `configs.recommended` enables 17 of them (15 at `error`, 2 at `warn`); `—` in the last column means the rule ships but must be enabled by name.
77
77
 
78
78
  #### Path handling
79
79
 
@@ -91,13 +91,17 @@ The table is **generated** from each rule's `meta.docs` by `bun run generate:cla
91
91
 
92
92
  | Rule | Bans | Use instead | Subpath | Fix | `recommended` |
93
93
  |---|---|---|---|---|---|
94
+ | `no-adhoc-errno` | an errno name (`ENOENT`, `EACCES`, …) as a string in a classifying position, and a catch that reads `e.code` then builds a refusal with `cause: e` | `fsFaultOf(e)` / `classifyFsFault(e, …)`, or a single-errno predicate such as `isPathAbsentError(e)` | — | | — |
94
95
  | `no-bare-executable-spawn` | Disallow spawning 'git' or 'node' by bare name — resolve the executable once (process.execPath; NODE_EXECUTABLE / gitExecutable() in tests) and spawn the absolute path | — | — | | `error` |
95
96
  | `no-bare-symlink-in-tests` | unguarded `fs.symlinkSync()` / `fs.promises.symlink()` | in tests: `createSymlink(cap, …)` / `createSymlinkAsync(cap, …)`; in shipped code: a win32 junction, or a `catch` naming the privilege | `/testing` | | — |
96
97
  | `no-child-process-execSync` | `child_process.execSync()` | `safeExecSync()` | `/process` | ✓ | `error` |
98
+ | `no-destructive-fs` | recursive `rm`/`rmSync`, `rmdir`, `rename`, `cp` and `copyFile` from `node:fs` / `node:fs/promises` (and their `Sync` forms), called or passed as values | `planTreeChanges()` / `applyTreePlan()`, `renameFileAtomic()`, `replaceFile()`, `copyTree()`, `withTempDir()` / `disposeTempDir()` | — | | — |
99
+ | `no-existssync` | `existsSync()` from `node:fs` — called, handed on, destructured or re-exported — under `packages/*/src/` | `pathPresent(path, mode, sideOf, absence)` (absent only on an absence; every other errno a classified `FS_FAULT`) | — | | — |
97
100
  | `no-fs-mkdirSync` | `fs.mkdirSync()` | `mkdirSyncReal()` | `/fs` | ✓ | `error` |
98
- | `no-fs-promises-cp` | `cp()` from `node:fs/promises` (drops nested files on Node 22) | `cpSync()` from `node:fs` | — | ✓ | `error` |
99
101
  | `no-fs-realpathSync` | `fs.realpathSync()` | `normalizePath()` | `/fs` | ✓ | `error` |
102
+ | `no-link-following-fs` | `stat`/`statSync`/`existsSync`/`realpath`/`realpathSync`, and `symlink`/`symlinkSync` called with no type, from `node:fs` or `node:fs/promises` under `packages/*/src/` | `followedStatSync`/`followedKindSync`/`realpathNativeSync(path, within)` or `pathPresent(path, { follow: within }, …)` | — | | — |
100
103
  | `no-os-tmpdir` | `os.tmpdir()` (8.3 short names on Windows) | `normalizedTmpdir()` | `/fs` | ✓ | `error` |
104
+ | `no-raw-signal-listener` | `process.on(<signal>, …)`, `process.off(<signal>, …)`, `once(process, <signal>)` and `process.on(<non-literal>, …)` | `handleTerminatingSignals()` | `/process` | | — |
101
105
  | `no-unix-shell-commands` | `tar`, `grep`, `rm`, `echo`, … spawned directly | Node APIs, or a portable script fixture | — | | `error` |
102
106
 
103
107
  #### URLs and dynamic imports
@@ -142,6 +146,7 @@ The table is **generated** from each rule's `meta.docs` by `bun run generate:cla
142
146
 
143
147
  | Rule | Bans | Use instead | Subpath | Fix | `recommended` |
144
148
  |---|---|---|---|---|---|
149
+ | `no-literal-test-timeout` | `it(name, fn, 60_000)`, `beforeAll(fn, tier * 12)`, `{ timeout: isWin ? 900_000 : 60_000 }` | the tier default, or `atLeastTierTimeout(inject('tierTestTimeout'), budget)` | — | | — |
145
150
  | `no-test-scoped-functions` | helper functions declared inside `describe`/`it` | module scope | — | | — |
146
151
  | `prefer-startswith-over-regex` | `/^foo/.test(s)`, `` /^\*glob/.test(s) ``, `const RE = /^foo/; RE.test(s)` | `s.startsWith('foo')` | — | | `error` |
147
152
  | `require-justified-skip` | unannotated `it.skip`/`it.todo`, tautological assertions, empty test bodies | a `SKIP(#123): reason` annotation, or a real assertion | — | | — |
@@ -158,6 +163,7 @@ The table is **generated** from each rule's `meta.docs` by `bun run generate:cla
158
163
  | `no-io-in-unit-tier` | Disallow child_process imports and mkdtemp/spawn/exec calls in unit-tier test files — a test that spawns or writes to disk belongs in the integration or system tier | — | — | | — |
159
164
  | `no-literal-process-exit` | Disallow process.exit(<number>) and process.exitCode = <number> — name the meaning with the ExitCode enum so every command shares one exit contract | — | — | | — |
160
165
  | `no-registry-count-pin` | Disallow pinning the size of an imported registry with a literal in tests — toHaveLength(27) on something pulled from src is a change detector fixed by retyping | — | — | | — |
166
+ | `no-stdout-outside-writer` | Disallow writing stdout under a command directory except through the one document writer — process.stdout.write, console.log and the stdout helpers publish a shape nothing validates | — | — | | — |
161
167
  | `no-version-literal` | Disallow z.literal(<number>) on a version-named field and <X>_VERSION = <number> constants — a hand-bumped integer deciding data validity is the shape CLAUDE.md bans | — | — | | — |
162
168
  <!-- /gen:eslint-rules -->
163
169
 
@@ -216,7 +222,7 @@ Not in `recommended` because the first half depends on **your** Node floor — a
216
222
 
217
223
  `try { return statSync(p); } catch { return null; }` answers three different questions with one word. *Not there* is what the author meant. *Refused* — `EACCES`, `EPERM`, `ELOOP` — is a file that exists and could not be read, now reported as absent. *Bug* — a `TypeError` two frames down — is a defect, now reported as a file that is not there. All three exit 0, and the tool is quietest exactly where it is most wrong.
218
224
 
219
- The rule is a floor, deliberately syntactic: a catch is fine if it **references its error binding anywhere** in the body (`isFilesystemAccessError(e)`, `e instanceof X`, `e.code === 'ENOENT'`, `errors.push(String(e))`, `log.warn(e)`) or **throws at its own level** (a rethrow, or a translation into a louder error; a `throw` inside a nested function is a promise to fail later, not a rethrow). It cannot tell `narrow(e)` from `log(e)` and does not try. What it guarantees is the weaker, enforceable property — *the error was looked at before it was discarded* — which every one of the shipped defects lacked.
225
+ The rule is a floor, deliberately syntactic: a catch is fine if it **references its error binding anywhere** in the body (`fsFaultOf(e)`, `e instanceof X`, `e.code === 'ENOENT'`, `errors.push(String(e))`, `log.warn(e)`) or **throws at its own level** (a rethrow, or a translation into a louder error; a `throw` inside a nested function is a promise to fail later, not a rethrow). It cannot tell `narrow(e)` from `log(e)` and does not try. What it guarantees is the weaker, enforceable property — *the error was looked at before it was discarded* — which every one of the shipped defects lacked.
220
226
 
221
227
  This is the one seam `tsc` cannot see. When a callee learns to throw where it used to return — a crawler that starts refusing an unreadable directory instead of skipping it — every caller whose contract changed by TYPE fails to compile and gets fixed; the caller with a blind `catch` compiles unchanged and absorbs the new refusal. That is how a refuse-by-default crawler shipped under a `catch { return null }` that turned `vat audit` into a scan of nothing.
222
228
 
@@ -277,6 +283,8 @@ Every rule marked `—` in the table ships without riding in `recommended`, and
277
283
 
278
284
  **Test-style opinions** — `no-test-scoped-functions` (where a helper may be declared) and `require-justified-skip` (the annotation grammar for a disabled test). Neither is a portability or correctness fact, and installing this package for `safePath.join()` should not also import someone else's test conventions. Both are worth turning on deliberately.
279
285
 
286
+ **Names a value only your runner config can provide** — `no-literal-test-timeout`. Its remedy is a multiple of the tier timeout your vitest config hands its tests (`provide`/`inject`); this pack cannot supply that value, so the rule cannot ride in `recommended`.
287
+
280
288
  **Unsound, pending a rewrite** — `no-unsafe-root-join`. It keys on whether an identifier's *name* ends in `root` rather than on whether any segment is caller-controlled, which makes it noisy and blind at the same time. Measured against 4,670 files of real adopter source: 108 findings, none autofixable. Verified behaviour:
281
289
 
282
290
  ```js