@openclaw/openshell-sandbox 2026.9.2 → 2026.9.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 (710) hide show
  1. package/dist/index.js +87 -47
  2. package/node_modules/@openclaw/fs-safe/CHANGELOG.md +700 -0
  3. package/node_modules/@openclaw/fs-safe/LICENSE +21 -0
  4. package/node_modules/@openclaw/fs-safe/README.md +564 -0
  5. package/node_modules/@openclaw/fs-safe/SECURITY.md +45 -0
  6. package/node_modules/@openclaw/fs-safe/dist/absolute-path.d.ts +33 -0
  7. package/node_modules/@openclaw/fs-safe/dist/absolute-path.d.ts.map +1 -0
  8. package/node_modules/@openclaw/fs-safe/dist/absolute-path.js +307 -0
  9. package/node_modules/@openclaw/fs-safe/dist/advanced.d.ts +26 -0
  10. package/node_modules/@openclaw/fs-safe/dist/advanced.d.ts.map +1 -0
  11. package/node_modules/@openclaw/fs-safe/dist/advanced.js +28 -0
  12. package/node_modules/@openclaw/fs-safe/dist/archive-crc32.d.ts +2 -0
  13. package/node_modules/@openclaw/fs-safe/dist/archive-crc32.d.ts.map +1 -0
  14. package/node_modules/@openclaw/fs-safe/dist/archive-crc32.js +14 -0
  15. package/node_modules/@openclaw/fs-safe/dist/archive-deadline.d.ts +12 -0
  16. package/node_modules/@openclaw/fs-safe/dist/archive-deadline.d.ts.map +1 -0
  17. package/node_modules/@openclaw/fs-safe/dist/archive-deadline.js +103 -0
  18. package/node_modules/@openclaw/fs-safe/dist/archive-entry.d.ts +14 -0
  19. package/node_modules/@openclaw/fs-safe/dist/archive-entry.d.ts.map +1 -0
  20. package/node_modules/@openclaw/fs-safe/dist/archive-entry.js +85 -0
  21. package/node_modules/@openclaw/fs-safe/dist/archive-errors.d.ts +13 -0
  22. package/node_modules/@openclaw/fs-safe/dist/archive-errors.d.ts.map +1 -0
  23. package/node_modules/@openclaw/fs-safe/dist/archive-errors.js +23 -0
  24. package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.d.ts +18 -0
  25. package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.d.ts.map +1 -0
  26. package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.js +74 -0
  27. package/node_modules/@openclaw/fs-safe/dist/archive-input.d.ts +19 -0
  28. package/node_modules/@openclaw/fs-safe/dist/archive-input.d.ts.map +1 -0
  29. package/node_modules/@openclaw/fs-safe/dist/archive-input.js +92 -0
  30. package/node_modules/@openclaw/fs-safe/dist/archive-kind.d.ts +9 -0
  31. package/node_modules/@openclaw/fs-safe/dist/archive-kind.d.ts.map +1 -0
  32. package/node_modules/@openclaw/fs-safe/dist/archive-kind.js +82 -0
  33. package/node_modules/@openclaw/fs-safe/dist/archive-limits.d.ts +57 -0
  34. package/node_modules/@openclaw/fs-safe/dist/archive-limits.d.ts.map +1 -0
  35. package/node_modules/@openclaw/fs-safe/dist/archive-limits.js +131 -0
  36. package/node_modules/@openclaw/fs-safe/dist/archive-merge.d.ts +18 -0
  37. package/node_modules/@openclaw/fs-safe/dist/archive-merge.d.ts.map +1 -0
  38. package/node_modules/@openclaw/fs-safe/dist/archive-merge.js +157 -0
  39. package/node_modules/@openclaw/fs-safe/dist/archive-native.d.ts +20 -0
  40. package/node_modules/@openclaw/fs-safe/dist/archive-native.d.ts.map +1 -0
  41. package/node_modules/@openclaw/fs-safe/dist/archive-native.js +107 -0
  42. package/node_modules/@openclaw/fs-safe/dist/archive-options.d.ts +21 -0
  43. package/node_modules/@openclaw/fs-safe/dist/archive-options.d.ts.map +1 -0
  44. package/node_modules/@openclaw/fs-safe/dist/archive-options.js +1 -0
  45. package/node_modules/@openclaw/fs-safe/dist/archive-parser-errors.d.ts +2 -0
  46. package/node_modules/@openclaw/fs-safe/dist/archive-parser-errors.d.ts.map +1 -0
  47. package/node_modules/@openclaw/fs-safe/dist/archive-parser-errors.js +12 -0
  48. package/node_modules/@openclaw/fs-safe/dist/archive-parser.wasm +0 -0
  49. package/node_modules/@openclaw/fs-safe/dist/archive-plan.d.ts +20 -0
  50. package/node_modules/@openclaw/fs-safe/dist/archive-plan.d.ts.map +1 -0
  51. package/node_modules/@openclaw/fs-safe/dist/archive-plan.js +55 -0
  52. package/node_modules/@openclaw/fs-safe/dist/archive-policy.d.ts +22 -0
  53. package/node_modules/@openclaw/fs-safe/dist/archive-policy.d.ts.map +1 -0
  54. package/node_modules/@openclaw/fs-safe/dist/archive-policy.js +38 -0
  55. package/node_modules/@openclaw/fs-safe/dist/archive-read.d.ts +6 -0
  56. package/node_modules/@openclaw/fs-safe/dist/archive-read.d.ts.map +1 -0
  57. package/node_modules/@openclaw/fs-safe/dist/archive-read.js +225 -0
  58. package/node_modules/@openclaw/fs-safe/dist/archive-staging.d.ts +31 -0
  59. package/node_modules/@openclaw/fs-safe/dist/archive-staging.d.ts.map +1 -0
  60. package/node_modules/@openclaw/fs-safe/dist/archive-staging.js +250 -0
  61. package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.d.ts +7 -0
  62. package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.d.ts.map +1 -0
  63. package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.js +59 -0
  64. package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.d.ts +18 -0
  65. package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.d.ts.map +1 -0
  66. package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.js +95 -0
  67. package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.d.ts +18 -0
  68. package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.d.ts.map +1 -0
  69. package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.js +99 -0
  70. package/node_modules/@openclaw/fs-safe/dist/archive-tar.d.ts +19 -0
  71. package/node_modules/@openclaw/fs-safe/dist/archive-tar.d.ts.map +1 -0
  72. package/node_modules/@openclaw/fs-safe/dist/archive-tar.js +21 -0
  73. package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.d.ts +8 -0
  74. package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.d.ts.map +1 -0
  75. package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.js +60 -0
  76. package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.d.ts +2 -0
  77. package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.d.ts.map +1 -0
  78. package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.js +140 -0
  79. package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.d.ts +15 -0
  80. package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.d.ts.map +1 -0
  81. package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.js +228 -0
  82. package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.d.ts +21 -0
  83. package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.d.ts.map +1 -0
  84. package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.js +27 -0
  85. package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.d.ts +5 -0
  86. package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.d.ts.map +1 -0
  87. package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.js +41 -0
  88. package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.d.ts +12 -0
  89. package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.d.ts.map +1 -0
  90. package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.js +100 -0
  91. package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.d.ts +7 -0
  92. package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.d.ts.map +1 -0
  93. package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.js +44 -0
  94. package/node_modules/@openclaw/fs-safe/dist/archive.d.ts +15 -0
  95. package/node_modules/@openclaw/fs-safe/dist/archive.d.ts.map +1 -0
  96. package/node_modules/@openclaw/fs-safe/dist/archive.js +275 -0
  97. package/node_modules/@openclaw/fs-safe/dist/async-lock.d.ts +2 -0
  98. package/node_modules/@openclaw/fs-safe/dist/async-lock.d.ts.map +1 -0
  99. package/node_modules/@openclaw/fs-safe/dist/async-lock.js +17 -0
  100. package/node_modules/@openclaw/fs-safe/dist/atomic.d.ts +5 -0
  101. package/node_modules/@openclaw/fs-safe/dist/atomic.d.ts.map +1 -0
  102. package/node_modules/@openclaw/fs-safe/dist/atomic.js +4 -0
  103. package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.d.ts +4 -0
  104. package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.d.ts.map +1 -0
  105. package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.js +21 -0
  106. package/node_modules/@openclaw/fs-safe/dist/bounded-read.d.ts +14 -0
  107. package/node_modules/@openclaw/fs-safe/dist/bounded-read.d.ts.map +1 -0
  108. package/node_modules/@openclaw/fs-safe/dist/bounded-read.js +106 -0
  109. package/node_modules/@openclaw/fs-safe/dist/byte-budget.d.ts +4 -0
  110. package/node_modules/@openclaw/fs-safe/dist/byte-budget.d.ts.map +1 -0
  111. package/node_modules/@openclaw/fs-safe/dist/byte-budget.js +9 -0
  112. package/node_modules/@openclaw/fs-safe/dist/config.d.ts +3 -0
  113. package/node_modules/@openclaw/fs-safe/dist/config.d.ts.map +1 -0
  114. package/node_modules/@openclaw/fs-safe/dist/config.js +2 -0
  115. package/node_modules/@openclaw/fs-safe/dist/containment.d.ts +2 -0
  116. package/node_modules/@openclaw/fs-safe/dist/containment.d.ts.map +1 -0
  117. package/node_modules/@openclaw/fs-safe/dist/containment.js +1 -0
  118. package/node_modules/@openclaw/fs-safe/dist/deny-mutations.d.ts +12 -0
  119. package/node_modules/@openclaw/fs-safe/dist/deny-mutations.d.ts.map +1 -0
  120. package/node_modules/@openclaw/fs-safe/dist/deny-mutations.js +69 -0
  121. package/node_modules/@openclaw/fs-safe/dist/device-path.d.ts +15 -0
  122. package/node_modules/@openclaw/fs-safe/dist/device-path.d.ts.map +1 -0
  123. package/node_modules/@openclaw/fs-safe/dist/device-path.js +137 -0
  124. package/node_modules/@openclaw/fs-safe/dist/directory-durability.d.ts +44 -0
  125. package/node_modules/@openclaw/fs-safe/dist/directory-durability.d.ts.map +1 -0
  126. package/node_modules/@openclaw/fs-safe/dist/directory-durability.js +299 -0
  127. package/node_modules/@openclaw/fs-safe/dist/directory-guard.d.ts +31 -0
  128. package/node_modules/@openclaw/fs-safe/dist/directory-guard.d.ts.map +1 -0
  129. package/node_modules/@openclaw/fs-safe/dist/directory-guard.js +82 -0
  130. package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.d.ts +8 -0
  131. package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.d.ts.map +1 -0
  132. package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.js +93 -0
  133. package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.d.ts +21 -0
  134. package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.d.ts.map +1 -0
  135. package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.js +78 -0
  136. package/node_modules/@openclaw/fs-safe/dist/durability.d.ts +4 -0
  137. package/node_modules/@openclaw/fs-safe/dist/durability.d.ts.map +1 -0
  138. package/node_modules/@openclaw/fs-safe/dist/durability.js +3 -0
  139. package/node_modules/@openclaw/fs-safe/dist/error-detail.d.ts +3 -0
  140. package/node_modules/@openclaw/fs-safe/dist/error-detail.d.ts.map +1 -0
  141. package/node_modules/@openclaw/fs-safe/dist/error-detail.js +10 -0
  142. package/node_modules/@openclaw/fs-safe/dist/errors.d.ts +14 -0
  143. package/node_modules/@openclaw/fs-safe/dist/errors.d.ts.map +1 -0
  144. package/node_modules/@openclaw/fs-safe/dist/errors.js +26 -0
  145. package/node_modules/@openclaw/fs-safe/dist/file-hash.d.ts +10 -0
  146. package/node_modules/@openclaw/fs-safe/dist/file-hash.d.ts.map +1 -0
  147. package/node_modules/@openclaw/fs-safe/dist/file-hash.js +73 -0
  148. package/node_modules/@openclaw/fs-safe/dist/file-identity.d.ts +8 -0
  149. package/node_modules/@openclaw/fs-safe/dist/file-identity.d.ts.map +1 -0
  150. package/node_modules/@openclaw/fs-safe/dist/file-identity.js +34 -0
  151. package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.d.ts +35 -0
  152. package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.d.ts.map +1 -0
  153. package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.js +349 -0
  154. package/node_modules/@openclaw/fs-safe/dist/file-lock.d.ts +24 -0
  155. package/node_modules/@openclaw/fs-safe/dist/file-lock.d.ts.map +1 -0
  156. package/node_modules/@openclaw/fs-safe/dist/file-lock.js +46 -0
  157. package/node_modules/@openclaw/fs-safe/dist/file-observation.d.ts +9 -0
  158. package/node_modules/@openclaw/fs-safe/dist/file-observation.d.ts.map +1 -0
  159. package/node_modules/@openclaw/fs-safe/dist/file-observation.js +22 -0
  160. package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.d.ts +33 -0
  161. package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.d.ts.map +1 -0
  162. package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.js +189 -0
  163. package/node_modules/@openclaw/fs-safe/dist/file-store-limit.d.ts +2 -0
  164. package/node_modules/@openclaw/fs-safe/dist/file-store-limit.d.ts.map +1 -0
  165. package/node_modules/@openclaw/fs-safe/dist/file-store-limit.js +8 -0
  166. package/node_modules/@openclaw/fs-safe/dist/file-store-prune.d.ts +12 -0
  167. package/node_modules/@openclaw/fs-safe/dist/file-store-prune.d.ts.map +1 -0
  168. package/node_modules/@openclaw/fs-safe/dist/file-store-prune.js +95 -0
  169. package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.d.ts +9 -0
  170. package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.d.ts.map +1 -0
  171. package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.js +127 -0
  172. package/node_modules/@openclaw/fs-safe/dist/file-store.d.ts +62 -0
  173. package/node_modules/@openclaw/fs-safe/dist/file-store.d.ts.map +1 -0
  174. package/node_modules/@openclaw/fs-safe/dist/file-store.js +357 -0
  175. package/node_modules/@openclaw/fs-safe/dist/file-sync.d.ts +5 -0
  176. package/node_modules/@openclaw/fs-safe/dist/file-sync.d.ts.map +1 -0
  177. package/node_modules/@openclaw/fs-safe/dist/file-sync.js +19 -0
  178. package/node_modules/@openclaw/fs-safe/dist/filename.d.ts +8 -0
  179. package/node_modules/@openclaw/fs-safe/dist/filename.d.ts.map +1 -0
  180. package/node_modules/@openclaw/fs-safe/dist/filename.js +91 -0
  181. package/node_modules/@openclaw/fs-safe/dist/fs.d.ts +13 -0
  182. package/node_modules/@openclaw/fs-safe/dist/fs.d.ts.map +1 -0
  183. package/node_modules/@openclaw/fs-safe/dist/fs.js +30 -0
  184. package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.d.ts +14 -0
  185. package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.d.ts.map +1 -0
  186. package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.js +87 -0
  187. package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.d.ts +37 -0
  188. package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.d.ts.map +1 -0
  189. package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.js +82 -0
  190. package/node_modules/@openclaw/fs-safe/dist/home-dir.d.ts +12 -0
  191. package/node_modules/@openclaw/fs-safe/dist/home-dir.d.ts.map +1 -0
  192. package/node_modules/@openclaw/fs-safe/dist/home-dir.js +84 -0
  193. package/node_modules/@openclaw/fs-safe/dist/index.d.ts +7 -0
  194. package/node_modules/@openclaw/fs-safe/dist/index.d.ts.map +1 -0
  195. package/node_modules/@openclaw/fs-safe/dist/index.js +5 -0
  196. package/node_modules/@openclaw/fs-safe/dist/install-path.d.ts +20 -0
  197. package/node_modules/@openclaw/fs-safe/dist/install-path.d.ts.map +1 -0
  198. package/node_modules/@openclaw/fs-safe/dist/install-path.js +94 -0
  199. package/node_modules/@openclaw/fs-safe/dist/json-document-store.d.ts +35 -0
  200. package/node_modules/@openclaw/fs-safe/dist/json-document-store.d.ts.map +1 -0
  201. package/node_modules/@openclaw/fs-safe/dist/json-document-store.js +97 -0
  202. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.d.ts +2 -0
  203. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.d.ts.map +1 -0
  204. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.js +20 -0
  205. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.d.ts +17 -0
  206. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.d.ts.map +1 -0
  207. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.js +292 -0
  208. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.d.ts +46 -0
  209. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.d.ts.map +1 -0
  210. package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.js +383 -0
  211. package/node_modules/@openclaw/fs-safe/dist/json-store.d.ts +9 -0
  212. package/node_modules/@openclaw/fs-safe/dist/json-store.d.ts.map +1 -0
  213. package/node_modules/@openclaw/fs-safe/dist/json-store.js +12 -0
  214. package/node_modules/@openclaw/fs-safe/dist/json-stringify.d.ts +2 -0
  215. package/node_modules/@openclaw/fs-safe/dist/json-stringify.d.ts.map +1 -0
  216. package/node_modules/@openclaw/fs-safe/dist/json-stringify.js +7 -0
  217. package/node_modules/@openclaw/fs-safe/dist/json.d.ts +50 -0
  218. package/node_modules/@openclaw/fs-safe/dist/json.d.ts.map +1 -0
  219. package/node_modules/@openclaw/fs-safe/dist/json.js +343 -0
  220. package/node_modules/@openclaw/fs-safe/dist/local-file-access.d.ts +9 -0
  221. package/node_modules/@openclaw/fs-safe/dist/local-file-access.d.ts.map +1 -0
  222. package/node_modules/@openclaw/fs-safe/dist/local-file-access.js +87 -0
  223. package/node_modules/@openclaw/fs-safe/dist/local-roots.d.ts +26 -0
  224. package/node_modules/@openclaw/fs-safe/dist/local-roots.d.ts.map +1 -0
  225. package/node_modules/@openclaw/fs-safe/dist/local-roots.js +135 -0
  226. package/node_modules/@openclaw/fs-safe/dist/lock-config.d.ts +10 -0
  227. package/node_modules/@openclaw/fs-safe/dist/lock-config.d.ts.map +1 -0
  228. package/node_modules/@openclaw/fs-safe/dist/lock-config.js +12 -0
  229. package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.d.ts +43 -0
  230. package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.d.ts.map +1 -0
  231. package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.js +161 -0
  232. package/node_modules/@openclaw/fs-safe/dist/move-path.d.ts +21 -0
  233. package/node_modules/@openclaw/fs-safe/dist/move-path.d.ts.map +1 -0
  234. package/node_modules/@openclaw/fs-safe/dist/move-path.js +334 -0
  235. package/node_modules/@openclaw/fs-safe/dist/native-binding.d.ts +93 -0
  236. package/node_modules/@openclaw/fs-safe/dist/native-binding.d.ts.map +1 -0
  237. package/node_modules/@openclaw/fs-safe/dist/native-binding.js +1 -0
  238. package/node_modules/@openclaw/fs-safe/dist/native-config.d.ts +17 -0
  239. package/node_modules/@openclaw/fs-safe/dist/native-config.d.ts.map +1 -0
  240. package/node_modules/@openclaw/fs-safe/dist/native-config.js +71 -0
  241. package/node_modules/@openclaw/fs-safe/dist/native-operations.d.ts +21 -0
  242. package/node_modules/@openclaw/fs-safe/dist/native-operations.d.ts.map +1 -0
  243. package/node_modules/@openclaw/fs-safe/dist/native-operations.js +132 -0
  244. package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.d.ts +8 -0
  245. package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.d.ts.map +1 -0
  246. package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.js +96 -0
  247. package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.d.ts +5 -0
  248. package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.d.ts.map +1 -0
  249. package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.js +161 -0
  250. package/node_modules/@openclaw/fs-safe/dist/native-staged-file.d.ts +31 -0
  251. package/node_modules/@openclaw/fs-safe/dist/native-staged-file.d.ts.map +1 -0
  252. package/node_modules/@openclaw/fs-safe/dist/native-staged-file.js +362 -0
  253. package/node_modules/@openclaw/fs-safe/dist/native.d.ts +14 -0
  254. package/node_modules/@openclaw/fs-safe/dist/native.d.ts.map +1 -0
  255. package/node_modules/@openclaw/fs-safe/dist/native.js +204 -0
  256. package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.d.ts +8 -0
  257. package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.d.ts.map +1 -0
  258. package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.js +45 -0
  259. package/node_modules/@openclaw/fs-safe/dist/opened-realpath.d.ts +16 -0
  260. package/node_modules/@openclaw/fs-safe/dist/opened-realpath.d.ts.map +1 -0
  261. package/node_modules/@openclaw/fs-safe/dist/opened-realpath.js +92 -0
  262. package/node_modules/@openclaw/fs-safe/dist/output.d.ts +15 -0
  263. package/node_modules/@openclaw/fs-safe/dist/output.d.ts.map +1 -0
  264. package/node_modules/@openclaw/fs-safe/dist/output.js +123 -0
  265. package/node_modules/@openclaw/fs-safe/dist/owner-dacl.d.ts +31 -0
  266. package/node_modules/@openclaw/fs-safe/dist/owner-dacl.d.ts.map +1 -0
  267. package/node_modules/@openclaw/fs-safe/dist/owner-dacl.js +28 -0
  268. package/node_modules/@openclaw/fs-safe/dist/path-policy.d.ts +25 -0
  269. package/node_modules/@openclaw/fs-safe/dist/path-policy.d.ts.map +1 -0
  270. package/node_modules/@openclaw/fs-safe/dist/path-policy.js +44 -0
  271. package/node_modules/@openclaw/fs-safe/dist/path.d.ts +21 -0
  272. package/node_modules/@openclaw/fs-safe/dist/path.d.ts.map +1 -0
  273. package/node_modules/@openclaw/fs-safe/dist/path.js +136 -0
  274. package/node_modules/@openclaw/fs-safe/dist/permission-exec.d.ts +25 -0
  275. package/node_modules/@openclaw/fs-safe/dist/permission-exec.d.ts.map +1 -0
  276. package/node_modules/@openclaw/fs-safe/dist/permission-exec.js +74 -0
  277. package/node_modules/@openclaw/fs-safe/dist/permissions-public.d.ts +4 -0
  278. package/node_modules/@openclaw/fs-safe/dist/permissions-public.d.ts.map +1 -0
  279. package/node_modules/@openclaw/fs-safe/dist/permissions-public.js +3 -0
  280. package/node_modules/@openclaw/fs-safe/dist/permissions-windows.d.ts +59 -0
  281. package/node_modules/@openclaw/fs-safe/dist/permissions-windows.d.ts.map +1 -0
  282. package/node_modules/@openclaw/fs-safe/dist/permissions-windows.js +296 -0
  283. package/node_modules/@openclaw/fs-safe/dist/permissions.d.ts +60 -0
  284. package/node_modules/@openclaw/fs-safe/dist/permissions.d.ts.map +1 -0
  285. package/node_modules/@openclaw/fs-safe/dist/permissions.js +125 -0
  286. package/node_modules/@openclaw/fs-safe/dist/pinned-open.d.ts +24 -0
  287. package/node_modules/@openclaw/fs-safe/dist/pinned-open.d.ts.map +1 -0
  288. package/node_modules/@openclaw/fs-safe/dist/pinned-open.js +74 -0
  289. package/node_modules/@openclaw/fs-safe/dist/pinned-operation.d.ts +2 -0
  290. package/node_modules/@openclaw/fs-safe/dist/pinned-operation.d.ts.map +1 -0
  291. package/node_modules/@openclaw/fs-safe/dist/pinned-operation.js +35 -0
  292. package/node_modules/@openclaw/fs-safe/dist/pinned-write.d.ts +36 -0
  293. package/node_modules/@openclaw/fs-safe/dist/pinned-write.d.ts.map +1 -0
  294. package/node_modules/@openclaw/fs-safe/dist/pinned-write.js +252 -0
  295. package/node_modules/@openclaw/fs-safe/dist/private-directory.d.ts +5 -0
  296. package/node_modules/@openclaw/fs-safe/dist/private-directory.d.ts.map +1 -0
  297. package/node_modules/@openclaw/fs-safe/dist/private-directory.js +14 -0
  298. package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.d.ts +45 -0
  299. package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.d.ts.map +1 -0
  300. package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.js +299 -0
  301. package/node_modules/@openclaw/fs-safe/dist/publish-file-failure.d.ts +28 -0
  302. package/node_modules/@openclaw/fs-safe/dist/publish-file-failure.d.ts.map +1 -0
  303. package/node_modules/@openclaw/fs-safe/dist/publish-file-failure.js +22 -0
  304. package/node_modules/@openclaw/fs-safe/dist/publish-file.d.ts +21 -0
  305. package/node_modules/@openclaw/fs-safe/dist/publish-file.d.ts.map +1 -0
  306. package/node_modules/@openclaw/fs-safe/dist/publish-file.js +366 -0
  307. package/node_modules/@openclaw/fs-safe/dist/read-open-flags.d.ts +8 -0
  308. package/node_modules/@openclaw/fs-safe/dist/read-open-flags.d.ts.map +1 -0
  309. package/node_modules/@openclaw/fs-safe/dist/read-open-flags.js +13 -0
  310. package/node_modules/@openclaw/fs-safe/dist/read-opened-file.d.ts +21 -0
  311. package/node_modules/@openclaw/fs-safe/dist/read-opened-file.d.ts.map +1 -0
  312. package/node_modules/@openclaw/fs-safe/dist/read-opened-file.js +18 -0
  313. package/node_modules/@openclaw/fs-safe/dist/regular-file.d.ts +38 -0
  314. package/node_modules/@openclaw/fs-safe/dist/regular-file.d.ts.map +1 -0
  315. package/node_modules/@openclaw/fs-safe/dist/regular-file.js +391 -0
  316. package/node_modules/@openclaw/fs-safe/dist/replace-directory.d.ts +7 -0
  317. package/node_modules/@openclaw/fs-safe/dist/replace-directory.d.ts.map +1 -0
  318. package/node_modules/@openclaw/fs-safe/dist/replace-directory.js +42 -0
  319. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.d.ts +39 -0
  320. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.d.ts.map +1 -0
  321. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.js +331 -0
  322. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.d.ts +21 -0
  323. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.d.ts.map +1 -0
  324. package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.js +107 -0
  325. package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.d.ts +51 -0
  326. package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.d.ts.map +1 -0
  327. package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.js +161 -0
  328. package/node_modules/@openclaw/fs-safe/dist/replace-file-rename-policy.d.ts +7 -0
  329. package/node_modules/@openclaw/fs-safe/dist/replace-file-rename-policy.d.ts.map +1 -0
  330. package/node_modules/@openclaw/fs-safe/dist/replace-file-rename-policy.js +30 -0
  331. package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.d.ts +53 -0
  332. package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.d.ts.map +1 -0
  333. package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.js +376 -0
  334. package/node_modules/@openclaw/fs-safe/dist/replace-file.d.ts +58 -0
  335. package/node_modules/@openclaw/fs-safe/dist/replace-file.d.ts.map +1 -0
  336. package/node_modules/@openclaw/fs-safe/dist/replace-file.js +329 -0
  337. package/node_modules/@openclaw/fs-safe/dist/root-context.d.ts +38 -0
  338. package/node_modules/@openclaw/fs-safe/dist/root-context.d.ts.map +1 -0
  339. package/node_modules/@openclaw/fs-safe/dist/root-context.js +141 -0
  340. package/node_modules/@openclaw/fs-safe/dist/root-errors.d.ts +12 -0
  341. package/node_modules/@openclaw/fs-safe/dist/root-errors.d.ts.map +1 -0
  342. package/node_modules/@openclaw/fs-safe/dist/root-errors.js +75 -0
  343. package/node_modules/@openclaw/fs-safe/dist/root-file.d.ts +45 -0
  344. package/node_modules/@openclaw/fs-safe/dist/root-file.d.ts.map +1 -0
  345. package/node_modules/@openclaw/fs-safe/dist/root-file.js +120 -0
  346. package/node_modules/@openclaw/fs-safe/dist/root-impl.d.ts +163 -0
  347. package/node_modules/@openclaw/fs-safe/dist/root-impl.d.ts.map +1 -0
  348. package/node_modules/@openclaw/fs-safe/dist/root-impl.js +1230 -0
  349. package/node_modules/@openclaw/fs-safe/dist/root-path-existing.d.ts +3 -0
  350. package/node_modules/@openclaw/fs-safe/dist/root-path-existing.d.ts.map +1 -0
  351. package/node_modules/@openclaw/fs-safe/dist/root-path-existing.js +68 -0
  352. package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.d.ts +7 -0
  353. package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.d.ts.map +1 -0
  354. package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.js +35 -0
  355. package/node_modules/@openclaw/fs-safe/dist/root-path.d.ts +40 -0
  356. package/node_modules/@openclaw/fs-safe/dist/root-path.d.ts.map +1 -0
  357. package/node_modules/@openclaw/fs-safe/dist/root-path.js +481 -0
  358. package/node_modules/@openclaw/fs-safe/dist/root-paths.d.ts +89 -0
  359. package/node_modules/@openclaw/fs-safe/dist/root-paths.d.ts.map +1 -0
  360. package/node_modules/@openclaw/fs-safe/dist/root-paths.js +381 -0
  361. package/node_modules/@openclaw/fs-safe/dist/root-walk.d.ts +41 -0
  362. package/node_modules/@openclaw/fs-safe/dist/root-walk.d.ts.map +1 -0
  363. package/node_modules/@openclaw/fs-safe/dist/root-walk.js +133 -0
  364. package/node_modules/@openclaw/fs-safe/dist/root-write-mode.d.ts +6 -0
  365. package/node_modules/@openclaw/fs-safe/dist/root-write-mode.d.ts.map +1 -0
  366. package/node_modules/@openclaw/fs-safe/dist/root-write-mode.js +61 -0
  367. package/node_modules/@openclaw/fs-safe/dist/root-write-verification.d.ts +12 -0
  368. package/node_modules/@openclaw/fs-safe/dist/root-write-verification.d.ts.map +1 -0
  369. package/node_modules/@openclaw/fs-safe/dist/root-write-verification.js +97 -0
  370. package/node_modules/@openclaw/fs-safe/dist/root.d.ts +4 -0
  371. package/node_modules/@openclaw/fs-safe/dist/root.d.ts.map +1 -0
  372. package/node_modules/@openclaw/fs-safe/dist/root.js +1 -0
  373. package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.d.ts +12 -0
  374. package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.d.ts.map +1 -0
  375. package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.js +75 -0
  376. package/node_modules/@openclaw/fs-safe/dist/secret-file.d.ts +25 -0
  377. package/node_modules/@openclaw/fs-safe/dist/secret-file.d.ts.map +1 -0
  378. package/node_modules/@openclaw/fs-safe/dist/secret-file.js +329 -0
  379. package/node_modules/@openclaw/fs-safe/dist/secret-read-async.d.ts +4 -0
  380. package/node_modules/@openclaw/fs-safe/dist/secret-read-async.d.ts.map +1 -0
  381. package/node_modules/@openclaw/fs-safe/dist/secret-read-async.js +73 -0
  382. package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.d.ts +17 -0
  383. package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.d.ts.map +1 -0
  384. package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.js +40 -0
  385. package/node_modules/@openclaw/fs-safe/dist/secret.d.ts +4 -0
  386. package/node_modules/@openclaw/fs-safe/dist/secret.d.ts.map +1 -0
  387. package/node_modules/@openclaw/fs-safe/dist/secret.js +3 -0
  388. package/node_modules/@openclaw/fs-safe/dist/secure-file.d.ts +32 -0
  389. package/node_modules/@openclaw/fs-safe/dist/secure-file.d.ts.map +1 -0
  390. package/node_modules/@openclaw/fs-safe/dist/secure-file.js +182 -0
  391. package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.d.ts +27 -0
  392. package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.d.ts.map +1 -0
  393. package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.js +160 -0
  394. package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.d.ts +15 -0
  395. package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.d.ts.map +1 -0
  396. package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.js +143 -0
  397. package/node_modules/@openclaw/fs-safe/dist/sibling-temp.d.ts +27 -0
  398. package/node_modules/@openclaw/fs-safe/dist/sibling-temp.d.ts.map +1 -0
  399. package/node_modules/@openclaw/fs-safe/dist/sibling-temp.js +95 -0
  400. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.d.ts +31 -0
  401. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.d.ts.map +1 -0
  402. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.js +336 -0
  403. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.d.ts +24 -0
  404. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.d.ts.map +1 -0
  405. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.js +42 -0
  406. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.d.ts +14 -0
  407. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.d.ts.map +1 -0
  408. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.js +71 -0
  409. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.d.ts +63 -0
  410. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.d.ts.map +1 -0
  411. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js +305 -0
  412. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.d.ts +3 -0
  413. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.d.ts.map +1 -0
  414. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.js +76 -0
  415. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-types.d.ts +63 -0
  416. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-types.d.ts.map +1 -0
  417. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-types.js +1 -0
  418. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.d.ts +14 -0
  419. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.d.ts.map +1 -0
  420. package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.js +265 -0
  421. package/node_modules/@openclaw/fs-safe/dist/staged-directory.d.ts +16 -0
  422. package/node_modules/@openclaw/fs-safe/dist/staged-directory.d.ts.map +1 -0
  423. package/node_modules/@openclaw/fs-safe/dist/staged-directory.js +60 -0
  424. package/node_modules/@openclaw/fs-safe/dist/staged-file-types.d.ts +56 -0
  425. package/node_modules/@openclaw/fs-safe/dist/staged-file-types.d.ts.map +1 -0
  426. package/node_modules/@openclaw/fs-safe/dist/staged-file-types.js +1 -0
  427. package/node_modules/@openclaw/fs-safe/dist/store.d.ts +4 -0
  428. package/node_modules/@openclaw/fs-safe/dist/store.d.ts.map +1 -0
  429. package/node_modules/@openclaw/fs-safe/dist/store.js +3 -0
  430. package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.d.ts +6 -0
  431. package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.d.ts.map +1 -0
  432. package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.js +51 -0
  433. package/node_modules/@openclaw/fs-safe/dist/string-coerce.d.ts +5 -0
  434. package/node_modules/@openclaw/fs-safe/dist/string-coerce.d.ts.map +1 -0
  435. package/node_modules/@openclaw/fs-safe/dist/string-coerce.js +16 -0
  436. package/node_modules/@openclaw/fs-safe/dist/suppressed-error.d.ts +6 -0
  437. package/node_modules/@openclaw/fs-safe/dist/suppressed-error.d.ts.map +1 -0
  438. package/node_modules/@openclaw/fs-safe/dist/suppressed-error.js +15 -0
  439. package/node_modules/@openclaw/fs-safe/dist/symlink-parents.d.ts +12 -0
  440. package/node_modules/@openclaw/fs-safe/dist/symlink-parents.d.ts.map +1 -0
  441. package/node_modules/@openclaw/fs-safe/dist/symlink-parents.js +78 -0
  442. package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.d.ts +14 -0
  443. package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.d.ts.map +1 -0
  444. package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.js +87 -0
  445. package/node_modules/@openclaw/fs-safe/dist/temp-target.d.ts +28 -0
  446. package/node_modules/@openclaw/fs-safe/dist/temp-target.d.ts.map +1 -0
  447. package/node_modules/@openclaw/fs-safe/dist/temp-target.js +137 -0
  448. package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.d.ts +23 -0
  449. package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.d.ts.map +1 -0
  450. package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.js +320 -0
  451. package/node_modules/@openclaw/fs-safe/dist/temp.d.ts +4 -0
  452. package/node_modules/@openclaw/fs-safe/dist/temp.d.ts.map +1 -0
  453. package/node_modules/@openclaw/fs-safe/dist/temp.js +2 -0
  454. package/node_modules/@openclaw/fs-safe/dist/test-hooks.d.ts +25 -0
  455. package/node_modules/@openclaw/fs-safe/dist/test-hooks.d.ts.map +1 -0
  456. package/node_modules/@openclaw/fs-safe/dist/test-hooks.js +13 -0
  457. package/node_modules/@openclaw/fs-safe/dist/text-atomic.d.ts +14 -0
  458. package/node_modules/@openclaw/fs-safe/dist/text-atomic.d.ts.map +1 -0
  459. package/node_modules/@openclaw/fs-safe/dist/text-atomic.js +14 -0
  460. package/node_modules/@openclaw/fs-safe/dist/timing.d.ts +8 -0
  461. package/node_modules/@openclaw/fs-safe/dist/timing.d.ts.map +1 -0
  462. package/node_modules/@openclaw/fs-safe/dist/timing.js +40 -0
  463. package/node_modules/@openclaw/fs-safe/dist/trash.d.ts +5 -0
  464. package/node_modules/@openclaw/fs-safe/dist/trash.d.ts.map +1 -0
  465. package/node_modules/@openclaw/fs-safe/dist/trash.js +171 -0
  466. package/node_modules/@openclaw/fs-safe/dist/types.d.ts +23 -0
  467. package/node_modules/@openclaw/fs-safe/dist/types.d.ts.map +1 -0
  468. package/node_modules/@openclaw/fs-safe/dist/types.js +1 -0
  469. package/node_modules/@openclaw/fs-safe/dist/walk.d.ts +37 -0
  470. package/node_modules/@openclaw/fs-safe/dist/walk.d.ts.map +1 -0
  471. package/node_modules/@openclaw/fs-safe/dist/walk.js +207 -0
  472. package/node_modules/@openclaw/fs-safe/dist/windows-command.d.ts +2 -0
  473. package/node_modules/@openclaw/fs-safe/dist/windows-command.d.ts.map +1 -0
  474. package/node_modules/@openclaw/fs-safe/dist/windows-command.js +34 -0
  475. package/node_modules/@openclaw/fs-safe/dist/windows-owner.d.ts +32 -0
  476. package/node_modules/@openclaw/fs-safe/dist/windows-owner.d.ts.map +1 -0
  477. package/node_modules/@openclaw/fs-safe/dist/windows-owner.js +126 -0
  478. package/node_modules/@openclaw/fs-safe/dist/write-open-flags.d.ts +5 -0
  479. package/node_modules/@openclaw/fs-safe/dist/write-open-flags.d.ts.map +1 -0
  480. package/node_modules/@openclaw/fs-safe/dist/write-open-flags.js +35 -0
  481. package/node_modules/@openclaw/fs-safe/dist/write-queue.d.ts +2 -0
  482. package/node_modules/@openclaw/fs-safe/dist/write-queue.d.ts.map +1 -0
  483. package/node_modules/@openclaw/fs-safe/dist/write-queue.js +18 -0
  484. package/node_modules/@openclaw/fs-safe/docs/advanced.md +153 -0
  485. package/node_modules/@openclaw/fs-safe/docs/archive.md +658 -0
  486. package/node_modules/@openclaw/fs-safe/docs/assets/readme-banner.jpg +0 -0
  487. package/node_modules/@openclaw/fs-safe/docs/atomic.md +334 -0
  488. package/node_modules/@openclaw/fs-safe/docs/config.md +131 -0
  489. package/node_modules/@openclaw/fs-safe/docs/contributing.md +180 -0
  490. package/node_modules/@openclaw/fs-safe/docs/durability.md +313 -0
  491. package/node_modules/@openclaw/fs-safe/docs/errors.md +232 -0
  492. package/node_modules/@openclaw/fs-safe/docs/file-store.md +258 -0
  493. package/node_modules/@openclaw/fs-safe/docs/filename.md +96 -0
  494. package/node_modules/@openclaw/fs-safe/docs/index.md +84 -0
  495. package/node_modules/@openclaw/fs-safe/docs/install-path.md +170 -0
  496. package/node_modules/@openclaw/fs-safe/docs/install.md +163 -0
  497. package/node_modules/@openclaw/fs-safe/docs/json-store.md +221 -0
  498. package/node_modules/@openclaw/fs-safe/docs/json.md +213 -0
  499. package/node_modules/@openclaw/fs-safe/docs/local-roots.md +141 -0
  500. package/node_modules/@openclaw/fs-safe/docs/migrating-to-0.5.md +196 -0
  501. package/node_modules/@openclaw/fs-safe/docs/migrating-to-0.6.md +43 -0
  502. package/node_modules/@openclaw/fs-safe/docs/native-helper.md +118 -0
  503. package/node_modules/@openclaw/fs-safe/docs/native.md +196 -0
  504. package/node_modules/@openclaw/fs-safe/docs/output.md +139 -0
  505. package/node_modules/@openclaw/fs-safe/docs/path-scope.md +159 -0
  506. package/node_modules/@openclaw/fs-safe/docs/path.md +208 -0
  507. package/node_modules/@openclaw/fs-safe/docs/permissions.md +200 -0
  508. package/node_modules/@openclaw/fs-safe/docs/private-file-store.md +54 -0
  509. package/node_modules/@openclaw/fs-safe/docs/public-api.md +112 -0
  510. package/node_modules/@openclaw/fs-safe/docs/quickstart.md +154 -0
  511. package/node_modules/@openclaw/fs-safe/docs/reading.md +183 -0
  512. package/node_modules/@openclaw/fs-safe/docs/regular-file.md +190 -0
  513. package/node_modules/@openclaw/fs-safe/docs/root.md +266 -0
  514. package/node_modules/@openclaw/fs-safe/docs/secret-file.md +273 -0
  515. package/node_modules/@openclaw/fs-safe/docs/secure-file.md +100 -0
  516. package/node_modules/@openclaw/fs-safe/docs/security-model.md +188 -0
  517. package/node_modules/@openclaw/fs-safe/docs/sidecar-lock.md +439 -0
  518. package/node_modules/@openclaw/fs-safe/docs/staged-file.md +182 -0
  519. package/node_modules/@openclaw/fs-safe/docs/store.md +94 -0
  520. package/node_modules/@openclaw/fs-safe/docs/temp.md +476 -0
  521. package/node_modules/@openclaw/fs-safe/docs/test-hooks.md +96 -0
  522. package/node_modules/@openclaw/fs-safe/docs/testing.md +189 -0
  523. package/node_modules/@openclaw/fs-safe/docs/timing.md +121 -0
  524. package/node_modules/@openclaw/fs-safe/docs/types.md +188 -0
  525. package/node_modules/@openclaw/fs-safe/docs/walk.md +128 -0
  526. package/node_modules/@openclaw/fs-safe/docs/writing.md +347 -0
  527. package/node_modules/@openclaw/fs-safe/package.json +187 -0
  528. package/node_modules/@openclaw/fs-safe-darwin-arm64/fs-safe-native.node +0 -0
  529. package/node_modules/@openclaw/fs-safe-darwin-arm64/package.json +29 -0
  530. package/node_modules/@openclaw/fs-safe-darwin-x64/fs-safe-native.node +0 -0
  531. package/node_modules/@openclaw/fs-safe-darwin-x64/package.json +29 -0
  532. package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/fs-safe-native.node +0 -0
  533. package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/package.json +32 -0
  534. package/node_modules/@openclaw/fs-safe-linux-arm64-musl/fs-safe-native.node +0 -0
  535. package/node_modules/@openclaw/fs-safe-linux-arm64-musl/package.json +32 -0
  536. package/node_modules/@openclaw/fs-safe-linux-x64-gnu/fs-safe-native.node +0 -0
  537. package/node_modules/@openclaw/fs-safe-linux-x64-gnu/package.json +32 -0
  538. package/node_modules/@openclaw/fs-safe-linux-x64-musl/fs-safe-native.node +0 -0
  539. package/node_modules/@openclaw/fs-safe-linux-x64-musl/package.json +32 -0
  540. package/node_modules/@openclaw/fs-safe-win32-x64-msvc/fs-safe-native.node +0 -0
  541. package/node_modules/@openclaw/fs-safe-win32-x64-msvc/package.json +29 -0
  542. package/node_modules/core-util-is/LICENSE +19 -0
  543. package/node_modules/core-util-is/README.md +3 -0
  544. package/node_modules/core-util-is/lib/util.js +107 -0
  545. package/node_modules/core-util-is/package.json +38 -0
  546. package/node_modules/immediate/LICENSE.txt +20 -0
  547. package/node_modules/immediate/README.md +93 -0
  548. package/node_modules/immediate/dist/immediate.js +75 -0
  549. package/node_modules/immediate/dist/immediate.min.js +1 -0
  550. package/node_modules/immediate/lib/browser.js +69 -0
  551. package/node_modules/immediate/lib/index.js +73 -0
  552. package/node_modules/immediate/package.json +42 -0
  553. package/node_modules/inherits/LICENSE +16 -0
  554. package/node_modules/inherits/README.md +42 -0
  555. package/node_modules/inherits/inherits.js +9 -0
  556. package/node_modules/inherits/inherits_browser.js +27 -0
  557. package/node_modules/inherits/package.json +29 -0
  558. package/node_modules/isarray/.npmignore +1 -0
  559. package/node_modules/isarray/.travis.yml +4 -0
  560. package/node_modules/isarray/Makefile +6 -0
  561. package/node_modules/isarray/README.md +60 -0
  562. package/node_modules/isarray/component.json +19 -0
  563. package/node_modules/isarray/index.js +5 -0
  564. package/node_modules/isarray/package.json +45 -0
  565. package/node_modules/isarray/test.js +20 -0
  566. package/node_modules/jszip/.codeclimate.yml +16 -0
  567. package/node_modules/jszip/.editorconfig +8 -0
  568. package/node_modules/jszip/.eslintrc.js +43 -0
  569. package/node_modules/jszip/.github/workflows/pr.yaml +58 -0
  570. package/node_modules/jszip/.jekyll-metadata +0 -0
  571. package/node_modules/jszip/.travis.yml +17 -0
  572. package/node_modules/jszip/CHANGES.md +204 -0
  573. package/node_modules/jszip/LICENSE.markdown +651 -0
  574. package/node_modules/jszip/README.markdown +33 -0
  575. package/node_modules/jszip/deps.js +37 -0
  576. package/node_modules/jszip/dist/jszip.js +11577 -0
  577. package/node_modules/jszip/dist/jszip.min.js +13 -0
  578. package/node_modules/jszip/graph.svg +601 -0
  579. package/node_modules/jszip/index.d.ts +330 -0
  580. package/node_modules/jszip/lib/base64.js +106 -0
  581. package/node_modules/jszip/lib/compressedObject.js +74 -0
  582. package/node_modules/jszip/lib/compressions.js +14 -0
  583. package/node_modules/jszip/lib/crc32.js +77 -0
  584. package/node_modules/jszip/lib/defaults.js +11 -0
  585. package/node_modules/jszip/lib/external.js +18 -0
  586. package/node_modules/jszip/lib/flate.js +85 -0
  587. package/node_modules/jszip/lib/generate/ZipFileWorker.js +539 -0
  588. package/node_modules/jszip/lib/generate/index.js +57 -0
  589. package/node_modules/jszip/lib/index.js +55 -0
  590. package/node_modules/jszip/lib/license_header.js +11 -0
  591. package/node_modules/jszip/lib/load.js +88 -0
  592. package/node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js +74 -0
  593. package/node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js +42 -0
  594. package/node_modules/jszip/lib/nodejsUtils.js +57 -0
  595. package/node_modules/jszip/lib/object.js +384 -0
  596. package/node_modules/jszip/lib/readable-stream-browser.js +10 -0
  597. package/node_modules/jszip/lib/reader/ArrayReader.js +57 -0
  598. package/node_modules/jszip/lib/reader/DataReader.js +116 -0
  599. package/node_modules/jszip/lib/reader/NodeBufferReader.js +19 -0
  600. package/node_modules/jszip/lib/reader/StringReader.js +38 -0
  601. package/node_modules/jszip/lib/reader/Uint8ArrayReader.js +22 -0
  602. package/node_modules/jszip/lib/reader/readerFor.js +28 -0
  603. package/node_modules/jszip/lib/signature.js +7 -0
  604. package/node_modules/jszip/lib/stream/ConvertWorker.js +26 -0
  605. package/node_modules/jszip/lib/stream/Crc32Probe.js +24 -0
  606. package/node_modules/jszip/lib/stream/DataLengthProbe.js +29 -0
  607. package/node_modules/jszip/lib/stream/DataWorker.js +116 -0
  608. package/node_modules/jszip/lib/stream/GenericWorker.js +263 -0
  609. package/node_modules/jszip/lib/stream/StreamHelper.js +214 -0
  610. package/node_modules/jszip/lib/support.js +38 -0
  611. package/node_modules/jszip/lib/utf8.js +275 -0
  612. package/node_modules/jszip/lib/utils.js +501 -0
  613. package/node_modules/jszip/lib/zipEntries.js +261 -0
  614. package/node_modules/jszip/lib/zipEntry.js +293 -0
  615. package/node_modules/jszip/lib/zipObject.js +133 -0
  616. package/node_modules/jszip/package.json +67 -0
  617. package/node_modules/jszip/sponsors.md +21 -0
  618. package/node_modules/jszip/tsconfig.json +101 -0
  619. package/node_modules/jszip/vendor/FileSaver.js +247 -0
  620. package/node_modules/lie/README.md +62 -0
  621. package/node_modules/lie/dist/lie.js +350 -0
  622. package/node_modules/lie/dist/lie.min.js +1 -0
  623. package/node_modules/lie/dist/lie.polyfill.js +358 -0
  624. package/node_modules/lie/dist/lie.polyfill.min.js +1 -0
  625. package/node_modules/lie/lib/browser.js +273 -0
  626. package/node_modules/lie/lib/index.js +298 -0
  627. package/node_modules/lie/license.md +7 -0
  628. package/node_modules/lie/lie.d.ts +244 -0
  629. package/node_modules/lie/package.json +69 -0
  630. package/node_modules/lie/polyfill.js +4 -0
  631. package/node_modules/pako/CHANGELOG.md +164 -0
  632. package/node_modules/pako/LICENSE +21 -0
  633. package/node_modules/pako/README.md +191 -0
  634. package/node_modules/pako/dist/pako.js +6818 -0
  635. package/node_modules/pako/dist/pako.min.js +1 -0
  636. package/node_modules/pako/dist/pako_deflate.js +3997 -0
  637. package/node_modules/pako/dist/pako_deflate.min.js +1 -0
  638. package/node_modules/pako/dist/pako_inflate.js +3300 -0
  639. package/node_modules/pako/dist/pako_inflate.min.js +1 -0
  640. package/node_modules/pako/index.js +14 -0
  641. package/node_modules/pako/lib/deflate.js +400 -0
  642. package/node_modules/pako/lib/inflate.js +423 -0
  643. package/node_modules/pako/lib/utils/common.js +105 -0
  644. package/node_modules/pako/lib/utils/strings.js +187 -0
  645. package/node_modules/pako/lib/zlib/README +59 -0
  646. package/node_modules/pako/lib/zlib/adler32.js +51 -0
  647. package/node_modules/pako/lib/zlib/constants.js +68 -0
  648. package/node_modules/pako/lib/zlib/crc32.js +59 -0
  649. package/node_modules/pako/lib/zlib/deflate.js +1874 -0
  650. package/node_modules/pako/lib/zlib/gzheader.js +58 -0
  651. package/node_modules/pako/lib/zlib/inffast.js +345 -0
  652. package/node_modules/pako/lib/zlib/inflate.js +1556 -0
  653. package/node_modules/pako/lib/zlib/inftrees.js +343 -0
  654. package/node_modules/pako/lib/zlib/messages.js +32 -0
  655. package/node_modules/pako/lib/zlib/trees.js +1222 -0
  656. package/node_modules/pako/lib/zlib/zstream.js +47 -0
  657. package/node_modules/pako/package.json +44 -0
  658. package/node_modules/process-nextick-args/index.js +45 -0
  659. package/node_modules/process-nextick-args/license.md +19 -0
  660. package/node_modules/process-nextick-args/package.json +25 -0
  661. package/node_modules/process-nextick-args/readme.md +18 -0
  662. package/node_modules/readable-stream/.travis.yml +34 -0
  663. package/node_modules/readable-stream/CONTRIBUTING.md +38 -0
  664. package/node_modules/readable-stream/GOVERNANCE.md +136 -0
  665. package/node_modules/readable-stream/LICENSE +47 -0
  666. package/node_modules/readable-stream/README.md +58 -0
  667. package/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +60 -0
  668. package/node_modules/readable-stream/duplex-browser.js +1 -0
  669. package/node_modules/readable-stream/duplex.js +1 -0
  670. package/node_modules/readable-stream/lib/_stream_duplex.js +131 -0
  671. package/node_modules/readable-stream/lib/_stream_passthrough.js +47 -0
  672. package/node_modules/readable-stream/lib/_stream_readable.js +1019 -0
  673. package/node_modules/readable-stream/lib/_stream_transform.js +214 -0
  674. package/node_modules/readable-stream/lib/_stream_writable.js +685 -0
  675. package/node_modules/readable-stream/lib/internal/streams/BufferList.js +78 -0
  676. package/node_modules/readable-stream/lib/internal/streams/destroy.js +84 -0
  677. package/node_modules/readable-stream/lib/internal/streams/stream-browser.js +1 -0
  678. package/node_modules/readable-stream/lib/internal/streams/stream.js +1 -0
  679. package/node_modules/readable-stream/package.json +52 -0
  680. package/node_modules/readable-stream/passthrough.js +1 -0
  681. package/node_modules/readable-stream/readable-browser.js +7 -0
  682. package/node_modules/readable-stream/readable.js +19 -0
  683. package/node_modules/readable-stream/transform.js +1 -0
  684. package/node_modules/readable-stream/writable-browser.js +1 -0
  685. package/node_modules/readable-stream/writable.js +8 -0
  686. package/node_modules/safe-buffer/LICENSE +21 -0
  687. package/node_modules/safe-buffer/README.md +584 -0
  688. package/node_modules/safe-buffer/index.d.ts +187 -0
  689. package/node_modules/safe-buffer/index.js +62 -0
  690. package/node_modules/safe-buffer/package.json +37 -0
  691. package/node_modules/setimmediate/LICENSE.txt +20 -0
  692. package/node_modules/setimmediate/package.json +30 -0
  693. package/node_modules/setimmediate/setImmediate.js +186 -0
  694. package/node_modules/string_decoder/.travis.yml +50 -0
  695. package/node_modules/string_decoder/LICENSE +48 -0
  696. package/node_modules/string_decoder/README.md +47 -0
  697. package/node_modules/string_decoder/lib/string_decoder.js +296 -0
  698. package/node_modules/string_decoder/package.json +31 -0
  699. package/node_modules/util-deprecate/History.md +16 -0
  700. package/node_modules/util-deprecate/LICENSE +24 -0
  701. package/node_modules/util-deprecate/README.md +53 -0
  702. package/node_modules/util-deprecate/browser.js +67 -0
  703. package/node_modules/util-deprecate/node.js +6 -0
  704. package/node_modules/util-deprecate/package.json +27 -0
  705. package/package.json +6 -4
  706. /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/index.d.ts +0 -0
  707. /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/index.js +0 -0
  708. /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/license +0 -0
  709. /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/package.json +0 -0
  710. /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/readme.md +0 -0
@@ -0,0 +1,1230 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import fsSync, { constants as fsConstants } from "node:fs";
3
+ import fs from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { normalizeMaxBytes } from "./byte-budget.js";
6
+ import { assertAsyncDirectoryGuard, createAsyncDirectoryGuard, createNearestExistingDirectoryGuard } from "./directory-guard.js";
7
+ import { FsSafeError } from "./errors.js";
8
+ import { syncDirectoryBestEffort } from "./directory-durability.js";
9
+ import { sameFileIdentity, sameFileIdentityForCleanup, } from "./file-identity.js";
10
+ import { mkdirPathComponentsWithGuards } from "./guarded-mkdir.js";
11
+ import { withAsyncDirectoryGuards } from "./guarded-mutation.js";
12
+ import { assertMutationNotDenied, mergeDenyMutationPolicies, } from "./deny-mutations.js";
13
+ import { resolveOpenedFileRealPathForFd, resolveOpenedFileRealPathForHandle } from "./opened-realpath.js";
14
+ import { openedPathResolutionError, recordExclusiveCreateFailure, recordFileOpenFailure, recordOpenedFileFailure, recordPreOpenFileChange } from "./opened-file-failure.js";
15
+ import { runPinnedWriteHelper, runPinnedWriteWithRenamePolicy, } from "./pinned-write.js";
16
+ import { getNativeBinding } from "./native.js";
17
+ import { validatePinnedOperationPayload } from "./pinned-operation.js";
18
+ import { assertNoPathAliasEscape, PATH_ALIAS_POLICIES } from "./path-policy.js";
19
+ import { assertNoNulPathInput, assertNoUnsafeDeviceReadPath, hasNodeErrorCode, isNotFoundPathError, isPathInside, isSymlinkOpenError, } from "./path.js";
20
+ import { readOpenedFileSafely } from "./read-opened-file.js";
21
+ import { resolveReadOpenFlags } from "./read-open-flags.js";
22
+ import { isNonRegularWriteOpenError, resolveNonblockingWriteFlag } from "./write-open-flags.js";
23
+ import { resolveRootPath } from "./root-path.js";
24
+ import { assertRootIdentityCurrent, assertValidRootDestinationPath, assertValidRootRelativePath, ensureTrailingSep, expandRelativePathWithHome, resolvePathInRoot, resolveRootContext, rootRelativeReadPath, } from "./root-context.js";
25
+ import { fileNotFoundError, hardlinkedPathNotAllowedError, isAlreadyExistsError, normalizePinnedPathError, normalizePinnedWriteError, normalizeRemoveGuardError, normalizeRemovePathError, outsideWorkspaceError, } from "./root-errors.js";
26
+ import { getFsSafeTestHooks } from "./test-hooks.js";
27
+ import { stringifyJsonDocument } from "./json-stringify.js";
28
+ import { walkRoot } from "./root-walk.js";
29
+ import { registerTempPathForExit } from "./temp-cleanup.js";
30
+ import { serializePathWrite } from "./write-queue.js";
31
+ import { verifyAtomicWriteResult } from "./root-write-verification.js";
32
+ import { inheritWriteTargetMode } from "./root-write-mode.js";
33
+ import { inspectFileIdentity } from "./strict-file-identity.js";
34
+ export { resolveOpenedFileRealPathForHandle } from "./opened-realpath.js";
35
+ function logWarn(message) {
36
+ if (process.env.FS_SAFE_DEBUG_WARNINGS === "1") {
37
+ console.warn(message);
38
+ }
39
+ }
40
+ const SUPPORTS_NOFOLLOW = process.platform !== "win32" && "O_NOFOLLOW" in fsConstants;
41
+ const OPEN_READ_FLAGS = resolveReadOpenFlags();
42
+ const OPEN_READ_FOLLOW_FLAGS = resolveReadOpenFlags({ followSymlinks: true });
43
+ const OPEN_WRITE_EXISTING_FLAGS = fsConstants.O_WRONLY | (SUPPORTS_NOFOLLOW ? fsConstants.O_NOFOLLOW : 0) |
44
+ resolveNonblockingWriteFlag();
45
+ const OPEN_WRITE_CREATE_FLAGS = fsConstants.O_WRONLY |
46
+ fsConstants.O_CREAT |
47
+ fsConstants.O_EXCL |
48
+ (SUPPORTS_NOFOLLOW ? fsConstants.O_NOFOLLOW : 0);
49
+ const OPEN_APPEND_EXISTING_FLAGS = fsConstants.O_RDWR | fsConstants.O_APPEND | (SUPPORTS_NOFOLLOW ? fsConstants.O_NOFOLLOW : 0) |
50
+ resolveNonblockingWriteFlag();
51
+ const OPEN_APPEND_CREATE_FLAGS = fsConstants.O_RDWR |
52
+ fsConstants.O_APPEND |
53
+ fsConstants.O_CREAT |
54
+ fsConstants.O_EXCL |
55
+ (SUPPORTS_NOFOLLOW ? fsConstants.O_NOFOLLOW : 0);
56
+ export const DEFAULT_ROOT_MAX_BYTES = 16 * 1024 * 1024;
57
+ function pathStatFromStats(stat) {
58
+ return {
59
+ dev: Number(stat.dev),
60
+ gid: Number(stat.gid),
61
+ ino: Number(stat.ino),
62
+ isDirectory: stat.isDirectory(),
63
+ isFile: stat.isFile(),
64
+ isSymbolicLink: stat.isSymbolicLink(),
65
+ mode: stat.mode,
66
+ mtimeMs: stat.mtimeMs,
67
+ nlink: stat.nlink,
68
+ size: stat.size,
69
+ uid: stat.uid,
70
+ };
71
+ }
72
+ function openResult(params) {
73
+ return {
74
+ handle: params.handle,
75
+ containment: "best-effort",
76
+ realPath: params.realPath,
77
+ stat: params.stat,
78
+ [Symbol.asyncDispose]: () => params.handle.close().catch(() => undefined),
79
+ };
80
+ }
81
+ async function openVerifiedLocalFile(filePath, options) {
82
+ assertNoUnsafeDeviceReadPath(filePath);
83
+ const fsSafeTestHooks = getFsSafeTestHooks();
84
+ let preOpenStat;
85
+ let observedBeforeOpen = false;
86
+ // Reject directories before opening so we never surface EISDIR to callers (e.g. tool
87
+ // results that get sent to messaging channels). See openclaw/openclaw#31186.
88
+ try {
89
+ preOpenStat = await inspectFileIdentity(async () => {
90
+ const stat = fsSync.lstatSync(filePath, { bigint: true });
91
+ observedBeforeOpen = true;
92
+ if (stat.isSymbolicLink() && options?.symlinks !== "follow-within-root") {
93
+ throw new FsSafeError("symlink", "symlink not allowed");
94
+ }
95
+ if (!stat.isFile() && !stat.isSymbolicLink()) {
96
+ throw new FsSafeError("not-file", "not a file");
97
+ }
98
+ return stat;
99
+ });
100
+ }
101
+ catch (err) {
102
+ if (err instanceof FsSafeError || observedBeforeOpen) {
103
+ throw err;
104
+ }
105
+ // Only an initial lookup failure falls through; a failed re-inspection aborts.
106
+ }
107
+ if (preOpenStat) {
108
+ await fsSafeTestHooks?.afterPreOpenLstat?.(filePath);
109
+ }
110
+ const openFlags = options?.symlinks === "follow-within-root"
111
+ ? OPEN_READ_FOLLOW_FLAGS
112
+ : OPEN_READ_FLAGS;
113
+ await fsSafeTestHooks?.beforeOpen?.(filePath, openFlags);
114
+ let handle;
115
+ try {
116
+ handle = await fs.open(filePath, openFlags).catch((error) => recordFileOpenFailure(isNotFoundPathError(error) ? fileNotFoundError() : error, filePath));
117
+ }
118
+ catch (err) {
119
+ if (isSymlinkOpenError(err)) {
120
+ throw new FsSafeError("symlink", "symlink open blocked", { cause: err });
121
+ }
122
+ // Defensive: if open still throws EISDIR (e.g. race), sanitize so it never leaks.
123
+ if (hasNodeErrorCode(err, "EISDIR")) {
124
+ throw new FsSafeError("not-file", "not a file");
125
+ }
126
+ throw err;
127
+ }
128
+ try {
129
+ await fsSafeTestHooks?.afterOpen?.(filePath, handle);
130
+ const stat = fsSync.fstatSync(handle.fd);
131
+ if (!stat.isFile()) {
132
+ throw new FsSafeError("not-file", "not a file");
133
+ }
134
+ // Keep numeric Stats for the public receipt, never for identity verification.
135
+ let openedIdentity;
136
+ const identity = await inspectFileIdentity(async () => (openedIdentity = fsSync.fstatSync(handle.fd, { bigint: true })), preOpenStat && !preOpenStat.isSymbolicLink() ? preOpenStat : undefined).catch(async (error) => {
137
+ if ([0, 1].includes(stat.nlink)) {
138
+ await recordPreOpenFileChange(error, handle, filePath, preOpenStat, openedIdentity);
139
+ }
140
+ throw error;
141
+ });
142
+ if (options?.hardlinks === "reject" && stat.nlink > 1) {
143
+ throw hardlinkedPathNotAllowedError();
144
+ }
145
+ const inspectPathIdentity = async (inspect) => {
146
+ try {
147
+ return await inspectFileIdentity(inspect, identity);
148
+ }
149
+ catch (error) {
150
+ const failure = isNotFoundPathError(error) ? openedPathResolutionError(fileNotFoundError()) : error;
151
+ if (stat.nlink <= 1 && (!preOpenStat || preOpenStat.nlink <= 1n)) {
152
+ await recordOpenedFileFailure(failure, handle, filePath, identity);
153
+ }
154
+ throw failure;
155
+ }
156
+ };
157
+ await inspectPathIdentity(async () => {
158
+ const pathStat = options?.symlinks === "follow-within-root"
159
+ ? fsSync.statSync(filePath, { bigint: true })
160
+ : fsSync.lstatSync(filePath, { bigint: true });
161
+ if (pathStat.isSymbolicLink() && options?.symlinks !== "follow-within-root") {
162
+ throw new FsSafeError("symlink", "symlink not allowed");
163
+ }
164
+ return pathStat;
165
+ });
166
+ await fsSafeTestHooks?.afterOpenedPathIdentityCheck?.(filePath, handle);
167
+ const resolved = await resolveOpenedFileRealPathForFd(handle.fd, identity, filePath)
168
+ .catch(async (error) => {
169
+ if (stat.nlink <= 1 && (!preOpenStat || preOpenStat.nlink <= 1n)) {
170
+ await recordOpenedFileFailure(error, handle, filePath, identity);
171
+ }
172
+ throw error;
173
+ });
174
+ const { realPath } = resolved;
175
+ let resolvedStat = resolved.stat;
176
+ await inspectPathIdentity(async () => {
177
+ // Reuse the post-realpath observation; unknown Windows identities still
178
+ // get a fresh observation on inspectFileIdentity's retry.
179
+ const realStat = resolvedStat ?? fsSync.statSync(realPath, { bigint: true });
180
+ resolvedStat = undefined;
181
+ if (options?.hardlinks === "reject" && realStat.nlink > 1n) {
182
+ throw hardlinkedPathNotAllowedError();
183
+ }
184
+ return realStat;
185
+ });
186
+ return { opened: openResult({ handle, realPath, stat }), identity };
187
+ }
188
+ catch (err) {
189
+ await handle.close().catch(() => { });
190
+ throw err;
191
+ }
192
+ }
193
+ export class RootHandle {
194
+ rootIdentity;
195
+ rootDir;
196
+ rootReal;
197
+ rootWithSep;
198
+ defaults;
199
+ constructor(context, defaults = {}) {
200
+ this.rootIdentity = context.rootIdentity;
201
+ this.rootDir = context.rootDir;
202
+ this.rootReal = context.rootReal;
203
+ this.rootWithSep = context.rootWithSep;
204
+ this.defaults = defaults;
205
+ }
206
+ get context() {
207
+ return {
208
+ rootDir: this.rootDir,
209
+ rootIdentity: this.rootIdentity,
210
+ rootReal: this.rootReal,
211
+ rootWithSep: this.rootWithSep,
212
+ };
213
+ }
214
+ mutationOptions(options) {
215
+ return {
216
+ ...options,
217
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
218
+ };
219
+ }
220
+ async resolve(relativePath) {
221
+ assertValidRootDestinationPath(relativePath);
222
+ return (await resolvePathInRoot(this.context, relativePath, { allowFinalSymlink: true })).resolved;
223
+ }
224
+ async open(relativePath, options = {}) {
225
+ return await openFileInRoot(this.context, {
226
+ relativePath,
227
+ ...readDefaults(this.defaults),
228
+ ...options,
229
+ });
230
+ }
231
+ async read(relativePath, options = {}) {
232
+ return await readFileInRoot(this.context, {
233
+ relativePath,
234
+ ...mergeReadOptions(this.defaults, options),
235
+ });
236
+ }
237
+ async readBytes(relativePath, options = {}) {
238
+ return (await this.read(relativePath, options)).buffer;
239
+ }
240
+ async readText(relativePath, options = {}) {
241
+ const { encoding = "utf8", ...readOptions } = options;
242
+ return (await this.read(relativePath, readOptions)).buffer.toString(encoding);
243
+ }
244
+ async readJson(relativePath, options = {}) {
245
+ return JSON.parse(await this.readText(relativePath, options));
246
+ }
247
+ async readAbsolute(filePath, options = {}) {
248
+ return await readPathInRoot(this.context, {
249
+ filePath,
250
+ ...mergeReadOptions(this.defaults, options),
251
+ });
252
+ }
253
+ reader(options = {}) {
254
+ return async (filePath) => {
255
+ return (await this.readAbsolute(filePath, options)).buffer;
256
+ };
257
+ }
258
+ async openWritable(relativePath, options = {}) {
259
+ assertValidRootDestinationPath(relativePath);
260
+ const writeMode = options.writeMode ?? "replace";
261
+ return await openWritableFileInRoot(this.context, {
262
+ relativePath,
263
+ mkdir: this.defaults.mkdir,
264
+ mode: this.defaults.mode,
265
+ ...this.mutationOptions(options),
266
+ append: writeMode === "append",
267
+ truncateExisting: writeMode === "replace",
268
+ });
269
+ }
270
+ async append(relativePath, data, options = {}) {
271
+ assertValidRootDestinationPath(relativePath);
272
+ await appendFileInRoot(this.context, {
273
+ relativePath,
274
+ data,
275
+ mkdir: this.defaults.mkdir,
276
+ mode: this.defaults.mode,
277
+ ...this.mutationOptions(options),
278
+ durable: options.durable ?? this.defaults.durable ?? true,
279
+ });
280
+ }
281
+ async remove(relativePath, options = {}) {
282
+ assertValidRootRelativePath(relativePath);
283
+ await removePathInRoot(this.context, {
284
+ relativePath,
285
+ ...this.mutationOptions(options),
286
+ });
287
+ }
288
+ async mkdir(relativePath, options = {}) {
289
+ assertValidRootDestinationPath(relativePath);
290
+ await mkdirPathInRoot(this.context, {
291
+ relativePath,
292
+ ...this.mutationOptions(options),
293
+ });
294
+ }
295
+ async ensureRoot(options = {}) {
296
+ await mkdirPathInRoot(this.context, {
297
+ relativePath: "",
298
+ allowRoot: true,
299
+ ...this.mutationOptions(options),
300
+ });
301
+ }
302
+ async write(relativePath, data, options = {}) {
303
+ assertValidRootDestinationPath(relativePath);
304
+ await writeFileInRoot(this.context, {
305
+ relativePath,
306
+ data,
307
+ mkdir: this.defaults.mkdir,
308
+ mode: this.defaults.mode,
309
+ renameIdentity: this.defaults.renameIdentity,
310
+ ...this.mutationOptions(options),
311
+ durable: options.durable ?? this.defaults.durable ?? true,
312
+ });
313
+ }
314
+ async create(relativePath, data, options = {}) {
315
+ assertValidRootDestinationPath(relativePath);
316
+ await writeFileInRoot(this.context, {
317
+ relativePath,
318
+ data,
319
+ mkdir: this.defaults.mkdir,
320
+ mode: this.defaults.mode,
321
+ ...this.mutationOptions(options),
322
+ durable: options.durable ?? this.defaults.durable ?? true,
323
+ overwrite: false,
324
+ });
325
+ }
326
+ async writeJson(relativePath, data, options = {}) {
327
+ const { replacer, space, trailingNewline = true, ...writeOptions } = options;
328
+ const json = stringifyJsonDocument(data, replacer, space);
329
+ await this.write(relativePath, trailingNewline ? `${json}\n` : json, writeOptions);
330
+ }
331
+ async createJson(relativePath, data, options = {}) {
332
+ const { replacer, space, trailingNewline = true, ...writeOptions } = options;
333
+ const json = stringifyJsonDocument(data, replacer, space);
334
+ await this.create(relativePath, trailingNewline ? `${json}\n` : json, writeOptions);
335
+ }
336
+ async copyIn(relativePath, sourcePath, options = {}) {
337
+ assertValidRootDestinationPath(relativePath);
338
+ const { maxBytes, ...copyOptions } = this.mutationOptions(options);
339
+ await copyFileInRoot(this.context, {
340
+ sourcePath,
341
+ relativePath,
342
+ maxBytes: normalizeMaxBytes(maxBytes, { defaultValue: this.defaults.maxBytes }),
343
+ mkdir: this.defaults.mkdir,
344
+ mode: this.defaults.mode,
345
+ ...copyOptions,
346
+ });
347
+ }
348
+ async exists(relativePath) {
349
+ try {
350
+ await this.stat(relativePath);
351
+ return true;
352
+ }
353
+ catch (err) {
354
+ if (err instanceof FsSafeError && err.code === "not-found") {
355
+ return false;
356
+ }
357
+ throw err;
358
+ }
359
+ }
360
+ async stat(relativePath) {
361
+ assertValidRootRelativePath(relativePath);
362
+ validatePinnedOperationPayload({ relativePath });
363
+ return await statPathFallback(this.context, relativePath);
364
+ }
365
+ async list(relativePath, options = {}) {
366
+ assertValidRootRelativePath(relativePath);
367
+ validatePinnedOperationPayload({ relativePath });
368
+ return await listPathFallback(this.context, relativePath, options.withFileTypes === true);
369
+ }
370
+ async move(fromRelative, toRelative, options = {}) {
371
+ assertValidRootRelativePath(fromRelative);
372
+ assertValidRootDestinationPath(toRelative);
373
+ validatePinnedOperationPayload({ from: fromRelative, to: toRelative });
374
+ const { denyMutations } = this.mutationOptions(options);
375
+ await assertMoveMutationAllowed(this.context, {
376
+ fromRelative,
377
+ toRelative,
378
+ denyMutations,
379
+ });
380
+ await movePathFallback(this.context, {
381
+ fromRelative,
382
+ denyMutations,
383
+ overwrite: options.overwrite ?? false,
384
+ toRelative,
385
+ });
386
+ }
387
+ walk(relativePath, options) {
388
+ assertValidRootRelativePath(relativePath);
389
+ return walkRoot(this, relativePath, options);
390
+ }
391
+ }
392
+ function readDefaults(defaults) {
393
+ return {
394
+ hardlinks: defaults.hardlinks,
395
+ maxBytes: normalizeMaxBytes(defaults.maxBytes, { defaultValue: DEFAULT_ROOT_MAX_BYTES }),
396
+ symlinks: defaults.symlinks,
397
+ };
398
+ }
399
+ function mergeReadOptions(defaults, options) {
400
+ const merged = readDefaults(defaults);
401
+ if (options.hardlinks !== undefined)
402
+ merged.hardlinks = options.hardlinks;
403
+ merged.maxBytes = normalizeMaxBytes(options.maxBytes, { defaultValue: merged.maxBytes });
404
+ if (options.symlinks !== undefined)
405
+ merged.symlinks = options.symlinks;
406
+ return merged;
407
+ }
408
+ export async function root(rootDir, defaults = {}) {
409
+ normalizeMaxBytes(defaults.maxBytes);
410
+ return new RootHandle(await resolveRootContext(rootDir), defaults);
411
+ }
412
+ async function openFileInRoot(root, params) {
413
+ const { rootWithSep, resolved } = await resolvePathInRoot(root, params.relativePath, {
414
+ allowFinalSymlink: true,
415
+ rejectUnsafeDeviceReads: true,
416
+ rejectSymlinks: params.symlinks !== "follow-within-root",
417
+ });
418
+ const { opened } = await openVerifiedLocalFile(resolved, {
419
+ symlinks: params.symlinks,
420
+ });
421
+ if (params.hardlinks !== "allow" && opened.stat.nlink > 1) {
422
+ await opened.handle.close().catch(() => { });
423
+ throw hardlinkedPathNotAllowedError();
424
+ }
425
+ if (!isPathInside(rootWithSep, opened.realPath)) {
426
+ await opened.handle.close().catch(() => { });
427
+ throw outsideWorkspaceError();
428
+ }
429
+ return opened;
430
+ }
431
+ async function readFileInRoot(root, params) {
432
+ const opened = await openFileInRoot(root, params);
433
+ try {
434
+ return await readOpenedFileSafely({ opened, maxBytes: params.maxBytes });
435
+ }
436
+ finally {
437
+ await opened.handle.close().catch(() => { });
438
+ }
439
+ }
440
+ async function readPathInRoot(root, params) {
441
+ const relativePath = rootRelativeReadPath(root, params.filePath);
442
+ return await readFileInRoot(root, {
443
+ relativePath,
444
+ hardlinks: params.hardlinks,
445
+ maxBytes: params.maxBytes,
446
+ symlinks: params.symlinks,
447
+ });
448
+ }
449
+ export async function readLocalFileSafely(params) {
450
+ const maxBytes = normalizeMaxBytes(params.maxBytes);
451
+ const opened = await openLocalFileSafely({ filePath: params.filePath });
452
+ try {
453
+ return await readOpenedFileSafely({ opened, maxBytes });
454
+ }
455
+ finally {
456
+ await opened.handle.close().catch(() => { });
457
+ }
458
+ }
459
+ export async function openLocalFileSafely(params) {
460
+ assertNoNulPathInput(params.filePath, "file path contains a NUL byte");
461
+ return (await openVerifiedLocalFile(params.filePath)).opened;
462
+ }
463
+ function emitWriteBoundaryWarning(reason) {
464
+ logWarn(`security: fs-safe write boundary warning (${reason})`);
465
+ }
466
+ function buildAtomicWriteTempPath(targetPath) {
467
+ return path.join(path.dirname(targetPath), `.fs-safe-${randomUUID()}.tmp`);
468
+ }
469
+ function rootWriteQueueKey(root, relativePath) {
470
+ return `${root.rootReal}\0${relativePath}`;
471
+ }
472
+ async function prepareRootWriteTarget(rootReal, targetPath) {
473
+ const parentPath = await mkdirPathComponentsWithGuards({
474
+ rootReal,
475
+ targetPath: path.dirname(targetPath),
476
+ });
477
+ // Continue through the guarded walk's real parent instead of re-entering
478
+ // the original path through a symlinked component.
479
+ return path.join(parentPath, path.basename(targetPath));
480
+ }
481
+ async function writeTempFileForAtomicReplace(params) {
482
+ const tempHandle = await fs.open(params.tempPath, OPEN_WRITE_CREATE_FLAGS, params.mode);
483
+ try {
484
+ if (typeof params.data === "string") {
485
+ await tempHandle.writeFile(params.data, params.encoding ?? "utf8");
486
+ }
487
+ else {
488
+ await tempHandle.writeFile(params.data);
489
+ }
490
+ return {
491
+ handle: tempHandle,
492
+ identity: fsSync.fstatSync(tempHandle.fd, { bigint: true }),
493
+ };
494
+ }
495
+ catch (error) {
496
+ await tempHandle.close().catch(() => { });
497
+ throw error;
498
+ }
499
+ }
500
+ async function resolveGuardedWritePathInRoot(root, params) {
501
+ const resolvedPath = await resolvePathInRoot(root, params.relativePath, {
502
+ aliasErrorCode: "path-alias",
503
+ allowFinalSymlink: params.allowFinalSymlink,
504
+ });
505
+ await assertMutationNotDenied(resolvedPath.resolved, params.denyMutations, params.protectDeniedAncestors ? { protectAncestors: true } : undefined);
506
+ if (await (params.shouldAssertNoPathAlias?.(resolvedPath) ?? true)) {
507
+ try {
508
+ await assertNoPathAliasEscape({
509
+ absolutePath: resolvedPath.resolved,
510
+ rootPath: resolvedPath.rootReal,
511
+ boundaryLabel: "root",
512
+ });
513
+ }
514
+ catch (error) {
515
+ throw new FsSafeError("path-alias", "path alias escape blocked", {
516
+ cause: error instanceof Error ? error : undefined,
517
+ });
518
+ }
519
+ }
520
+ return resolvedPath;
521
+ }
522
+ async function openWritableFileInRoot(root, params) {
523
+ const { rootReal, rootWithSep, resolved } = await resolveGuardedWritePathInRoot(root, {
524
+ relativePath: params.relativePath,
525
+ denyMutations: params.denyMutations,
526
+ });
527
+ let ioPath = params.mkdir === false
528
+ ? resolved
529
+ : await prepareRootWriteTarget(rootReal, resolved);
530
+ try {
531
+ const resolvedRealPath = fsSync.realpathSync.native(ioPath);
532
+ if (!isPathInside(rootWithSep, resolvedRealPath)) {
533
+ throw outsideWorkspaceError();
534
+ }
535
+ ioPath = resolvedRealPath;
536
+ }
537
+ catch (err) {
538
+ if (err instanceof FsSafeError) {
539
+ throw err;
540
+ }
541
+ if (!isNotFoundPathError(err)) {
542
+ throw err;
543
+ }
544
+ }
545
+ const mode = params.mode ?? 0o600;
546
+ let handle;
547
+ let createdForWrite = false;
548
+ const existingFlags = params.append ? OPEN_APPEND_EXISTING_FLAGS : OPEN_WRITE_EXISTING_FLAGS;
549
+ const createFlags = params.append ? OPEN_APPEND_CREATE_FLAGS : OPEN_WRITE_CREATE_FLAGS;
550
+ try {
551
+ try {
552
+ handle = await fs.open(ioPath, existingFlags, mode);
553
+ }
554
+ catch (err) {
555
+ if (await isNonRegularWriteOpenError(err, ioPath, existingFlags)) {
556
+ throw new FsSafeError("not-file", "path is not a regular file under root");
557
+ }
558
+ if (!isNotFoundPathError(err)) {
559
+ throw err;
560
+ }
561
+ handle = await fs.open(ioPath, createFlags, mode);
562
+ createdForWrite = true;
563
+ }
564
+ }
565
+ catch (err) {
566
+ if (isNotFoundPathError(err)) {
567
+ throw fileNotFoundError();
568
+ }
569
+ if (isSymlinkOpenError(err)) {
570
+ throw new FsSafeError("symlink", "symlink open blocked", { cause: err });
571
+ }
572
+ if (hasNodeErrorCode(err, "EISDIR")) {
573
+ throw new FsSafeError("not-file", "not a file", { cause: err });
574
+ }
575
+ throw err;
576
+ }
577
+ let realPathForCleanup = null;
578
+ let createdIdentity = null;
579
+ try {
580
+ const stat = fsSync.fstatSync(handle.fd);
581
+ if (createdForWrite) {
582
+ createdIdentity = stat;
583
+ }
584
+ if (!stat.isFile()) {
585
+ throw new FsSafeError("not-file", "path is not a regular file under root");
586
+ }
587
+ if (stat.nlink > 1) {
588
+ throw hardlinkedPathNotAllowedError();
589
+ }
590
+ try {
591
+ const lstat = fsSync.lstatSync(ioPath);
592
+ if (lstat.isSymbolicLink() || !lstat.isFile()) {
593
+ throw new FsSafeError(lstat.isSymbolicLink() ? "symlink" : "not-file", "path is not a regular file under root");
594
+ }
595
+ if (!sameFileIdentity(stat, lstat)) {
596
+ throw new FsSafeError("path-mismatch", "path changed during write");
597
+ }
598
+ }
599
+ catch (err) {
600
+ if (!isNotFoundPathError(err)) {
601
+ throw err;
602
+ }
603
+ }
604
+ const realPath = await resolveOpenedFileRealPathForHandle(handle, ioPath);
605
+ realPathForCleanup = realPath;
606
+ const realStat = fsSync.statSync(realPath);
607
+ if (!sameFileIdentity(stat, realStat)) {
608
+ throw new FsSafeError("path-mismatch", "path mismatch");
609
+ }
610
+ if (realStat.nlink > 1) {
611
+ throw hardlinkedPathNotAllowedError();
612
+ }
613
+ if (!isPathInside(rootWithSep, realPath)) {
614
+ throw outsideWorkspaceError();
615
+ }
616
+ // Truncate only after boundary and identity checks complete. This avoids
617
+ // irreversible side effects if a symlink target changes before validation.
618
+ if (params.append !== true && params.truncateExisting !== false && !createdForWrite) {
619
+ await handle.truncate(0);
620
+ }
621
+ return {
622
+ handle,
623
+ containment: "best-effort",
624
+ createdForWrite,
625
+ realPath,
626
+ stat,
627
+ [Symbol.asyncDispose]: () => handle.close().catch(() => undefined),
628
+ };
629
+ }
630
+ catch (err) {
631
+ const cleanupCreatedPath = createdForWrite && err instanceof FsSafeError;
632
+ const cleanupPath = realPathForCleanup ?? ioPath;
633
+ await handle.close().catch(() => { });
634
+ if (cleanupCreatedPath && createdIdentity) {
635
+ await removePathIfIdentityUnchanged(cleanupPath, createdIdentity).catch(() => { });
636
+ }
637
+ throw err;
638
+ }
639
+ }
640
+ async function appendFileInRoot(root, params) {
641
+ const target = await openWritableFileInRoot(root, {
642
+ relativePath: params.relativePath,
643
+ mkdir: params.mkdir,
644
+ mode: params.mode,
645
+ denyMutations: params.denyMutations,
646
+ truncateExisting: false,
647
+ append: true,
648
+ });
649
+ try {
650
+ let prefix = "";
651
+ if (params.prependNewlineIfNeeded === true &&
652
+ !target.createdForWrite &&
653
+ target.stat.size > 0 &&
654
+ ((typeof params.data === "string" && !params.data.startsWith("\n")) ||
655
+ (Buffer.isBuffer(params.data) && params.data.length > 0 && params.data[0] !== 0x0a))) {
656
+ const lastByte = Buffer.alloc(1);
657
+ const { bytesRead } = await target.handle.read(lastByte, 0, 1, target.stat.size - 1);
658
+ if (bytesRead === 1 && lastByte[0] !== 0x0a) {
659
+ prefix = "\n";
660
+ }
661
+ }
662
+ if (typeof params.data === "string") {
663
+ await target.handle.appendFile(`${prefix}${params.data}`, params.encoding ?? "utf8");
664
+ }
665
+ else {
666
+ const payload = prefix.length > 0 ? Buffer.concat([Buffer.from(prefix, "utf8"), params.data]) : params.data;
667
+ await target.handle.appendFile(payload);
668
+ }
669
+ if (params.durable !== false)
670
+ await target.handle.sync();
671
+ if (params.durable !== false && target.createdForWrite) {
672
+ await syncDirectoryBestEffort(path.dirname(target.realPath));
673
+ }
674
+ }
675
+ finally {
676
+ await target.handle.close().catch(() => { });
677
+ }
678
+ }
679
+ async function removePathInRoot(root, params) {
680
+ validatePinnedOperationPayload({ relativePath: params.relativePath });
681
+ const resolved = await resolvePinnedPathInRoot(root, {
682
+ relativePath: params.relativePath,
683
+ denyMutations: params.denyMutations,
684
+ remove: true,
685
+ });
686
+ try {
687
+ await removePathFallback(resolved);
688
+ }
689
+ catch (error) {
690
+ throw normalizePinnedPathError(error);
691
+ }
692
+ }
693
+ async function mkdirPathInRoot(root, params) {
694
+ validatePinnedOperationPayload({ relativePath: params.relativePath });
695
+ const resolved = await resolvePinnedPathInRoot(root, params);
696
+ try {
697
+ await mkdirPathFallback(resolved);
698
+ }
699
+ catch (error) {
700
+ throw normalizePinnedPathError(error);
701
+ }
702
+ }
703
+ async function writeFileInRoot(root, params) {
704
+ await serializePathWrite(rootWriteQueueKey(root, params.relativePath), async () => {
705
+ if (process.platform === "win32" &&
706
+ (params.renameIdentity === "verify-content-with-lock" || !getNativeBinding())) {
707
+ await writeFileFallback(root, params);
708
+ return;
709
+ }
710
+ const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations, params.overwrite);
711
+ await serializePathWrite(pinned.targetPath, async () => {
712
+ await commitPinnedWriteInRoot(root, pinned, params);
713
+ });
714
+ });
715
+ }
716
+ async function commitPinnedWriteInRoot(root, pinned, params) {
717
+ let verifyingPublication = false;
718
+ try {
719
+ await runPinnedWriteWithRenamePolicy({
720
+ rootPath: pinned.rootReal,
721
+ relativeParentPath: pinned.relativeParentPath,
722
+ basename: pinned.basename,
723
+ targetPath: pinned.targetPath,
724
+ renameIdentity: params.renameIdentity,
725
+ mkdir: params.mkdir !== false,
726
+ mode: params.mode ?? pinned.mode,
727
+ sync: params.durable !== false,
728
+ overwrite: params.overwrite,
729
+ input: { kind: "buffer", data: params.data, encoding: params.encoding },
730
+ rootIdentity: root.rootIdentity,
731
+ verifyPublished: async (fd, expectedIdentity, parentGuard) => {
732
+ verifyingPublication = true;
733
+ try {
734
+ await verifyAtomicWriteResult({
735
+ root,
736
+ targetPath: pinned.targetPath,
737
+ fd,
738
+ expectedIdentity,
739
+ parentGuard,
740
+ });
741
+ }
742
+ catch (error) {
743
+ emitWriteBoundaryWarning(`post-write verification failed: ${String(error)}`);
744
+ throw error;
745
+ }
746
+ },
747
+ });
748
+ }
749
+ catch (error) {
750
+ if (verifyingPublication)
751
+ throw error;
752
+ const errorCode = error?.code;
753
+ if (errorCode === "file_lock_stale" || errorCode === "file_lock_timeout") {
754
+ throw error;
755
+ }
756
+ if (params.overwrite === false && isAlreadyExistsError(error)) {
757
+ throw new FsSafeError("already-exists", "file already exists", {
758
+ cause: error instanceof Error ? error : undefined,
759
+ });
760
+ }
761
+ throw normalizePinnedWriteError(error);
762
+ }
763
+ }
764
+ async function copyFileInRoot(root, params) {
765
+ assertValidRootRelativePath(params.relativePath);
766
+ assertNoNulPathInput(params.sourcePath, "source path contains a NUL byte");
767
+ const { opened: source, identity: sourceIdentity } = await openVerifiedLocalFile(params.sourcePath, {
768
+ hardlinks: params.sourceHardlinks,
769
+ });
770
+ if (params.maxBytes !== undefined && source.stat.size > params.maxBytes) {
771
+ await source.handle.close().catch(() => { });
772
+ throw new FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${source.stat.size})`);
773
+ }
774
+ try {
775
+ await serializePathWrite(rootWriteQueueKey(root, params.relativePath), async () => {
776
+ const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
777
+ await serializePathWrite(pinned.targetPath, async () => {
778
+ await assertCopySourceCurrent(source, sourceIdentity);
779
+ let identity;
780
+ try {
781
+ identity = await runPinnedWriteHelper({
782
+ rootPath: pinned.rootReal,
783
+ relativeParentPath: pinned.relativeParentPath,
784
+ basename: pinned.basename,
785
+ mkdir: params.mkdir !== false,
786
+ mode: pinned.mode,
787
+ overwrite: true,
788
+ maxBytes: params.maxBytes,
789
+ input: { kind: "stream", stream: source.handle.createReadStream() },
790
+ rootIdentity: root.rootIdentity,
791
+ });
792
+ }
793
+ catch (error) {
794
+ throw normalizePinnedWriteError(error);
795
+ }
796
+ try {
797
+ await assertCopySourcePathCurrent(source, sourceIdentity);
798
+ }
799
+ catch (error) {
800
+ await removePathIfIdentityUnchanged(pinned.targetPath, identity).catch(() => undefined);
801
+ throw error;
802
+ }
803
+ });
804
+ });
805
+ }
806
+ finally {
807
+ await source.handle.close().catch(() => { });
808
+ }
809
+ }
810
+ async function assertCopySourceCurrent(source, identity) {
811
+ await inspectFileIdentity(() => fsSync.fstatSync(source.handle.fd, { bigint: true }), identity);
812
+ await assertCopySourcePathCurrent(source, identity);
813
+ }
814
+ async function assertCopySourcePathCurrent(source, identity) {
815
+ await inspectFileIdentity(async () => {
816
+ const current = fsSync.lstatSync(source.realPath, { bigint: true });
817
+ if (current.isSymbolicLink() || !current.isFile()) {
818
+ throw new FsSafeError("path-mismatch", "copy source path changed");
819
+ }
820
+ return current;
821
+ }, identity);
822
+ }
823
+ async function removePathIfIdentityUnchanged(targetPath, identity) {
824
+ const parentGuard = await createAsyncDirectoryGuard(path.dirname(targetPath));
825
+ const current = fsSync.lstatSync(targetPath);
826
+ if (current.isSymbolicLink() || !sameFileIdentityForCleanup(current, identity)) {
827
+ return;
828
+ }
829
+ await withAsyncDirectoryGuards([parentGuard], async () => {
830
+ await fs.rm(targetPath);
831
+ });
832
+ }
833
+ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode, denyMutations, overwrite = true) {
834
+ const { rootReal, rootWithSep, resolved } = await resolveGuardedWritePathInRoot(root, {
835
+ relativePath,
836
+ denyMutations,
837
+ });
838
+ // resolvePathInRoot already enforces isPathInside, so any actual escape
839
+ // is rejected upstream.
840
+ const relativeResolved = path.relative(rootReal, resolved);
841
+ if (path.isAbsolute(relativeResolved)) {
842
+ throw outsideWorkspaceError();
843
+ }
844
+ const relativePosix = relativeResolved
845
+ ? relativeResolved.split(path.sep).join(path.posix.sep)
846
+ : "";
847
+ const basename = path.posix.basename(relativePosix);
848
+ if (!basename || basename === "." || basename === "/") {
849
+ throw new FsSafeError("invalid-path", "invalid target path");
850
+ }
851
+ // Exclusive publication cannot inherit an existing file's mode. Keep type
852
+ // and alias checks, but never open a competing owner's record just to reject it.
853
+ if (!overwrite) {
854
+ try {
855
+ const existing = fsSync.statSync(resolved);
856
+ if (!existing.isFile())
857
+ throw new FsSafeError("not-file", "not a file");
858
+ if (existing.nlink > 1)
859
+ throw hardlinkedPathNotAllowedError();
860
+ throw new FsSafeError("already-exists", "file already exists");
861
+ }
862
+ catch (error) {
863
+ if (!isNotFoundPathError(error))
864
+ throw error;
865
+ }
866
+ }
867
+ const mode = overwrite
868
+ ? await inheritWriteTargetMode({ targetPath: resolved, rootWithSep, requestedMode })
869
+ : requestedMode ?? 0o600;
870
+ return {
871
+ rootReal,
872
+ targetPath: resolved,
873
+ relativeParentPath: path.posix.dirname(relativePosix) === "." ? "" : path.posix.dirname(relativePosix),
874
+ basename,
875
+ mode,
876
+ };
877
+ }
878
+ async function resolvePinnedPathInRoot(root, params) {
879
+ return await resolvePinnedOperationPathInRoot(root, {
880
+ allowRoot: params.allowRoot,
881
+ denyMutations: params.denyMutations,
882
+ protectDenyMutationAncestors: params.remove === true,
883
+ relativePath: params.relativePath,
884
+ policy: params.remove ? PATH_ALIAS_POLICIES.unlinkTarget : PATH_ALIAS_POLICIES.strict,
885
+ });
886
+ }
887
+ async function resolvePinnedOperationPathInRoot(root, params) {
888
+ const resolved = await resolvePinnedRootPathInRoot(root, {
889
+ relativePath: params.relativePath,
890
+ policy: params.policy,
891
+ });
892
+ const relativeResolved = path.relative(resolved.rootReal, resolved.canonicalPath);
893
+ if ((relativeResolved === "" || relativeResolved === ".") && params.allowRoot === true) {
894
+ await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations);
895
+ return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix: "" };
896
+ }
897
+ const firstSegment = relativeResolved.split(path.sep)[0];
898
+ if (relativeResolved === "" ||
899
+ relativeResolved === "." ||
900
+ firstSegment === ".." ||
901
+ path.isAbsolute(relativeResolved)) {
902
+ throw outsideWorkspaceError();
903
+ }
904
+ const relativePosix = relativeResolved.split(path.sep).join(path.posix.sep);
905
+ if (!isPathInside(resolved.rootWithSep, resolved.canonicalPath)) {
906
+ throw outsideWorkspaceError();
907
+ }
908
+ await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations, {
909
+ protectAncestors: params.protectDenyMutationAncestors,
910
+ });
911
+ return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix };
912
+ }
913
+ async function resolvePinnedRootPathInRoot(root, params) {
914
+ await assertRootIdentityCurrent(root);
915
+ const rootReal = root.rootReal;
916
+ let resolved;
917
+ try {
918
+ const expandedPath = await expandRelativePathWithHome(params.relativePath);
919
+ resolved = await resolveRootPath({
920
+ absolutePath: path.isAbsolute(expandedPath)
921
+ ? expandedPath
922
+ : `${ensureTrailingSep(rootReal)}${expandedPath}`,
923
+ rootPath: rootReal,
924
+ rootCanonicalPath: rootReal,
925
+ boundaryLabel: "root",
926
+ policy: params.policy,
927
+ });
928
+ }
929
+ catch (err) {
930
+ throw new FsSafeError("path-alias", "path alias escape blocked", { cause: err });
931
+ }
932
+ const rootWithSep = ensureTrailingSep(resolved.rootCanonicalPath);
933
+ return {
934
+ rootReal: resolved.rootCanonicalPath,
935
+ rootWithSep,
936
+ canonicalPath: resolved.canonicalPath,
937
+ };
938
+ }
939
+ async function prepareRemoveGuard(targetPath) {
940
+ try {
941
+ const guard = await createAsyncDirectoryGuard(path.dirname(targetPath));
942
+ await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("remove", targetPath);
943
+ await assertAsyncDirectoryGuard(guard);
944
+ return guard;
945
+ }
946
+ catch (error) {
947
+ throw normalizeRemoveGuardError(error);
948
+ }
949
+ }
950
+ async function removePathFallback(resolved) {
951
+ const guard = await prepareRemoveGuard(resolved.resolved);
952
+ try {
953
+ await (fsSync.lstatSync(resolved.resolved).isDirectory() ? fs.rmdir(resolved.resolved) : fs.rm(resolved.resolved));
954
+ }
955
+ catch (error) {
956
+ throw normalizeRemovePathError(error);
957
+ }
958
+ await assertAsyncDirectoryGuard(guard).catch(() => undefined);
959
+ }
960
+ async function mkdirPathFallback(resolved) {
961
+ await mkdirPathComponentsWithGuards({
962
+ rootReal: resolved.rootReal, targetPath: resolved.resolved,
963
+ beforeComponent: async (componentPath) => await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("mkdir", componentPath),
964
+ });
965
+ }
966
+ async function statPathFallback(root, relativePath) {
967
+ const resolved = await resolvePinnedPathInRoot(root, { relativePath, allowRoot: true });
968
+ try {
969
+ const stat = pathStatFromStats(fsSync.lstatSync(resolved.resolved));
970
+ await assertRootIdentityCurrent(root);
971
+ return stat;
972
+ }
973
+ catch (error) {
974
+ if (isNotFoundPathError(error)) {
975
+ throw fileNotFoundError(error instanceof Error ? error : undefined);
976
+ }
977
+ throw error;
978
+ }
979
+ }
980
+ async function listPathFallback(root, relativePath, withFileTypes) {
981
+ const resolved = await resolvePinnedPathInRoot(root, { relativePath, allowRoot: true });
982
+ try {
983
+ const names = await fs.readdir(resolved.resolved);
984
+ const sortedNames = names.toSorted();
985
+ if (!withFileTypes) {
986
+ await assertRootIdentityCurrent(root);
987
+ return sortedNames;
988
+ }
989
+ const entries = [];
990
+ for (const name of sortedNames) {
991
+ entries.push({
992
+ name,
993
+ ...pathStatFromStats(fsSync.lstatSync(path.join(resolved.resolved, name))),
994
+ });
995
+ }
996
+ await assertRootIdentityCurrent(root);
997
+ return entries;
998
+ }
999
+ catch (error) {
1000
+ if (isNotFoundPathError(error)) {
1001
+ throw new FsSafeError("not-found", "directory not found", {
1002
+ cause: error instanceof Error ? error : undefined,
1003
+ });
1004
+ }
1005
+ throw error;
1006
+ }
1007
+ }
1008
+ async function assertMoveMutationAllowed(root, params) {
1009
+ // Keep this preflight separate from the pinned resolutions in movePathFallback:
1010
+ // mutation denials must take precedence over source alias or identity failures.
1011
+ const source = await resolvePathInRoot(root, params.fromRelative, {
1012
+ aliasErrorCode: "path-alias",
1013
+ allowFinalSymlink: true,
1014
+ });
1015
+ await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
1016
+ const target = await resolvePathInRoot(root, params.toRelative, {
1017
+ aliasErrorCode: "path-alias",
1018
+ allowFinalSymlink: true,
1019
+ });
1020
+ await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
1021
+ }
1022
+ async function movePathFallback(root, params) {
1023
+ const source = await resolvePathInRoot(root, params.fromRelative, {
1024
+ aliasErrorCode: "path-alias",
1025
+ allowFinalSymlink: true,
1026
+ });
1027
+ await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
1028
+ await resolvePinnedRootPathInRoot(root, {
1029
+ relativePath: params.fromRelative,
1030
+ policy: PATH_ALIAS_POLICIES.strict,
1031
+ });
1032
+ const target = await resolveGuardedWritePathInRoot(root, {
1033
+ relativePath: params.toRelative,
1034
+ denyMutations: params.denyMutations,
1035
+ allowFinalSymlink: true,
1036
+ protectDeniedAncestors: true,
1037
+ shouldAssertNoPathAlias: async (resolvedTarget) => {
1038
+ await resolvePinnedRootPathInRoot(root, {
1039
+ relativePath: params.toRelative,
1040
+ policy: PATH_ALIAS_POLICIES.unlinkTarget,
1041
+ });
1042
+ let targetStat;
1043
+ try {
1044
+ targetStat = fsSync.lstatSync(resolvedTarget.resolved);
1045
+ }
1046
+ catch { /* Advisory lookup. */ }
1047
+ return !(process.platform !== "win32" &&
1048
+ params.overwrite &&
1049
+ targetStat?.isSymbolicLink() === true);
1050
+ },
1051
+ });
1052
+ let sourceStat;
1053
+ try {
1054
+ sourceStat = fsSync.lstatSync(source.resolved);
1055
+ }
1056
+ catch (error) {
1057
+ if (isNotFoundPathError(error)) {
1058
+ throw fileNotFoundError(error instanceof Error ? error : undefined);
1059
+ }
1060
+ throw error;
1061
+ }
1062
+ if (sourceStat.isSymbolicLink()) {
1063
+ throw new FsSafeError("symlink", "symlink not allowed");
1064
+ }
1065
+ if (sourceStat.isFile() && sourceStat.nlink > 1) {
1066
+ throw hardlinkedPathNotAllowedError();
1067
+ }
1068
+ if (!params.overwrite && sourceStat.isDirectory()) {
1069
+ throw new FsSafeError("invalid-path", "directory moves require overwrite: true");
1070
+ }
1071
+ if (!params.overwrite) {
1072
+ try {
1073
+ fsSync.lstatSync(target.resolved);
1074
+ throw new FsSafeError("already-exists", "destination exists");
1075
+ }
1076
+ catch (error) {
1077
+ if (error instanceof FsSafeError) {
1078
+ throw error;
1079
+ }
1080
+ if (!isNotFoundPathError(error)) {
1081
+ throw error;
1082
+ }
1083
+ }
1084
+ }
1085
+ const sourceParentGuard = await createAsyncDirectoryGuard(path.dirname(source.resolved));
1086
+ const targetParentGuard = await createNearestExistingDirectoryGuard(target.rootReal, path.dirname(target.resolved));
1087
+ await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("move", target.resolved);
1088
+ await assertAsyncDirectoryGuard(sourceParentGuard);
1089
+ await assertAsyncDirectoryGuard(targetParentGuard);
1090
+ try {
1091
+ await fs.rename(source.resolved, target.resolved);
1092
+ }
1093
+ catch (error) {
1094
+ if (isNotFoundPathError(error)) {
1095
+ throw fileNotFoundError(error instanceof Error ? error : undefined);
1096
+ }
1097
+ if (hasNodeErrorCode(error, "EEXIST")) {
1098
+ throw new FsSafeError("already-exists", "destination exists", {
1099
+ cause: error instanceof Error ? error : undefined,
1100
+ });
1101
+ }
1102
+ throw error;
1103
+ }
1104
+ await assertAsyncDirectoryGuard(targetParentGuard).catch(() => undefined);
1105
+ }
1106
+ async function writeFileFallback(root, params) {
1107
+ if (params.overwrite === false) {
1108
+ await writeMissingFileFallback(root, params);
1109
+ return;
1110
+ }
1111
+ const target = await openWritableFileInRoot(root, {
1112
+ relativePath: params.relativePath,
1113
+ mkdir: params.mkdir,
1114
+ mode: params.mode,
1115
+ denyMutations: params.denyMutations,
1116
+ truncateExisting: false,
1117
+ });
1118
+ const destinationPath = target.realPath;
1119
+ const mode = params.mode ?? (target.stat.mode & 0o777);
1120
+ await target.handle.close().catch(() => { });
1121
+ const destinationGuard = await createAsyncDirectoryGuard(path.dirname(destinationPath));
1122
+ let tempPath = null;
1123
+ let unregisterTempPath = null;
1124
+ let writtenHandle;
1125
+ try {
1126
+ tempPath = buildAtomicWriteTempPath(destinationPath);
1127
+ unregisterTempPath = registerTempPathForExit(tempPath);
1128
+ const written = await writeTempFileForAtomicReplace({
1129
+ tempPath,
1130
+ data: params.data,
1131
+ encoding: params.encoding,
1132
+ mode,
1133
+ });
1134
+ writtenHandle = written.handle;
1135
+ unregisterTempPath.setIdentity(written.identity);
1136
+ const commitTempPath = tempPath;
1137
+ await withAsyncDirectoryGuards([destinationGuard], async () => {
1138
+ await fs.rename(commitTempPath, destinationPath);
1139
+ tempPath = null;
1140
+ });
1141
+ unregisterTempPath();
1142
+ unregisterTempPath = null;
1143
+ try {
1144
+ await verifyAtomicWriteResult({
1145
+ root,
1146
+ targetPath: destinationPath,
1147
+ expectedIdentity: written.identity,
1148
+ fd: written.handle.fd,
1149
+ parentGuard: destinationGuard,
1150
+ });
1151
+ }
1152
+ catch (err) {
1153
+ emitWriteBoundaryWarning(`post-write verification failed: ${String(err)}`);
1154
+ throw err;
1155
+ }
1156
+ }
1157
+ finally {
1158
+ await writtenHandle?.close().catch(() => undefined);
1159
+ if (tempPath) {
1160
+ await fs.rm(tempPath, { force: true }).catch(() => { });
1161
+ }
1162
+ unregisterTempPath?.();
1163
+ }
1164
+ }
1165
+ async function writeMissingFileFallback(root, params) {
1166
+ const { rootReal, resolved } = await resolveGuardedWritePathInRoot(root, {
1167
+ relativePath: params.relativePath,
1168
+ denyMutations: params.denyMutations,
1169
+ });
1170
+ const targetPath = params.mkdir === false
1171
+ ? resolved
1172
+ : await prepareRootWriteTarget(rootReal, resolved);
1173
+ const parentGuard = await createAsyncDirectoryGuard(path.dirname(targetPath));
1174
+ let created = false;
1175
+ let createdIdentity;
1176
+ let writtenHandle;
1177
+ let verifyingPublication = false;
1178
+ try {
1179
+ const { handle, writtenStat } = await withAsyncDirectoryGuards([parentGuard], async () => {
1180
+ const handle = await fs.open(targetPath, OPEN_WRITE_CREATE_FLAGS, params.mode ?? 0o600).catch((error) => recordExclusiveCreateFailure(error, targetPath));
1181
+ created = true;
1182
+ try {
1183
+ createdIdentity = fsSync.fstatSync(handle.fd);
1184
+ const writtenStat = fsSync.fstatSync(handle.fd, { bigint: true });
1185
+ if (typeof params.data === "string") {
1186
+ await handle.writeFile(params.data, params.encoding ?? "utf8");
1187
+ }
1188
+ else {
1189
+ await handle.writeFile(params.data);
1190
+ }
1191
+ return { handle, writtenStat };
1192
+ }
1193
+ catch (error) {
1194
+ await handle.close().catch(() => undefined);
1195
+ throw error;
1196
+ }
1197
+ }, {
1198
+ onPostGuardFailure: async ({ handle }) => {
1199
+ created = false; // Parent is untrusted now; skip outer path cleanup by name.
1200
+ await handle.close().catch(() => undefined);
1201
+ },
1202
+ });
1203
+ writtenHandle = handle;
1204
+ created = false;
1205
+ verifyingPublication = true;
1206
+ await verifyAtomicWriteResult({
1207
+ root,
1208
+ targetPath,
1209
+ expectedIdentity: writtenStat,
1210
+ fd: handle.fd,
1211
+ parentGuard,
1212
+ });
1213
+ }
1214
+ catch (err) {
1215
+ if (verifyingPublication)
1216
+ throw err;
1217
+ if (hasNodeErrorCode(err, "EEXIST")) {
1218
+ throw new FsSafeError("already-exists", "file already exists", {
1219
+ cause: err instanceof Error ? err : undefined,
1220
+ });
1221
+ }
1222
+ throw err;
1223
+ }
1224
+ finally {
1225
+ await writtenHandle?.close().catch(() => undefined);
1226
+ if (created && createdIdentity) {
1227
+ await removePathIfIdentityUnchanged(targetPath, createdIdentity).catch(() => undefined);
1228
+ }
1229
+ }
1230
+ }