@openclaw/openshell-sandbox 2026.9.2 → 2026.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +87 -47
- package/node_modules/@openclaw/fs-safe/CHANGELOG.md +700 -0
- package/node_modules/@openclaw/fs-safe/LICENSE +21 -0
- package/node_modules/@openclaw/fs-safe/README.md +564 -0
- package/node_modules/@openclaw/fs-safe/SECURITY.md +45 -0
- package/node_modules/@openclaw/fs-safe/dist/absolute-path.d.ts +33 -0
- package/node_modules/@openclaw/fs-safe/dist/absolute-path.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/absolute-path.js +307 -0
- package/node_modules/@openclaw/fs-safe/dist/advanced.d.ts +26 -0
- package/node_modules/@openclaw/fs-safe/dist/advanced.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/advanced.js +28 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-crc32.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-crc32.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-crc32.js +14 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-deadline.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-deadline.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-deadline.js +103 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-entry.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-entry.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-entry.js +85 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-errors.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-errors.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-errors.js +23 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.d.ts +18 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-gzip-tail.js +74 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-input.d.ts +19 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-input.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-input.js +92 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-kind.d.ts +9 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-kind.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-kind.js +82 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-limits.d.ts +57 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-limits.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-limits.js +131 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-merge.d.ts +18 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-merge.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-merge.js +157 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-native.d.ts +20 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-native.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-native.js +107 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-options.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-options.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-options.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-parser-errors.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-parser-errors.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-parser-errors.js +12 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-parser.wasm +0 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-plan.d.ts +20 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-plan.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-plan.js +55 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-policy.d.ts +22 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-policy.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-policy.js +38 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-read.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-read.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-read.js +225 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-staging.d.ts +31 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-staging.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-staging.js +250 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-inspect.js +59 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.d.ts +18 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-stream.js +95 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.d.ts +18 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar-wasm.js +99 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar.d.ts +19 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-tar.js +21 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-admission.js +60 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-count.js +140 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-directory.js +228 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-entry.js +27 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-integrity.js +41 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-names.js +100 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive-zip-preflight.js +44 -0
- package/node_modules/@openclaw/fs-safe/dist/archive.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/archive.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/archive.js +275 -0
- package/node_modules/@openclaw/fs-safe/dist/async-lock.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/async-lock.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/async-lock.js +17 -0
- package/node_modules/@openclaw/fs-safe/dist/atomic.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/atomic.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/atomic.js +4 -0
- package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/bounded-read-stream.js +21 -0
- package/node_modules/@openclaw/fs-safe/dist/bounded-read.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/bounded-read.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/bounded-read.js +106 -0
- package/node_modules/@openclaw/fs-safe/dist/byte-budget.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/byte-budget.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/byte-budget.js +9 -0
- package/node_modules/@openclaw/fs-safe/dist/config.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/config.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/config.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/containment.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/containment.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/containment.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/deny-mutations.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/deny-mutations.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/deny-mutations.js +69 -0
- package/node_modules/@openclaw/fs-safe/dist/device-path.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/device-path.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/device-path.js +137 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-durability.d.ts +44 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-durability.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-durability.js +299 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-guard.d.ts +31 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-guard.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-guard.js +82 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-node.js +93 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/directory-mode-owner.js +78 -0
- package/node_modules/@openclaw/fs-safe/dist/durability.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/durability.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/durability.js +3 -0
- package/node_modules/@openclaw/fs-safe/dist/error-detail.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/error-detail.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/error-detail.js +10 -0
- package/node_modules/@openclaw/fs-safe/dist/errors.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/errors.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/errors.js +26 -0
- package/node_modules/@openclaw/fs-safe/dist/file-hash.d.ts +10 -0
- package/node_modules/@openclaw/fs-safe/dist/file-hash.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-hash.js +73 -0
- package/node_modules/@openclaw/fs-safe/dist/file-identity.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/file-identity.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-identity.js +34 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.d.ts +35 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock-sync.js +349 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock.d.ts +24 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-lock.js +46 -0
- package/node_modules/@openclaw/fs-safe/dist/file-observation.d.ts +9 -0
- package/node_modules/@openclaw/fs-safe/dist/file-observation.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-observation.js +22 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.d.ts +33 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-boundary.js +189 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-limit.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-limit.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-limit.js +8 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-prune.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-prune.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-prune.js +95 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.d.ts +9 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store-sync-write.js +127 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store.d.ts +62 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-store.js +357 -0
- package/node_modules/@openclaw/fs-safe/dist/file-sync.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/file-sync.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/file-sync.js +19 -0
- package/node_modules/@openclaw/fs-safe/dist/filename.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/filename.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/filename.js +91 -0
- package/node_modules/@openclaw/fs-safe/dist/fs.d.ts +13 -0
- package/node_modules/@openclaw/fs-safe/dist/fs.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/fs.js +30 -0
- package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/guarded-mkdir.js +87 -0
- package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.d.ts +37 -0
- package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/guarded-mutation.js +82 -0
- package/node_modules/@openclaw/fs-safe/dist/home-dir.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/home-dir.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/home-dir.js +84 -0
- package/node_modules/@openclaw/fs-safe/dist/index.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/index.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/index.js +5 -0
- package/node_modules/@openclaw/fs-safe/dist/install-path.d.ts +20 -0
- package/node_modules/@openclaw/fs-safe/dist/install-path.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/install-path.js +94 -0
- package/node_modules/@openclaw/fs-safe/dist/json-document-store.d.ts +35 -0
- package/node_modules/@openclaw/fs-safe/dist/json-document-store.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/json-document-store.js +97 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-directory.js +20 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.d.ts +17 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue-ownership.js +292 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.d.ts +46 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/json-durable-queue.js +383 -0
- package/node_modules/@openclaw/fs-safe/dist/json-store.d.ts +9 -0
- package/node_modules/@openclaw/fs-safe/dist/json-store.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/json-store.js +12 -0
- package/node_modules/@openclaw/fs-safe/dist/json-stringify.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/json-stringify.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/json-stringify.js +7 -0
- package/node_modules/@openclaw/fs-safe/dist/json.d.ts +50 -0
- package/node_modules/@openclaw/fs-safe/dist/json.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/json.js +343 -0
- package/node_modules/@openclaw/fs-safe/dist/local-file-access.d.ts +9 -0
- package/node_modules/@openclaw/fs-safe/dist/local-file-access.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/local-file-access.js +87 -0
- package/node_modules/@openclaw/fs-safe/dist/local-roots.d.ts +26 -0
- package/node_modules/@openclaw/fs-safe/dist/local-roots.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/local-roots.js +135 -0
- package/node_modules/@openclaw/fs-safe/dist/lock-config.d.ts +10 -0
- package/node_modules/@openclaw/fs-safe/dist/lock-config.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/lock-config.js +12 -0
- package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.d.ts +43 -0
- package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/move-path-cleanup.js +161 -0
- package/node_modules/@openclaw/fs-safe/dist/move-path.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/move-path.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/move-path.js +334 -0
- package/node_modules/@openclaw/fs-safe/dist/native-binding.d.ts +93 -0
- package/node_modules/@openclaw/fs-safe/dist/native-binding.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/native-binding.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/native-config.d.ts +17 -0
- package/node_modules/@openclaw/fs-safe/dist/native-config.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/native-config.js +71 -0
- package/node_modules/@openclaw/fs-safe/dist/native-operations.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/native-operations.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/native-operations.js +132 -0
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.js +96 -0
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/native-pinned-write.js +161 -0
- package/node_modules/@openclaw/fs-safe/dist/native-staged-file.d.ts +31 -0
- package/node_modules/@openclaw/fs-safe/dist/native-staged-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/native-staged-file.js +362 -0
- package/node_modules/@openclaw/fs-safe/dist/native.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/native.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/native.js +204 -0
- package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/opened-file-failure.js +45 -0
- package/node_modules/@openclaw/fs-safe/dist/opened-realpath.d.ts +16 -0
- package/node_modules/@openclaw/fs-safe/dist/opened-realpath.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/opened-realpath.js +92 -0
- package/node_modules/@openclaw/fs-safe/dist/output.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/output.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/output.js +123 -0
- package/node_modules/@openclaw/fs-safe/dist/owner-dacl.d.ts +31 -0
- package/node_modules/@openclaw/fs-safe/dist/owner-dacl.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/owner-dacl.js +28 -0
- package/node_modules/@openclaw/fs-safe/dist/path-policy.d.ts +25 -0
- package/node_modules/@openclaw/fs-safe/dist/path-policy.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/path-policy.js +44 -0
- package/node_modules/@openclaw/fs-safe/dist/path.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/path.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/path.js +136 -0
- package/node_modules/@openclaw/fs-safe/dist/permission-exec.d.ts +25 -0
- package/node_modules/@openclaw/fs-safe/dist/permission-exec.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/permission-exec.js +74 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions-public.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions-public.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions-public.js +3 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions-windows.d.ts +59 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions-windows.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions-windows.js +296 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions.d.ts +60 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/permissions.js +125 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-open.d.ts +24 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-open.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-open.js +74 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-operation.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-operation.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-operation.js +35 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write.d.ts +36 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/pinned-write.js +252 -0
- package/node_modules/@openclaw/fs-safe/dist/private-directory.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/private-directory.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/private-directory.js +14 -0
- package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.d.ts +45 -0
- package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/private-temp-workspace.js +299 -0
- package/node_modules/@openclaw/fs-safe/dist/publish-file-failure.d.ts +28 -0
- package/node_modules/@openclaw/fs-safe/dist/publish-file-failure.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/publish-file-failure.js +22 -0
- package/node_modules/@openclaw/fs-safe/dist/publish-file.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/publish-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/publish-file.js +366 -0
- package/node_modules/@openclaw/fs-safe/dist/read-open-flags.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/read-open-flags.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/read-open-flags.js +13 -0
- package/node_modules/@openclaw/fs-safe/dist/read-opened-file.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/read-opened-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/read-opened-file.js +18 -0
- package/node_modules/@openclaw/fs-safe/dist/regular-file.d.ts +38 -0
- package/node_modules/@openclaw/fs-safe/dist/regular-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/regular-file.js +391 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-directory.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-directory.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-directory.js +42 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.d.ts +39 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-fallback.js +331 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.d.ts +21 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-copy-source.js +107 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.d.ts +51 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-descriptor.js +161 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-rename-policy.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-rename-policy.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-rename-policy.js +30 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.d.ts +53 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.js +376 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file.d.ts +58 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/replace-file.js +329 -0
- package/node_modules/@openclaw/fs-safe/dist/root-context.d.ts +38 -0
- package/node_modules/@openclaw/fs-safe/dist/root-context.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-context.js +141 -0
- package/node_modules/@openclaw/fs-safe/dist/root-errors.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/root-errors.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-errors.js +75 -0
- package/node_modules/@openclaw/fs-safe/dist/root-file.d.ts +45 -0
- package/node_modules/@openclaw/fs-safe/dist/root-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-file.js +120 -0
- package/node_modules/@openclaw/fs-safe/dist/root-impl.d.ts +163 -0
- package/node_modules/@openclaw/fs-safe/dist/root-impl.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-impl.js +1230 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-existing.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-existing.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-existing.js +68 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.d.ts +7 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path-symlink.js +35 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path.d.ts +40 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-path.js +481 -0
- package/node_modules/@openclaw/fs-safe/dist/root-paths.d.ts +89 -0
- package/node_modules/@openclaw/fs-safe/dist/root-paths.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-paths.js +381 -0
- package/node_modules/@openclaw/fs-safe/dist/root-walk.d.ts +41 -0
- package/node_modules/@openclaw/fs-safe/dist/root-walk.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-walk.js +133 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-mode.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-mode.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-mode.js +61 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-verification.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-verification.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root-write-verification.js +97 -0
- package/node_modules/@openclaw/fs-safe/dist/root.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/root.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/root.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/safe-path-segment.js +75 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-file.d.ts +25 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-file.js +329 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-read-async.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-read-async.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-read-async.js +73 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.d.ts +17 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/secret-read-policy.js +40 -0
- package/node_modules/@openclaw/fs-safe/dist/secret.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/secret.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/secret.js +3 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-file.d.ts +32 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-file.js +182 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.d.ts +27 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/secure-temp-dir.js +160 -0
- package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.d.ts +15 -0
- package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sibling-staged-file.js +143 -0
- package/node_modules/@openclaw/fs-safe/dist/sibling-temp.d.ts +27 -0
- package/node_modules/@openclaw/fs-safe/dist/sibling-temp.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sibling-temp.js +95 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.d.ts +31 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-acquire.js +336 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.d.ts +24 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-handle.js +42 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.js +71 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.d.ts +63 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-reclaim.js +305 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.d.ts +3 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-root.js +76 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-types.d.ts +63 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-types.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock-types.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/sidecar-lock.js +265 -0
- package/node_modules/@openclaw/fs-safe/dist/staged-directory.d.ts +16 -0
- package/node_modules/@openclaw/fs-safe/dist/staged-directory.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/staged-directory.js +60 -0
- package/node_modules/@openclaw/fs-safe/dist/staged-file-types.d.ts +56 -0
- package/node_modules/@openclaw/fs-safe/dist/staged-file-types.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/staged-file-types.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/store.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/store.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/store.js +3 -0
- package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/strict-file-identity.js +51 -0
- package/node_modules/@openclaw/fs-safe/dist/string-coerce.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/string-coerce.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/string-coerce.js +16 -0
- package/node_modules/@openclaw/fs-safe/dist/suppressed-error.d.ts +6 -0
- package/node_modules/@openclaw/fs-safe/dist/suppressed-error.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/suppressed-error.js +15 -0
- package/node_modules/@openclaw/fs-safe/dist/symlink-parents.d.ts +12 -0
- package/node_modules/@openclaw/fs-safe/dist/symlink-parents.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/symlink-parents.js +78 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-cleanup.js +87 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-target.d.ts +28 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-target.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-target.js +137 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.d.ts +23 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/temp-workspace-owner.js +320 -0
- package/node_modules/@openclaw/fs-safe/dist/temp.d.ts +4 -0
- package/node_modules/@openclaw/fs-safe/dist/temp.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/temp.js +2 -0
- package/node_modules/@openclaw/fs-safe/dist/test-hooks.d.ts +25 -0
- package/node_modules/@openclaw/fs-safe/dist/test-hooks.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/test-hooks.js +13 -0
- package/node_modules/@openclaw/fs-safe/dist/text-atomic.d.ts +14 -0
- package/node_modules/@openclaw/fs-safe/dist/text-atomic.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/text-atomic.js +14 -0
- package/node_modules/@openclaw/fs-safe/dist/timing.d.ts +8 -0
- package/node_modules/@openclaw/fs-safe/dist/timing.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/timing.js +40 -0
- package/node_modules/@openclaw/fs-safe/dist/trash.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/trash.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/trash.js +171 -0
- package/node_modules/@openclaw/fs-safe/dist/types.d.ts +23 -0
- package/node_modules/@openclaw/fs-safe/dist/types.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/types.js +1 -0
- package/node_modules/@openclaw/fs-safe/dist/walk.d.ts +37 -0
- package/node_modules/@openclaw/fs-safe/dist/walk.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/walk.js +207 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-command.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-command.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-command.js +34 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-owner.d.ts +32 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-owner.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/windows-owner.js +126 -0
- package/node_modules/@openclaw/fs-safe/dist/write-open-flags.d.ts +5 -0
- package/node_modules/@openclaw/fs-safe/dist/write-open-flags.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/write-open-flags.js +35 -0
- package/node_modules/@openclaw/fs-safe/dist/write-queue.d.ts +2 -0
- package/node_modules/@openclaw/fs-safe/dist/write-queue.d.ts.map +1 -0
- package/node_modules/@openclaw/fs-safe/dist/write-queue.js +18 -0
- package/node_modules/@openclaw/fs-safe/docs/advanced.md +153 -0
- package/node_modules/@openclaw/fs-safe/docs/archive.md +658 -0
- package/node_modules/@openclaw/fs-safe/docs/assets/readme-banner.jpg +0 -0
- package/node_modules/@openclaw/fs-safe/docs/atomic.md +334 -0
- package/node_modules/@openclaw/fs-safe/docs/config.md +131 -0
- package/node_modules/@openclaw/fs-safe/docs/contributing.md +180 -0
- package/node_modules/@openclaw/fs-safe/docs/durability.md +313 -0
- package/node_modules/@openclaw/fs-safe/docs/errors.md +232 -0
- package/node_modules/@openclaw/fs-safe/docs/file-store.md +258 -0
- package/node_modules/@openclaw/fs-safe/docs/filename.md +96 -0
- package/node_modules/@openclaw/fs-safe/docs/index.md +84 -0
- package/node_modules/@openclaw/fs-safe/docs/install-path.md +170 -0
- package/node_modules/@openclaw/fs-safe/docs/install.md +163 -0
- package/node_modules/@openclaw/fs-safe/docs/json-store.md +221 -0
- package/node_modules/@openclaw/fs-safe/docs/json.md +213 -0
- package/node_modules/@openclaw/fs-safe/docs/local-roots.md +141 -0
- package/node_modules/@openclaw/fs-safe/docs/migrating-to-0.5.md +196 -0
- package/node_modules/@openclaw/fs-safe/docs/migrating-to-0.6.md +43 -0
- package/node_modules/@openclaw/fs-safe/docs/native-helper.md +118 -0
- package/node_modules/@openclaw/fs-safe/docs/native.md +196 -0
- package/node_modules/@openclaw/fs-safe/docs/output.md +139 -0
- package/node_modules/@openclaw/fs-safe/docs/path-scope.md +159 -0
- package/node_modules/@openclaw/fs-safe/docs/path.md +208 -0
- package/node_modules/@openclaw/fs-safe/docs/permissions.md +200 -0
- package/node_modules/@openclaw/fs-safe/docs/private-file-store.md +54 -0
- package/node_modules/@openclaw/fs-safe/docs/public-api.md +112 -0
- package/node_modules/@openclaw/fs-safe/docs/quickstart.md +154 -0
- package/node_modules/@openclaw/fs-safe/docs/reading.md +183 -0
- package/node_modules/@openclaw/fs-safe/docs/regular-file.md +190 -0
- package/node_modules/@openclaw/fs-safe/docs/root.md +266 -0
- package/node_modules/@openclaw/fs-safe/docs/secret-file.md +273 -0
- package/node_modules/@openclaw/fs-safe/docs/secure-file.md +100 -0
- package/node_modules/@openclaw/fs-safe/docs/security-model.md +188 -0
- package/node_modules/@openclaw/fs-safe/docs/sidecar-lock.md +439 -0
- package/node_modules/@openclaw/fs-safe/docs/staged-file.md +182 -0
- package/node_modules/@openclaw/fs-safe/docs/store.md +94 -0
- package/node_modules/@openclaw/fs-safe/docs/temp.md +476 -0
- package/node_modules/@openclaw/fs-safe/docs/test-hooks.md +96 -0
- package/node_modules/@openclaw/fs-safe/docs/testing.md +189 -0
- package/node_modules/@openclaw/fs-safe/docs/timing.md +121 -0
- package/node_modules/@openclaw/fs-safe/docs/types.md +188 -0
- package/node_modules/@openclaw/fs-safe/docs/walk.md +128 -0
- package/node_modules/@openclaw/fs-safe/docs/writing.md +347 -0
- package/node_modules/@openclaw/fs-safe/package.json +187 -0
- package/node_modules/@openclaw/fs-safe-darwin-arm64/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-darwin-arm64/package.json +29 -0
- package/node_modules/@openclaw/fs-safe-darwin-x64/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-darwin-x64/package.json +29 -0
- package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-arm64-gnu/package.json +32 -0
- package/node_modules/@openclaw/fs-safe-linux-arm64-musl/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-arm64-musl/package.json +32 -0
- package/node_modules/@openclaw/fs-safe-linux-x64-gnu/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-x64-gnu/package.json +32 -0
- package/node_modules/@openclaw/fs-safe-linux-x64-musl/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-linux-x64-musl/package.json +32 -0
- package/node_modules/@openclaw/fs-safe-win32-x64-msvc/fs-safe-native.node +0 -0
- package/node_modules/@openclaw/fs-safe-win32-x64-msvc/package.json +29 -0
- package/node_modules/core-util-is/LICENSE +19 -0
- package/node_modules/core-util-is/README.md +3 -0
- package/node_modules/core-util-is/lib/util.js +107 -0
- package/node_modules/core-util-is/package.json +38 -0
- package/node_modules/immediate/LICENSE.txt +20 -0
- package/node_modules/immediate/README.md +93 -0
- package/node_modules/immediate/dist/immediate.js +75 -0
- package/node_modules/immediate/dist/immediate.min.js +1 -0
- package/node_modules/immediate/lib/browser.js +69 -0
- package/node_modules/immediate/lib/index.js +73 -0
- package/node_modules/immediate/package.json +42 -0
- package/node_modules/inherits/LICENSE +16 -0
- package/node_modules/inherits/README.md +42 -0
- package/node_modules/inherits/inherits.js +9 -0
- package/node_modules/inherits/inherits_browser.js +27 -0
- package/node_modules/inherits/package.json +29 -0
- package/node_modules/isarray/.npmignore +1 -0
- package/node_modules/isarray/.travis.yml +4 -0
- package/node_modules/isarray/Makefile +6 -0
- package/node_modules/isarray/README.md +60 -0
- package/node_modules/isarray/component.json +19 -0
- package/node_modules/isarray/index.js +5 -0
- package/node_modules/isarray/package.json +45 -0
- package/node_modules/isarray/test.js +20 -0
- package/node_modules/jszip/.codeclimate.yml +16 -0
- package/node_modules/jszip/.editorconfig +8 -0
- package/node_modules/jszip/.eslintrc.js +43 -0
- package/node_modules/jszip/.github/workflows/pr.yaml +58 -0
- package/node_modules/jszip/.jekyll-metadata +0 -0
- package/node_modules/jszip/.travis.yml +17 -0
- package/node_modules/jszip/CHANGES.md +204 -0
- package/node_modules/jszip/LICENSE.markdown +651 -0
- package/node_modules/jszip/README.markdown +33 -0
- package/node_modules/jszip/deps.js +37 -0
- package/node_modules/jszip/dist/jszip.js +11577 -0
- package/node_modules/jszip/dist/jszip.min.js +13 -0
- package/node_modules/jszip/graph.svg +601 -0
- package/node_modules/jszip/index.d.ts +330 -0
- package/node_modules/jszip/lib/base64.js +106 -0
- package/node_modules/jszip/lib/compressedObject.js +74 -0
- package/node_modules/jszip/lib/compressions.js +14 -0
- package/node_modules/jszip/lib/crc32.js +77 -0
- package/node_modules/jszip/lib/defaults.js +11 -0
- package/node_modules/jszip/lib/external.js +18 -0
- package/node_modules/jszip/lib/flate.js +85 -0
- package/node_modules/jszip/lib/generate/ZipFileWorker.js +539 -0
- package/node_modules/jszip/lib/generate/index.js +57 -0
- package/node_modules/jszip/lib/index.js +55 -0
- package/node_modules/jszip/lib/license_header.js +11 -0
- package/node_modules/jszip/lib/load.js +88 -0
- package/node_modules/jszip/lib/nodejs/NodejsStreamInputAdapter.js +74 -0
- package/node_modules/jszip/lib/nodejs/NodejsStreamOutputAdapter.js +42 -0
- package/node_modules/jszip/lib/nodejsUtils.js +57 -0
- package/node_modules/jszip/lib/object.js +384 -0
- package/node_modules/jszip/lib/readable-stream-browser.js +10 -0
- package/node_modules/jszip/lib/reader/ArrayReader.js +57 -0
- package/node_modules/jszip/lib/reader/DataReader.js +116 -0
- package/node_modules/jszip/lib/reader/NodeBufferReader.js +19 -0
- package/node_modules/jszip/lib/reader/StringReader.js +38 -0
- package/node_modules/jszip/lib/reader/Uint8ArrayReader.js +22 -0
- package/node_modules/jszip/lib/reader/readerFor.js +28 -0
- package/node_modules/jszip/lib/signature.js +7 -0
- package/node_modules/jszip/lib/stream/ConvertWorker.js +26 -0
- package/node_modules/jszip/lib/stream/Crc32Probe.js +24 -0
- package/node_modules/jszip/lib/stream/DataLengthProbe.js +29 -0
- package/node_modules/jszip/lib/stream/DataWorker.js +116 -0
- package/node_modules/jszip/lib/stream/GenericWorker.js +263 -0
- package/node_modules/jszip/lib/stream/StreamHelper.js +214 -0
- package/node_modules/jszip/lib/support.js +38 -0
- package/node_modules/jszip/lib/utf8.js +275 -0
- package/node_modules/jszip/lib/utils.js +501 -0
- package/node_modules/jszip/lib/zipEntries.js +261 -0
- package/node_modules/jszip/lib/zipEntry.js +293 -0
- package/node_modules/jszip/lib/zipObject.js +133 -0
- package/node_modules/jszip/package.json +67 -0
- package/node_modules/jszip/sponsors.md +21 -0
- package/node_modules/jszip/tsconfig.json +101 -0
- package/node_modules/jszip/vendor/FileSaver.js +247 -0
- package/node_modules/lie/README.md +62 -0
- package/node_modules/lie/dist/lie.js +350 -0
- package/node_modules/lie/dist/lie.min.js +1 -0
- package/node_modules/lie/dist/lie.polyfill.js +358 -0
- package/node_modules/lie/dist/lie.polyfill.min.js +1 -0
- package/node_modules/lie/lib/browser.js +273 -0
- package/node_modules/lie/lib/index.js +298 -0
- package/node_modules/lie/license.md +7 -0
- package/node_modules/lie/lie.d.ts +244 -0
- package/node_modules/lie/package.json +69 -0
- package/node_modules/lie/polyfill.js +4 -0
- package/node_modules/pako/CHANGELOG.md +164 -0
- package/node_modules/pako/LICENSE +21 -0
- package/node_modules/pako/README.md +191 -0
- package/node_modules/pako/dist/pako.js +6818 -0
- package/node_modules/pako/dist/pako.min.js +1 -0
- package/node_modules/pako/dist/pako_deflate.js +3997 -0
- package/node_modules/pako/dist/pako_deflate.min.js +1 -0
- package/node_modules/pako/dist/pako_inflate.js +3300 -0
- package/node_modules/pako/dist/pako_inflate.min.js +1 -0
- package/node_modules/pako/index.js +14 -0
- package/node_modules/pako/lib/deflate.js +400 -0
- package/node_modules/pako/lib/inflate.js +423 -0
- package/node_modules/pako/lib/utils/common.js +105 -0
- package/node_modules/pako/lib/utils/strings.js +187 -0
- package/node_modules/pako/lib/zlib/README +59 -0
- package/node_modules/pako/lib/zlib/adler32.js +51 -0
- package/node_modules/pako/lib/zlib/constants.js +68 -0
- package/node_modules/pako/lib/zlib/crc32.js +59 -0
- package/node_modules/pako/lib/zlib/deflate.js +1874 -0
- package/node_modules/pako/lib/zlib/gzheader.js +58 -0
- package/node_modules/pako/lib/zlib/inffast.js +345 -0
- package/node_modules/pako/lib/zlib/inflate.js +1556 -0
- package/node_modules/pako/lib/zlib/inftrees.js +343 -0
- package/node_modules/pako/lib/zlib/messages.js +32 -0
- package/node_modules/pako/lib/zlib/trees.js +1222 -0
- package/node_modules/pako/lib/zlib/zstream.js +47 -0
- package/node_modules/pako/package.json +44 -0
- package/node_modules/process-nextick-args/index.js +45 -0
- package/node_modules/process-nextick-args/license.md +19 -0
- package/node_modules/process-nextick-args/package.json +25 -0
- package/node_modules/process-nextick-args/readme.md +18 -0
- package/node_modules/readable-stream/.travis.yml +34 -0
- package/node_modules/readable-stream/CONTRIBUTING.md +38 -0
- package/node_modules/readable-stream/GOVERNANCE.md +136 -0
- package/node_modules/readable-stream/LICENSE +47 -0
- package/node_modules/readable-stream/README.md +58 -0
- package/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +60 -0
- package/node_modules/readable-stream/duplex-browser.js +1 -0
- package/node_modules/readable-stream/duplex.js +1 -0
- package/node_modules/readable-stream/lib/_stream_duplex.js +131 -0
- package/node_modules/readable-stream/lib/_stream_passthrough.js +47 -0
- package/node_modules/readable-stream/lib/_stream_readable.js +1019 -0
- package/node_modules/readable-stream/lib/_stream_transform.js +214 -0
- package/node_modules/readable-stream/lib/_stream_writable.js +685 -0
- package/node_modules/readable-stream/lib/internal/streams/BufferList.js +78 -0
- package/node_modules/readable-stream/lib/internal/streams/destroy.js +84 -0
- package/node_modules/readable-stream/lib/internal/streams/stream-browser.js +1 -0
- package/node_modules/readable-stream/lib/internal/streams/stream.js +1 -0
- package/node_modules/readable-stream/package.json +52 -0
- package/node_modules/readable-stream/passthrough.js +1 -0
- package/node_modules/readable-stream/readable-browser.js +7 -0
- package/node_modules/readable-stream/readable.js +19 -0
- package/node_modules/readable-stream/transform.js +1 -0
- package/node_modules/readable-stream/writable-browser.js +1 -0
- package/node_modules/readable-stream/writable.js +8 -0
- package/node_modules/safe-buffer/LICENSE +21 -0
- package/node_modules/safe-buffer/README.md +584 -0
- package/node_modules/safe-buffer/index.d.ts +187 -0
- package/node_modules/safe-buffer/index.js +62 -0
- package/node_modules/safe-buffer/package.json +37 -0
- package/node_modules/setimmediate/LICENSE.txt +20 -0
- package/node_modules/setimmediate/package.json +30 -0
- package/node_modules/setimmediate/setImmediate.js +186 -0
- package/node_modules/string_decoder/.travis.yml +50 -0
- package/node_modules/string_decoder/LICENSE +48 -0
- package/node_modules/string_decoder/README.md +47 -0
- package/node_modules/string_decoder/lib/string_decoder.js +296 -0
- package/node_modules/string_decoder/package.json +31 -0
- package/node_modules/util-deprecate/History.md +16 -0
- package/node_modules/util-deprecate/LICENSE +24 -0
- package/node_modules/util-deprecate/README.md +53 -0
- package/node_modules/util-deprecate/browser.js +67 -0
- package/node_modules/util-deprecate/node.js +6 -0
- package/node_modules/util-deprecate/package.json +27 -0
- package/openclaw.plugin.json +1 -0
- package/package.json +7 -4
- /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/index.d.ts +0 -0
- /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/index.js +0 -0
- /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/license +0 -0
- /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/package.json +0 -0
- /package/node_modules/{p-limit/node_modules/yocto-queue → yocto-queue}/readme.md +0 -0
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# Atomic writes
|
|
2
|
+
|
|
3
|
+
`@openclaw/fs-safe/atomic` re-exports the lower-level helpers that `root()`'s write methods are built on. Reach for them when you have an absolute path you trust and want sibling-temp + rename without setting up a `Root`, or when you need finer control over `fsync`, mode preservation, or pre-rename hooks.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import {
|
|
7
|
+
replaceFileAtomic,
|
|
8
|
+
replaceFileAtomicSync,
|
|
9
|
+
writeTextAtomic,
|
|
10
|
+
replaceDirectoryAtomic,
|
|
11
|
+
movePathWithCopyFallback,
|
|
12
|
+
} from "@openclaw/fs-safe/atomic";
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## `replaceFileAtomic` / `replaceFileAtomicSync`
|
|
16
|
+
|
|
17
|
+
Write `content` to a sibling temp file in the destination directory, apply the parent-directory and final file modes through verified descriptors, optionally `fsync` the file descriptor, optionally `fsync` the parent directory after rename, then atomically rename over the destination. No permission change follows a caller-supplied pathname.
|
|
18
|
+
|
|
19
|
+
On POSIX, the parent is opened with no-follow and directory-only flags, checked against its pre-open identity, and mode-adjusted through that descriptor. A replacement symlink is rejected rather than followed. If the directory cannot be opened for descriptor access, the operation fails closed instead of retrying by pathname. Windows does not enforce POSIX directory modes and Node cannot consistently open directory descriptors there, so `dirMode` is passed only to `mkdir`; no pathname `chmod` fallback is attempted.
|
|
20
|
+
|
|
21
|
+
Async replacements to the same destination are serialized inside the current process, so two overlapping `replaceFileAtomic()` calls do not interleave their temp-write/rename phases. Use a sidecar lock when multiple processes may write the same target.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { replaceFileAtomic } from "@openclaw/fs-safe/atomic";
|
|
25
|
+
|
|
26
|
+
await replaceFileAtomic({
|
|
27
|
+
filePath: "/srv/workspace/state.json",
|
|
28
|
+
content: JSON.stringify(state, null, 2),
|
|
29
|
+
mode: 0o600,
|
|
30
|
+
syncTempFile: true,
|
|
31
|
+
syncParentDir: true,
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Options
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
type ReplaceFileAtomicOptions = {
|
|
39
|
+
filePath: string; // destination
|
|
40
|
+
content: string | Uint8Array;
|
|
41
|
+
dirMode?: number; // parent-directory mode (POSIX; default 0o700)
|
|
42
|
+
mode?: number; // new-file mode (default 0o600)
|
|
43
|
+
preserveExistingMode?: boolean; // copy existing mode; default false
|
|
44
|
+
tempPrefix?: string; // default ".fs-safe-replace"
|
|
45
|
+
renameMaxRetries?: number; // EBUSY retries; default 0
|
|
46
|
+
renameRetryBaseDelayMs?: number; // exponential base; default 50
|
|
47
|
+
copyFallbackOnPermissionError?: boolean; // default false
|
|
48
|
+
copyFallbackRestore?: "restore-original" | "none"; // default: "none"
|
|
49
|
+
maxRestoreBytes?: number; // required with "restore-original"
|
|
50
|
+
destinationHardlinks?: "reject"; // default unset (no destination nlink policy)
|
|
51
|
+
renameIdentity?: "strict" | "verify-content-with-lock"; // default "strict"
|
|
52
|
+
syncTempFile?: boolean; // fsync(temp) before rename, or the final file after copy fallback; default false
|
|
53
|
+
syncParentDir?: boolean; // fsync(parent) after rename, POSIX only; default false
|
|
54
|
+
throwOnCleanupError?: boolean; // report temp cleanup failure; default false
|
|
55
|
+
beforeRename?: (params: { filePath: string; tempPath: string }) => Promise<void>;
|
|
56
|
+
fileSystem?: ReplaceFileAtomicFileSystem; // injectable fs for tests
|
|
57
|
+
};
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### `beforeRename`
|
|
61
|
+
|
|
62
|
+
Runs after the temp file is fully written and before the rename. Use it to take a backup snapshot, capture the about-to-be-replaced contents, or notify an observer. The helper retains the staged descriptor and exact bigint identity across the hook; replacing, deleting, hardlinking, or changing the temp entry to a non-regular file is rejected before publication:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
await replaceFileAtomic({
|
|
66
|
+
filePath: "/srv/workspace/config.toml",
|
|
67
|
+
content: rendered,
|
|
68
|
+
beforeRename: async ({ filePath }) => {
|
|
69
|
+
await fs.copyFile(filePath, `${filePath}.bak`); // snapshot existing
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
If `beforeRename` throws, the rename is skipped and the owned temp file is removed — the destination is unchanged. Cleanup unlinks only the exact admitted single-link file; a substitute observed at the temp name is preserved and removed from cleanup authority. The same identity is rechecked before every rename retry, when entering copy fallback, and at the final name after rename. A post-rename verification failure reports the race without rolling back or deleting the published name.
|
|
75
|
+
|
|
76
|
+
Identity checks and pathname rename/unlink remain separate syscalls, not atomic conditional mutations. Use an approved writable parent plus cooperative locking or OS isolation when arbitrary concurrent namespace mutation is in scope.
|
|
77
|
+
|
|
78
|
+
### FUSE mounts and unstable rename identity
|
|
79
|
+
|
|
80
|
+
Strict source-to-destination identity is the default. Some FUSE mounts assign a different inode to the destination during rename even without concurrency. Set `renameIdentity: "verify-content-with-lock"` to accept that boundary only when the re-opened no-follow destination has the exact requested SHA-256 content under an exclusive hashed sidecar lock in the destination parent. The newly accepted descriptor and identity remain pinned through parent sync and final verification. The synchronous helper provides the same policy with the synchronous lock implementation.
|
|
81
|
+
|
|
82
|
+
This is the same explicit weaker contract available on `Root` writes: cooperating writers are serialized, stale locks fail closed, and mismatched content is rejected after publication without rollback. A same-authority actor that ignores the advisory lock can still substitute another file with identical bytes, so do not use this compatibility policy in directories writable by untrusted same-UID processes.
|
|
83
|
+
|
|
84
|
+
### `EPERM` and copy fallback
|
|
85
|
+
|
|
86
|
+
On systems where `rename` fails with `EPERM`/`EEXIST`, pass
|
|
87
|
+
`copyFallbackOnPermissionError: true` to fall back to a non-atomic copy
|
|
88
|
+
replacement. The fallback removes the old destination, opens the replacement
|
|
89
|
+
with exclusive/no-follow flags where the platform supports them, and refuses
|
|
90
|
+
known symlink destinations so it does not write through a replaced destination
|
|
91
|
+
link.
|
|
92
|
+
|
|
93
|
+
Set `destinationHardlinks: "reject"` when an existing regular-file destination
|
|
94
|
+
must not have aliases. The policy reads `nlink` from a pinned destination
|
|
95
|
+
descriptor, not pathname metadata, before rename and rechecks it in the copy
|
|
96
|
+
fallback.
|
|
97
|
+
|
|
98
|
+
The default `copyFallbackRestore: "none"` preserves the existing fallback
|
|
99
|
+
contract: a failed copy can leave a partial destination. For state files where
|
|
100
|
+
preserving the old bytes is more important, choose `"restore-original"` and set
|
|
101
|
+
an explicit `maxRestoreBytes` memory budget. If the destination exists, fs-safe
|
|
102
|
+
snapshots it through a pinned descriptor, overwrites and mode-adjusts through
|
|
103
|
+
that same descriptor, and synchronizes the result. Any write, mode, or sync
|
|
104
|
+
failure triggers a byte-and-mode restore and another sync through the same
|
|
105
|
+
descriptor.
|
|
106
|
+
|
|
107
|
+
Restore failures are `FsSafeError("helper-failed")` values with typed
|
|
108
|
+
`details.cleanup` set to `"restored"` or `"restore-failed"`. An original larger
|
|
109
|
+
than `maxRestoreBytes` fails with `too-large` before mutation. A missing
|
|
110
|
+
destination has no original to restore and follows the exclusive-create copy
|
|
111
|
+
fallback.
|
|
112
|
+
|
|
113
|
+
### Sync variant
|
|
114
|
+
|
|
115
|
+
`replaceFileAtomicSync` accepts the same base options, a synchronous
|
|
116
|
+
`beforeRename` callback, and `ReplaceFileAtomicSyncFileSystem`. Use it inside
|
|
117
|
+
synchronous boot paths or test setup code. It returns the same
|
|
118
|
+
`{ method: "rename" | "copy-fallback" }` receipt as the async variant.
|
|
119
|
+
|
|
120
|
+
## `replaceDirectoryAtomic`
|
|
121
|
+
|
|
122
|
+
Atomically swap one directory's contents with another, using a temporary backup during the swap.
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { replaceDirectoryAtomic } from "@openclaw/fs-safe/atomic";
|
|
126
|
+
|
|
127
|
+
await replaceDirectoryAtomic({
|
|
128
|
+
stagedDir: "/srv/workspace/staging/snapshot-2026-05-05",
|
|
129
|
+
targetDir: "/srv/workspace/snapshot",
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The helper renames `targetDir` to a generated backup path, renames `stagedDir → targetDir`, then removes the backup. If the second rename fails, it tries to restore the original target before rethrowing.
|
|
134
|
+
Concurrent replacements of the same resolved target are serialized inside the
|
|
135
|
+
current process so their backup, commit, and cleanup phases cannot interleave.
|
|
136
|
+
`backupPrefix`, when supplied, is sanitized as one path prefix and cannot contain
|
|
137
|
+
path separators or NUL bytes; the generated backup tail is randomized.
|
|
138
|
+
|
|
139
|
+
Use it when callers must see a whole staged tree at the target path. For single-file replacement, `replaceFileAtomic` is the right tool.
|
|
140
|
+
|
|
141
|
+
## `writeTextAtomic`
|
|
142
|
+
|
|
143
|
+
Atomic UTF-8 text write with the same secure defaults as `writeJson`: sibling
|
|
144
|
+
temp file, descriptor-bound mode setting and fsync, rename, and parent fsync.
|
|
145
|
+
It delegates to `replaceFileAtomic()` with a smaller call shape. Use it when
|
|
146
|
+
you do not need replacement hooks such as `beforeRename`, `preserveExistingMode`,
|
|
147
|
+
or custom copy-fallback policy.
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { writeTextAtomic } from "@openclaw/fs-safe/atomic";
|
|
151
|
+
|
|
152
|
+
await writeTextAtomic("/srv/workspace/rendered.md", rendered, {
|
|
153
|
+
mode: 0o600,
|
|
154
|
+
dirMode: 0o700,
|
|
155
|
+
trailingNewline: true,
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Options:
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
type WriteTextAtomicOptions = {
|
|
163
|
+
mode?: number; // file mode (default 0o600)
|
|
164
|
+
dirMode?: number; // parent mode (default 0o777 masked by process umask)
|
|
165
|
+
trailingNewline?: boolean; // append "\n" if missing; default false
|
|
166
|
+
durable?: boolean; // default true; false skips temp/parent fsync
|
|
167
|
+
};
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`durable: false` keeps the sibling-temp replace/rename behavior but skips the
|
|
171
|
+
temp-file and parent-directory `fsync` calls. Use it only for reconstructible
|
|
172
|
+
metadata where lower latency matters more than crash-durability.
|
|
173
|
+
|
|
174
|
+
## `movePathWithCopyFallback`
|
|
175
|
+
|
|
176
|
+
Rename a path. If the rename fails with `EXDEV` (cross-device), or `EPERM` on
|
|
177
|
+
Windows, fall back to
|
|
178
|
+
copying into a staged sibling path, renaming that staged path into place, and
|
|
179
|
+
then removing only the source entries that were copied. The fallback avoids
|
|
180
|
+
buffering regular files into memory and does not tighten the destination parent
|
|
181
|
+
directory mode. Staged file modes are applied through their still-open handles.
|
|
182
|
+
If descriptor-bound mode application fails, the staged path is removed and the
|
|
183
|
+
move fails before publication. A transient staged-path cleanup failure retains
|
|
184
|
+
an identity-bound process-exit cleanup retry.
|
|
185
|
+
On POSIX, staged directory modes are applied through no-follow directory
|
|
186
|
+
descriptors; on Windows, Node cannot portably open those descriptors and no
|
|
187
|
+
pathname `chmod` fallback is attempted, so directory modes remain subject to
|
|
188
|
+
Windows' `mkdir(mode)` behavior. Symlink sources are copied as links rather than
|
|
189
|
+
followed, including when the referent is absent; only a source proven to be a
|
|
190
|
+
directory is dereferenced for the destination-descendant guard.
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { movePathWithCopyFallback } from "@openclaw/fs-safe/atomic";
|
|
194
|
+
|
|
195
|
+
await movePathWithCopyFallback({
|
|
196
|
+
from: "/srv/cache/blob.bin",
|
|
197
|
+
sourceHardlinks: "reject",
|
|
198
|
+
to: "/srv/persistent/blob.bin",
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Use it when source and destination might live on different filesystems (containers, tmpfs, separate volumes).
|
|
203
|
+
The hardlink policy is captured when the move starts. Changing or reusing the
|
|
204
|
+
options object later does not change the policy of an in-flight move.
|
|
205
|
+
`sourceHardlinks: "reject"` performs a recursive preflight capped at 50,000
|
|
206
|
+
entries before any mutation. Because link count and rename cannot be one atomic
|
|
207
|
+
portable operation, this mode always commits a fresh inode/tree through the
|
|
208
|
+
staged-copy route, even on one filesystem. Each regular file is checked again
|
|
209
|
+
after open and after copying, so a post-scan hardlink cannot become the
|
|
210
|
+
published target. A hardlink fails with `FsSafeError("hardlink")`; exceeding
|
|
211
|
+
the preflight cap fails with `FsSafeError("too-large")`.
|
|
212
|
+
If another writer changes source entries during the fallback, the staged copy
|
|
213
|
+
throws `ESTALE` before commit when possible. If the destination has already
|
|
214
|
+
been committed, cleanup still preserves the changed source entries and throws
|
|
215
|
+
`ESTALE`. When allowed source names are hardlinks to the same inode, each owned
|
|
216
|
+
unlink is verified through a remaining manifested alias and its exact resulting
|
|
217
|
+
identity becomes the next cleanup receipt. This accounts for the operation's
|
|
218
|
+
own link-count and ctime changes without suppressing unexpected external
|
|
219
|
+
mutations.
|
|
220
|
+
|
|
221
|
+
### Mutation authority and publication receipts
|
|
222
|
+
|
|
223
|
+
Pass `assertBeforeMutation` when a move depends on a revocable lease or another
|
|
224
|
+
caller-owned authorization. The helper captures the callback when called and
|
|
225
|
+
runs it synchronously after asynchronous preparation and identity checks,
|
|
226
|
+
immediately before each rename, source-file or source-symlink unlink, and
|
|
227
|
+
source-directory removal. `assertBeforeRename` remains available for callers
|
|
228
|
+
that only guard publication. When both are set, the rename check runs first,
|
|
229
|
+
then the mutation check, without yielding before dispatch.
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
type MovePathPublicationReceipt = Readonly<{
|
|
233
|
+
path: string;
|
|
234
|
+
dev: bigint;
|
|
235
|
+
ino: bigint;
|
|
236
|
+
}>;
|
|
237
|
+
|
|
238
|
+
type MovePathWithCopyFallbackOptions = {
|
|
239
|
+
from: string;
|
|
240
|
+
sourceHardlinks?: "allow" | "reject";
|
|
241
|
+
to: string;
|
|
242
|
+
assertBeforeRename?: () => void;
|
|
243
|
+
assertBeforeMutation?: () => void;
|
|
244
|
+
onDestinationPublished?: (receipt: MovePathPublicationReceipt) => void;
|
|
245
|
+
};
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Throw to refuse the next mutation. The original error is propagated, including
|
|
249
|
+
errors with `EXDEV` or `EPERM` codes; an authorization failure never starts a
|
|
250
|
+
copy fallback. A genuine rename failure may still require a second authority
|
|
251
|
+
check before publishing the staged copy.
|
|
252
|
+
|
|
253
|
+
All three callbacks must return `undefined` synchronously. Returning a Promise,
|
|
254
|
+
thenable, or any other value fails with a `TypeError`; rejected asynchronous
|
|
255
|
+
results are consumed. Perform asynchronous policy checks before calling the
|
|
256
|
+
helper and use the authority callback to recheck the current owner at each
|
|
257
|
+
mutation boundary. All callbacks are captured before the first await.
|
|
258
|
+
|
|
259
|
+
`onDestinationPublished` runs exactly once after a successful rename resolves,
|
|
260
|
+
before awaited post-rename directory checks or source cleanup. It receives a
|
|
261
|
+
frozen receipt with the resolved absolute destination path and the exact bigint
|
|
262
|
+
device/inode identity observed on the rename source before dispatch: the
|
|
263
|
+
original source for a direct rename, or the staged copy for fallback. Failed
|
|
264
|
+
rename attempts never emit receipts. The return contract remains `Promise<void>`.
|
|
265
|
+
|
|
266
|
+
The receipt records an observed identity, not authorization, durable storage,
|
|
267
|
+
or an atomic guarantee against concurrent pathname replacement. Before recovery,
|
|
268
|
+
recheck caller authority and compare the retained identity with a fresh bigint
|
|
269
|
+
stat of the destination. In particular, unknown Windows device/inode values
|
|
270
|
+
must not be treated as proof of ownership. Do not derive ownership from a new
|
|
271
|
+
post-failure snapshot alone.
|
|
272
|
+
|
|
273
|
+
A refused rename leaves the source and destination unchanged; any private
|
|
274
|
+
staged copy follows normal cleanup. If publication has already happened, a
|
|
275
|
+
callback error or later verification failure preserves the published destination
|
|
276
|
+
and stops further source cleanup. Revocation during cleanup leaves all
|
|
277
|
+
as-yet-unremoved source entries intact; entries already removed remain removed.
|
|
278
|
+
The caller retains the receipt even if the move later rejects and owns recovery
|
|
279
|
+
from this partial-move state. An observer that throws must retain its receipt
|
|
280
|
+
before throwing if recovery needs it.
|
|
281
|
+
|
|
282
|
+
These callbacks do not cancel already-dispatched operations or make an external
|
|
283
|
+
lease store atomic with the filesystem. `assertBeforeMutation` guards renames
|
|
284
|
+
and removal of copied source entries; private staging creation, writes, and
|
|
285
|
+
failed-staging cleanup remain owned by the helper. Omitting the new callbacks
|
|
286
|
+
preserves the existing move and source-identity behavior.
|
|
287
|
+
|
|
288
|
+
## Difference from `root()`
|
|
289
|
+
|
|
290
|
+
| `Root` methods | `atomic` helpers |
|
|
291
|
+
|---|---|
|
|
292
|
+
| Take relative paths, bound to a `rootDir`. | Take absolute paths, no boundary. |
|
|
293
|
+
| Throw `FsSafeError` with `code`. | Throw `FsSafeError` *or* the underlying `NodeJS.ErrnoException`, depending on failure point. |
|
|
294
|
+
| Atomicity, mode, hooks, fsync are sane defaults. | Caller controls all of the above. |
|
|
295
|
+
| `mkdir`, identity check, hardlink reject built in. | No root boundary; `movePathWithCopyFallback` has explicit `sourceHardlinks` policy, while other helpers expose their own narrower checks. |
|
|
296
|
+
|
|
297
|
+
Use `Root` when the path is caller-controlled. Use `atomic` when the path is fully under your control and you want explicit knobs.
|
|
298
|
+
|
|
299
|
+
## Test injection
|
|
300
|
+
|
|
301
|
+
Both `replaceFileAtomic` and `replaceFileAtomicSync` accept a `fileSystem` option that overrides the small set of `fs` calls they make. Pass a stub in unit tests to assert order, simulate `EPERM`, or capture the temp filename:
|
|
302
|
+
|
|
303
|
+
```ts
|
|
304
|
+
const ops: string[] = [];
|
|
305
|
+
await replaceFileAtomic({
|
|
306
|
+
filePath: "/tmp/x",
|
|
307
|
+
content: "hi",
|
|
308
|
+
fileSystem: {
|
|
309
|
+
promises: {
|
|
310
|
+
...realFs,
|
|
311
|
+
writeFile: async (...args) => { ops.push("write"); return realFs.writeFile(...args); },
|
|
312
|
+
rename: async (...args) => { ops.push("rename"); return realFs.rename(...args); },
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
The synchronous injectable interface has one optional descriptor-mode operation:
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
type ReplaceFileAtomicSyncFileSystem = {
|
|
322
|
+
// other required operations omitted
|
|
323
|
+
fchmodSync?: typeof import("node:fs").fchmodSync;
|
|
324
|
+
};
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
The async interface already requires `open()`, whose `FileHandle` supplies `chmod()`, so injecting `node:fs` or another conforming adapter needs no new async member. On POSIX, that `open()` must support no-follow directory descriptors as Node does. A custom synchronous filesystem that passes `mode`, `dirMode`, or `preserveExistingMode` must supply `fchmodSync`; omission fails before any file or directory is created and never falls back to a pathname `chmod`. Existing synchronous adapters that request none of those options may omit it; their parent is still opened and identity-checked through a no-follow directory descriptor. Injecting plain `node:fs` supports explicit file and directory modes. Older adapter literals may continue to include `chmod` or `chmodSync` for source compatibility, but those operations are ignored. Copy fallback applies the file mode through its pinned destination descriptor as well, preserving exact modes despite the process umask.
|
|
328
|
+
|
|
329
|
+
## See also
|
|
330
|
+
|
|
331
|
+
- [`root()`](root.md) — when you want method-style writes with the boundary baked in.
|
|
332
|
+
- [JSON files](json.md) — JSON/text helpers built on sibling-temp replacement.
|
|
333
|
+
- [Temp workspaces](temp.md) — for staging-then-swap directory builds.
|
|
334
|
+
- [Errors](errors.md) — code union for failures.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Config
|
|
3
|
+
description: "Process-global defaults for optional fs-safe helpers."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# `@openclaw/fs-safe/config`
|
|
7
|
+
|
|
8
|
+
Process-global configuration knobs for optional fs-safe helpers. The native helper policy is described in the [native helper policy](native-helper.md); this page is the API reference.
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import {
|
|
12
|
+
configureFsSafeNative,
|
|
13
|
+
configureFsSafeLocks,
|
|
14
|
+
getFsSafeNativeConfig,
|
|
15
|
+
getFsSafeLockConfig,
|
|
16
|
+
type FsSafeLockConfig,
|
|
17
|
+
type FsSafeNativeConfig,
|
|
18
|
+
type FsSafeNativeMode,
|
|
19
|
+
} from "@openclaw/fs-safe/config";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
These functions are also re-exported from the main entry point. Prefer the subpath when you only need helper configuration and want the smallest import surface.
|
|
23
|
+
|
|
24
|
+
## `configureFsSafeNative(config)`
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
function configureFsSafeNative(config: Partial<FsSafeNativeConfig>): void;
|
|
28
|
+
|
|
29
|
+
type FsSafeNativeConfig = {
|
|
30
|
+
mode: FsSafeNativeMode;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type FsSafeNativeMode = "auto" | "off" | "require";
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Set the process-global loading policy. Configure once at startup, before the first filesystem operation. The binding is loaded lazily and the result is cached.
|
|
37
|
+
|
|
38
|
+
| Mode | Behavior |
|
|
39
|
+
|---|---|
|
|
40
|
+
| `auto` | Default. Prefer the platform binding and use guarded JavaScript when it is unavailable. |
|
|
41
|
+
| `off` | Do not load the binding; use guarded JavaScript deterministically. |
|
|
42
|
+
| `require` | Operations that need the binding raise `FsSafeError("helper-unavailable")` when it cannot load. |
|
|
43
|
+
|
|
44
|
+
## `getFsSafeNativeConfig()`
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
function getFsSafeNativeConfig(): FsSafeNativeConfig;
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Return the effective configuration: programmatic overrides win, then env vars, then the package default (`auto`).
|
|
51
|
+
|
|
52
|
+
## `configureFsSafeLocks(config)`
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
function configureFsSafeLocks(config: Partial<FsSafeLockConfig>): void;
|
|
56
|
+
|
|
57
|
+
type FsSafeLockConfig = {
|
|
58
|
+
staleRecovery: "fail-closed" | "remove-if-unchanged";
|
|
59
|
+
staleMs?: number;
|
|
60
|
+
timeoutMs?: number;
|
|
61
|
+
retry?: FileLockRetryOptions;
|
|
62
|
+
};
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Set process-wide defaults for sidecar lock options. This does **not** turn locking on globally; callers still need to pass `lock: true` or a lock options object for the specific JSON store/resource that needs cross-process coordination.
|
|
66
|
+
|
|
67
|
+
`staleRecovery` defaults to `"fail-closed"`. The opt-in `"remove-if-unchanged"` mode requires caller approval and serializes the final snapshot check and unlink with an exclusive `.reclaim` guard. A reclaim guard left by a killed reclaimer fails closed and requires externally coordinated cleanup.
|
|
68
|
+
|
|
69
|
+
For a daemon that should wait briefly for normal contention but never delete a
|
|
70
|
+
stale owner without per-lock approval:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
configureFsSafeLocks({
|
|
74
|
+
staleRecovery: "fail-closed",
|
|
75
|
+
staleMs: 2 * 60_000,
|
|
76
|
+
timeoutMs: 15_000,
|
|
77
|
+
retry: { retries: 30, minTimeout: 50, maxTimeout: 1_000, randomize: true },
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
These defaults apply to both `acquireFileLock()` / `withFileLock()` and
|
|
82
|
+
`acquireFileLockSync()` / `withFileLockSync()`. Each acquisition resolves
|
|
83
|
+
`retry`, `staleMs`, `staleRecovery`, and `timeoutMs` from the per-call option
|
|
84
|
+
first, then the process configuration, then the package default. Explicit zero
|
|
85
|
+
values are preserved. A per-call `retry` object replaces the configured object
|
|
86
|
+
as a whole; omitted retry fields use package defaults, not configured fields.
|
|
87
|
+
|
|
88
|
+
Individual lock calls can override any default. Switching the global stale
|
|
89
|
+
recovery mode does not provide the application-owned liveness proof required
|
|
90
|
+
by `shouldRemoveStaleLock`.
|
|
91
|
+
|
|
92
|
+
## `getFsSafeLockConfig()`
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
function getFsSafeLockConfig(): FsSafeLockConfig;
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Return the current sidecar lock defaults.
|
|
99
|
+
|
|
100
|
+
## Environment variables
|
|
101
|
+
|
|
102
|
+
The same policy can be set without code:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
FS_SAFE_NATIVE_MODE=auto # auto | off | require | true | false | on | 1 | 0 | never | required
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`OPENCLAW_FS_SAFE_NATIVE_MODE` is accepted as an alias. Programmatic overrides via `configureFsSafeNative` always win.
|
|
109
|
+
|
|
110
|
+
### Python-helper migration bridge
|
|
111
|
+
|
|
112
|
+
Version 0.5 detects the former `FS_SAFE_PYTHON_MODE`, `FS_SAFE_PYTHON`,
|
|
113
|
+
`OPENCLAW_FS_SAFE_PYTHON_MODE`, `OPENCLAW_FS_SAFE_PYTHON`,
|
|
114
|
+
`OPENCLAW_PINNED_PYTHON`, and `OPENCLAW_PINNED_WRITE_PYTHON` names. It emits one
|
|
115
|
+
`FS_SAFE_PYTHON_DEPRECATED` warning and maps `auto`, `off`, or `require` to the
|
|
116
|
+
same native mode; interpreter paths are ignored. The deprecated
|
|
117
|
+
`configureFsSafePython()` export behaves the same way.
|
|
118
|
+
|
|
119
|
+
Replace these inputs with `configureFsSafeNative()` or
|
|
120
|
+
`FS_SAFE_NATIVE_MODE` during the 0.5 upgrade. The bridge exists only so shipped
|
|
121
|
+
0.4 configuration fails loudly and maps predictably; it is not a supported
|
|
122
|
+
Python execution path. Follow the [0.5 migration checklist](migrating-to-0.5.md)
|
|
123
|
+
for the full upgrade.
|
|
124
|
+
|
|
125
|
+
## Related pages
|
|
126
|
+
|
|
127
|
+
- [Native helper policy](native-helper.md) — when to pick `auto`, `off`, or `require`, and what each mode protects.
|
|
128
|
+
- [File lock](sidecar-lock.md) — the per-resource lock API that consumes lock defaults.
|
|
129
|
+
- [Root API](root.md) — the API whose POSIX hardening the helper backs.
|
|
130
|
+
- [Errors](errors.md) — `helper-unavailable` and `helper-failed`.
|
|
131
|
+
- [Migrating to 0.5](migrating-to-0.5.md) — ordered consumer upgrade checklist.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
The `fs-safe` repo lives at [github.com/openclaw/fs-safe](https://github.com/openclaw/fs-safe). Contributions welcome — issues, bug reports, focused PRs.
|
|
4
|
+
|
|
5
|
+
## Local setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/openclaw/fs-safe.git
|
|
9
|
+
cd fs-safe
|
|
10
|
+
pnpm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Node 22 or newer. The dev toolchain and lockfile use pnpm; use the package
|
|
14
|
+
manager version declared in `package.json`.
|
|
15
|
+
|
|
16
|
+
## Build
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm build
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Runs TypeScript compilation and builds the portable Rust TAR parser for
|
|
23
|
+
`wasm32-unknown-unknown`. Contributors need Rust (the native crate's declared
|
|
24
|
+
minimum or newer) and `rustup target add wasm32-unknown-unknown`; Alpine's
|
|
25
|
+
packaged toolchain uses `rust-wasm`. `pnpm archive:wasm` rebuilds just the parser.
|
|
26
|
+
The import-free asset lands at `dist/archive-parser.wasm`; source tests and
|
|
27
|
+
compiled consumers both resolve that generated artifact. Run `pnpm build`
|
|
28
|
+
before source tests in a fresh checkout. Do not commit `dist/` or built WASM.
|
|
29
|
+
Consumers receive the asset in the npm package and need no compiler.
|
|
30
|
+
|
|
31
|
+
Output lands in `dist/`. The package's `prepack` hook re-runs the build before publishing — manual `pnpm build` is only required when you want to inspect the output or run a freshly-built copy locally.
|
|
32
|
+
|
|
33
|
+
## Test
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pnpm test
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Vitest. Tests live in `test/` and follow `*.test.ts`. Run a single file with:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pnpm test test/archive.test.ts
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Use `vi.mock` sparingly. Most tests should drive real disk operations in a `mkdtemp`-created scratch directory, asserting on observable behavior. The library has [test hooks](testing.md) for the rare cases where you need to inject a TOCTOU race deterministically.
|
|
46
|
+
|
|
47
|
+
Vitest timeouts do not cancel filesystem promises. Shared fixtures with expensive
|
|
48
|
+
setup use `useSuiteFixture` from `test/helpers/suite-fixture.ts`: setup has a separate
|
|
49
|
+
30-second hook budget, and teardown waits for tracked setup and test work before
|
|
50
|
+
removing directories. Run shared-state corpora sequentially with a deadline per
|
|
51
|
+
payload. Keep child-process liveness limits separate from fixture preparation.
|
|
52
|
+
The Windows CI slow-copy proof runs the real package-copy process-exit test with a
|
|
53
|
+
six-second copy delay, retaining its four-second child deadline:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pnpm build
|
|
57
|
+
pnpm test --config scripts/slow-package-copy.config.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Checks
|
|
61
|
+
|
|
62
|
+
Run the complete repository gate before handoff:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pnpm check
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This runs the filesystem boundary checks, build, tests, and package
|
|
69
|
+
tarball/import validation.
|
|
70
|
+
|
|
71
|
+
### Real TAR producers
|
|
72
|
+
|
|
73
|
+
After installing the freshly packed root (and optionally its freshly built host
|
|
74
|
+
binding) in a disposable consumer, run:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pnpm archive:producer-smoke ./consumer off
|
|
78
|
+
pnpm archive:producer-smoke ./consumer require
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This uses a child bound to canonical cwd/device/inode running `/usr/bin/tar -czf - .`
|
|
82
|
+
with unchanged stdout, and npm tar, on synthetic Unicode/newline/long-name files,
|
|
83
|
+
then the installed package API for exact payload hashes and bounded reads.
|
|
84
|
+
It also rejects a valid PAX override attached to an invalid raw UTF-8 field.
|
|
85
|
+
The `require` command must resolve the freshly packed native binding; the
|
|
86
|
+
`off` command uses the installed WASM asset. No live user files are read.
|
|
87
|
+
|
|
88
|
+
### Native consumer installs
|
|
89
|
+
|
|
90
|
+
The CI Node 24 and native jobs also run `node scripts/device-path-proof.mjs off`
|
|
91
|
+
and `node scripts/device-path-proof.mjs require` against the built package.
|
|
92
|
+
This extracts real ZIP files and checks bounded member reads, preserving reserved
|
|
93
|
+
device-like names on POSIX while rejecting them and ignored-space aliases on
|
|
94
|
+
Windows. It also verifies ordinary secret reads and typed device-path rejection
|
|
95
|
+
without replacing filesystem functions. Run after `pnpm build`, and build the
|
|
96
|
+
host binding with `pnpm native:build` before the `require` case.
|
|
97
|
+
|
|
98
|
+
After `pnpm build` and a fresh `pnpm native:build`, run `pnpm package:smoke`.
|
|
99
|
+
It packs the real root and host binding, then runs root-only npm and the
|
|
100
|
+
declared pnpm version against a disposable loopback registry. The root's exact
|
|
101
|
+
optional dependencies stay unchanged. Each consumer lives outside the workspace
|
|
102
|
+
with isolated configuration, caches, and stores; the registry never proxies to
|
|
103
|
+
the Internet. The smoke verifies root integrity, consumer-local resolution,
|
|
104
|
+
OS/CPU/libc selection, a native-required SHA-256 operation, and fresh-process
|
|
105
|
+
`auto`/`off` fallbacks and `require` failures for missing bindings and omitted
|
|
106
|
+
optionals. Omitted-optionals installs also verify that all public subpaths can
|
|
107
|
+
be imported, without implying every operation remains available.
|
|
108
|
+
|
|
109
|
+
Host-only smoke supplies the six foreign packages using their unchanged real
|
|
110
|
+
manifests and clearly marked synthetic, non-executable payloads. Every foreign
|
|
111
|
+
metadata/tarball endpoint is checked before installation, so a missing fixture
|
|
112
|
+
cannot masquerade as successful platform filtering. These temporary fixtures
|
|
113
|
+
never enter `packages/`, release artifacts, or the publish manifest. They prove
|
|
114
|
+
installer filtering, not foreign native compilation or execution. Full release
|
|
115
|
+
collection uses the actual seven collected native tarballs instead. Run it with
|
|
116
|
+
`pnpm package:collect` after assembling all seven real bindings; missing targets
|
|
117
|
+
fail collection. `pnpm package:collect --allow-host-only` exercises the same
|
|
118
|
+
lifecycle boundary locally but proves only the host. Both collection commands
|
|
119
|
+
require the pnpm lifecycle CLI path; direct `node` invocation is unsupported. Archive
|
|
120
|
+
codecs and their dependencies are packed from the installed dependency graph.
|
|
121
|
+
|
|
122
|
+
PR CI builds and executes four host targets: Linux x64 glibc, Linux x64 musl
|
|
123
|
+
(Alpine), macOS arm64, and Windows x64. The root-only smoke runs on each. The
|
|
124
|
+
seven-target source build matrix runs on release tags; packaging all seven is
|
|
125
|
+
not execution proof for every architecture. The smoke writes manager versions,
|
|
126
|
+
cases, and synthetic-fixture scope to `release-artifacts/consumer-proof.json`.
|
|
127
|
+
|
|
128
|
+
## Docs
|
|
129
|
+
|
|
130
|
+
The docs site is rendered recursively from Markdown files under `docs/` by `scripts/build-docs-site.mjs`. Build locally to preview:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
pnpm docs:site
|
|
134
|
+
open dist/docs-site/index.html
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The build validates internal links and embedded anchors. Broken links fail the build — fix them before pushing. Navigation must list every non-excluded Markdown page exactly once: missing, nonexistent, and duplicate entries fail before the build replaces existing site output. The builder and navigation tests share discovery and validation in `scripts/docs-site-navigation.mjs`.
|
|
138
|
+
|
|
139
|
+
Adding a new doc page:
|
|
140
|
+
|
|
141
|
+
1. Create `docs/<page>.md`. Use a leading `# Title` heading.
|
|
142
|
+
2. Add the page to the appropriate section in `scripts/docs-site-navigation.mjs` (`sections` array near the top). Nested pages use slash-separated paths relative to `docs/`, such as `guides/example.md`.
|
|
143
|
+
3. Cross-link from `docs/index.md` if it's a major surface.
|
|
144
|
+
4. Run `pnpm test test/docs-site-navigation.test.ts` and re-run the local build.
|
|
145
|
+
|
|
146
|
+
Internal links use relative `*.md` paths — the builder rewrites them to the rendered HTML. Code fences support GitHub-flavored markdown.
|
|
147
|
+
|
|
148
|
+
## PRs
|
|
149
|
+
|
|
150
|
+
Small, focused PRs land faster. The general shape:
|
|
151
|
+
|
|
152
|
+
- One concern per PR. Bug fixes separate from new APIs.
|
|
153
|
+
- A regression test for every bug fix where the test framework can express it.
|
|
154
|
+
- A changelog entry under `## Unreleased` when behavior visibly changes.
|
|
155
|
+
- For new public APIs: a docs page in `docs/` plus a sidebar entry.
|
|
156
|
+
|
|
157
|
+
## Releases
|
|
158
|
+
|
|
159
|
+
Maintainers publish from a protected `vX.Y.Z` tag on `main` through
|
|
160
|
+
`.github/workflows/release.yml`. The workflow requires the package version and a
|
|
161
|
+
dated `CHANGELOG.md` section to match the tag. It builds and publishes all seven
|
|
162
|
+
platform packages before publishing `@openclaw/fs-safe`, verifies every registry
|
|
163
|
+
artifact and provenance statement, and then creates the GitHub release.
|
|
164
|
+
|
|
165
|
+
Each package needs its own npm trusted-publisher configuration for
|
|
166
|
+
`openclaw/fs-safe` and `release.yml`. A new platform package must be created and
|
|
167
|
+
configured on npm before the first tag that references it; npm trust is
|
|
168
|
+
package-specific and cannot be bootstrapped by the tag workflow itself.
|
|
169
|
+
|
|
170
|
+
External contributors do not need to do anything beyond getting the pull
|
|
171
|
+
request merged. Maintainers must not publish locally or add npm automation
|
|
172
|
+
tokens.
|
|
173
|
+
|
|
174
|
+
## Reporting security issues
|
|
175
|
+
|
|
176
|
+
Suspected security issues belong in private disclosure first. See [`SECURITY.md`](https://github.com/openclaw/fs-safe/blob/main/SECURITY.md) in the repo for the current contact path. Don't open a public issue for a credential-stealing or sandbox-escape bug — coordinate the disclosure first.
|
|
177
|
+
|
|
178
|
+
## License
|
|
179
|
+
|
|
180
|
+
By contributing you agree that your contributions are licensed under the project's [MIT license](https://github.com/openclaw/fs-safe/blob/main/LICENSE).
|