@lousy-agents/mcp 5.21.5 → 5.21.7

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 (2) hide show
  1. package/dist/mcp-server.js +1352 -472
  2. package/package.json +1 -1
@@ -6559,7 +6559,7 @@ function escapeJsonPtr(str) {
6559
6559
 
6560
6560
 
6561
6561
  },
6562
- 3829(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
6562
+ 6732(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
6563
6563
  // NAMESPACE OBJECT: ../../node_modules/micromark/lib/constructs.js
6564
6564
  var constructs_namespaceObject = {};
6565
6565
  __webpack_require__.r(constructs_namespaceObject);
@@ -37057,7 +37057,7 @@ function byte_budget_normalizeMaxBytes(value, options = {}) {
37057
37057
  if (selected === undefined || selected === Number.POSITIVE_INFINITY)
37058
37058
  return selected;
37059
37059
  if (!Number.isSafeInteger(selected) || selected < 0) {
37060
- throw new RangeError(`${options.label ?? "maxBytes"} must be a non-negative safe integer or Infinity`);
37060
+ throw new RangeError("maxBytes must be a non-negative safe integer or Infinity");
37061
37061
  }
37062
37062
  return selected;
37063
37063
  }
@@ -37076,7 +37076,7 @@ function isStatValueProvablyDifferent(left, right, platform) {
37076
37076
  }
37077
37077
  return platform !== "win32" || (!isZero(left) && !isZero(right));
37078
37078
  }
37079
- function sha256Hex(data, encoding) {
37079
+ function file_identity_sha256Hex(data, encoding) {
37080
37080
  const buffer = typeof data === "string" ? Buffer.from(data, encoding ?? "utf8") : data;
37081
37081
  return (0,external_node_crypto_.createHash)("sha256").update(buffer).digest("hex");
37082
37082
  }
@@ -37087,7 +37087,7 @@ function file_identity_sameFileIdentity(left, right, platform = process.platform
37087
37087
  return (!isStatValueProvablyDifferent(left.dev, right.dev, platform) &&
37088
37088
  !isStatValueProvablyDifferent(left.ino, right.ino, platform));
37089
37089
  }
37090
- function sameFileIdentityForCleanup(left, right, platform = process.platform) {
37090
+ function file_identity_sameFileIdentityForCleanup(left, right, platform = process.platform) {
37091
37091
  // A zero Windows device or inode is unknown, not proof that a pathname still
37092
37092
  // names the object we created. Cleanup must fail closed rather than delete a
37093
37093
  // replacement that happens to share the known half of the identity.
@@ -37158,7 +37158,7 @@ function identityCheck(expected, platform) {
37158
37158
  }
37159
37159
  // Retry only unknown Windows identities, retaining every known component so a
37160
37160
  // later observation cannot erase a definite mismatch. Never reopen the file.
37161
- async function inspectFileIdentity(inspect, expected, platform = process.platform) {
37161
+ async function strict_file_identity_inspectFileIdentity(inspect, expected, platform = process.platform) {
37162
37162
  const check = identityCheck(expected, platform);
37163
37163
  for (let attempt = 0; attempt < 2; attempt++) {
37164
37164
  const stat = await inspect();
@@ -37167,7 +37167,7 @@ async function inspectFileIdentity(inspect, expected, platform = process.platfor
37167
37167
  }
37168
37168
  throw identityMismatch();
37169
37169
  }
37170
- function inspectFileIdentitySync(inspect, expected, platform = process.platform) {
37170
+ function strict_file_identity_inspectFileIdentitySync(inspect, expected, platform = process.platform) {
37171
37171
  const check = identityCheck(expected, platform);
37172
37172
  for (let attempt = 0; attempt < 2; attempt++) {
37173
37173
  const stat = inspect();
@@ -37198,11 +37198,11 @@ function normalizeWindowsPathForComparison(input) {
37198
37198
  // whitespace is part of the path and must not be trimmed away.
37199
37199
  return normalized.replaceAll("/", "\\").toLowerCase();
37200
37200
  }
37201
- function isNodeError(value) {
37201
+ function path_isNodeError(value) {
37202
37202
  return Boolean(value && typeof value === "object" && "code" in value);
37203
37203
  }
37204
37204
  function hasNodeErrorCode(value, code) {
37205
- return isNodeError(value) && value.code === code;
37205
+ return path_isNodeError(value) && value.code === code;
37206
37206
  }
37207
37207
  function path_assertNoNulPathInput(filePath, message = "path contains a NUL byte") {
37208
37208
  if (filePath.includes("\0")) {
@@ -37210,10 +37210,10 @@ function path_assertNoNulPathInput(filePath, message = "path contains a NUL byte
37210
37210
  }
37211
37211
  }
37212
37212
  function path_isNotFoundPathError(value) {
37213
- return isNodeError(value) && typeof value.code === "string" && NOT_FOUND_CODES.has(value.code);
37213
+ return path_isNodeError(value) && typeof value.code === "string" && NOT_FOUND_CODES.has(value.code);
37214
37214
  }
37215
37215
  function isSymlinkOpenError(value) {
37216
- return isNodeError(value) && typeof value.code === "string" && SYMLINK_OPEN_CODES.has(value.code);
37216
+ return path_isNodeError(value) && typeof value.code === "string" && SYMLINK_OPEN_CODES.has(value.code);
37217
37217
  }
37218
37218
  function path_isPathInside(root, target) {
37219
37219
  if (process.platform === "win32") {
@@ -37370,7 +37370,7 @@ function normalizeRemovePathError(error) {
37370
37370
  if (error instanceof errors_FsSafeError) {
37371
37371
  return error;
37372
37372
  }
37373
- if (!isNodeError(error) || typeof error.code !== "string") {
37373
+ if (!path_isNodeError(error) || typeof error.code !== "string") {
37374
37374
  return normalizePinnedPathError(error);
37375
37375
  }
37376
37376
  const cause = error instanceof Error ? error : undefined;
@@ -37382,6 +37382,15 @@ function normalizeRemovePathError(error) {
37382
37382
  }
37383
37383
  return new errors_FsSafeError("not-removable", "path could not be removed", { cause });
37384
37384
  }
37385
+ function throwFsSafeReadError(error, label) {
37386
+ if (error instanceof FsSafeError) {
37387
+ throw error;
37388
+ }
37389
+ if (isNodeError(error)) {
37390
+ throw new FsSafeError("read-failed", `${label} target could not be read`, { cause: error });
37391
+ }
37392
+ throw error;
37393
+ }
37385
37394
 
37386
37395
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/directory-guard.js
37387
37396
 
@@ -37391,20 +37400,21 @@ function normalizeRemovePathError(error) {
37391
37400
 
37392
37401
 
37393
37402
 
37394
-
37395
- async function directory_guard_createAsyncDirectoryGuard(dir) {
37396
- const stat = await promises_.lstat(dir);
37403
+ async function directory_guard_createAsyncDirectoryGuard(dir, options) {
37404
+ const stat = options?.bigint ? await inspectDirectoryIdentity(dir) : external_node_fs_.lstatSync(dir);
37397
37405
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
37398
37406
  throw root_errors_directoryComponentNotDirectoryError();
37399
37407
  }
37400
- return { dir, realPath: await promises_.realpath(dir), stat };
37408
+ return { dir, realPath: external_node_fs_.realpathSync.native(dir), stat };
37401
37409
  }
37402
- async function assertAsyncDirectoryGuard(guard) {
37403
- const stat = await promises_.lstat(guard.dir);
37410
+ async function directory_guard_assertAsyncDirectoryGuard(guard) {
37411
+ const stat = typeof guard.stat.dev === "bigint" && typeof guard.stat.ino === "bigint"
37412
+ ? await inspectDirectoryIdentity(guard.dir, { dev: guard.stat.dev, ino: guard.stat.ino })
37413
+ : external_node_fs_.lstatSync(guard.dir);
37404
37414
  if (stat.isSymbolicLink() || !stat.isDirectory()) {
37405
37415
  throw root_errors_directoryComponentNotDirectoryError();
37406
37416
  }
37407
- if (!file_identity_sameFileIdentity(stat, guard.stat) || (await promises_.realpath(guard.dir)) !== guard.realPath) {
37417
+ if (!file_identity_sameFileIdentity(stat, guard.stat) || external_node_fs_.realpathSync.native(guard.dir) !== guard.realPath) {
37408
37418
  throw new errors_FsSafeError("path-mismatch", "directory changed during operation");
37409
37419
  }
37410
37420
  }
@@ -37424,12 +37434,12 @@ function directory_guard_assertSyncDirectoryGuard(guard) {
37424
37434
  throw new FsSafeError("path-mismatch", "directory changed during operation");
37425
37435
  }
37426
37436
  }
37427
- async function directory_guard_createNearestExistingDirectoryGuard(rootReal, targetPath) {
37437
+ async function directory_guard_createNearestExistingDirectoryGuard(rootReal, targetPath, options = { bigint: false }) {
37428
37438
  let current = external_node_path_.resolve(targetPath);
37429
37439
  const root = external_node_path_.resolve(rootReal);
37430
37440
  while (current !== root) {
37431
37441
  try {
37432
- return await directory_guard_createAsyncDirectoryGuard(current);
37442
+ return await directory_guard_createAsyncDirectoryGuard(current, options);
37433
37443
  }
37434
37444
  catch (error) {
37435
37445
  if (!path_isNotFoundPathError(error)) {
@@ -37438,7 +37448,7 @@ async function directory_guard_createNearestExistingDirectoryGuard(rootReal, tar
37438
37448
  current = external_node_path_.dirname(current);
37439
37449
  }
37440
37450
  }
37441
- return await directory_guard_createAsyncDirectoryGuard(root);
37451
+ return await directory_guard_createAsyncDirectoryGuard(root, options);
37442
37452
  }
37443
37453
  function directory_guard_createNearestExistingSyncDirectoryGuard(rootReal, targetPath) {
37444
37454
  let current = path.resolve(targetPath);
@@ -37458,8 +37468,8 @@ function directory_guard_createNearestExistingSyncDirectoryGuard(rootReal, targe
37458
37468
  }
37459
37469
  // Recovery receipts must retain every identity bit, including on Windows.
37460
37470
  async function inspectDirectoryIdentity(dir, expected) {
37461
- return await inspectFileIdentity(async () => {
37462
- const stat = await promises_.lstat(dir, { bigint: true });
37471
+ return await strict_file_identity_inspectFileIdentity(async () => {
37472
+ const stat = external_node_fs_.lstatSync(dir, { bigint: true });
37463
37473
  if (stat.isSymbolicLink() || !stat.isDirectory())
37464
37474
  throw root_errors_directoryComponentNotDirectoryError();
37465
37475
  return stat;
@@ -37512,11 +37522,11 @@ function assertDirectory(identity, pathname, label) {
37512
37522
  }
37513
37523
  async function createDirectoryReceipt(directoryPath, label) {
37514
37524
  const resolvedPath = external_node_path_.resolve(directoryPath);
37515
- const identity = await promises_.lstat(resolvedPath);
37525
+ const identity = external_node_fs_.lstatSync(resolvedPath);
37516
37526
  assertDirectory(identity, resolvedPath, label);
37517
37527
  return {
37518
37528
  path: resolvedPath,
37519
- realPath: await promises_.realpath(resolvedPath),
37529
+ realPath: external_node_fs_.realpathSync.native(resolvedPath),
37520
37530
  identity,
37521
37531
  };
37522
37532
  }
@@ -37531,10 +37541,10 @@ function createDirectoryReceiptSync(directoryPath, label) {
37531
37541
  };
37532
37542
  }
37533
37543
  async function assertDirectoryReceiptCurrent(receipt, label) {
37534
- const currentIdentity = await promises_.lstat(receipt.path);
37544
+ const currentIdentity = external_node_fs_.lstatSync(receipt.path);
37535
37545
  assertDirectory(currentIdentity, receipt.path, label);
37536
37546
  if (!file_identity_sameFileIdentity(receipt.identity, currentIdentity) ||
37537
- (await promises_.realpath(receipt.path)) !== receipt.realPath) {
37547
+ (external_node_fs_.realpathSync.native(receipt.path)) !== receipt.realPath) {
37538
37548
  throw new errors_FsSafeError("path-mismatch", `${label} changed during durable directory operation: ${receipt.path}`);
37539
37549
  }
37540
37550
  }
@@ -37547,7 +37557,7 @@ function assertDirectoryReceiptCurrentSync(receipt, label) {
37547
37557
  }
37548
37558
  }
37549
37559
  async function assertOpenDirectoryCurrent(handle, receipt, label) {
37550
- const openedIdentity = await handle.stat();
37560
+ const openedIdentity = external_node_fs_.fstatSync(handle.fd);
37551
37561
  assertDirectory(openedIdentity, receipt.path, label);
37552
37562
  if (!file_identity_sameFileIdentity(receipt.identity, openedIdentity)) {
37553
37563
  throw new errors_FsSafeError("path-mismatch", `${label} handle changed during directory sync: ${receipt.path}`);
@@ -37774,13 +37784,14 @@ async function ensureDurableDirectory(options) {
37774
37784
 
37775
37785
 
37776
37786
 
37787
+
37777
37788
  function isSameOrChildPath(candidate, parent) {
37778
37789
  const parentPrefix = parent.endsWith(external_node_path_.sep) ? parent : `${parent}${external_node_path_.sep}`;
37779
37790
  return candidate === parent || candidate.startsWith(parentPrefix);
37780
37791
  }
37781
37792
  async function realpathOrThrowNotFile(target) {
37782
37793
  try {
37783
- return external_node_path_.resolve(await promises_.realpath(target));
37794
+ return external_node_path_.resolve(external_node_fs_.realpathSync.native(target));
37784
37795
  }
37785
37796
  catch (error) {
37786
37797
  if (path_isNotFoundPathError(error)) {
@@ -37799,7 +37810,7 @@ async function realpathOrThrowNotFile(target) {
37799
37810
  */
37800
37811
  async function mkdirPathComponentsWithGuards(params) {
37801
37812
  const root = external_node_path_.resolve(params.rootReal);
37802
- const rootCanonical = external_node_path_.resolve(await promises_.realpath(root));
37813
+ const rootCanonical = external_node_path_.resolve(external_node_fs_.realpathSync.native(root));
37803
37814
  const target = external_node_path_.resolve(params.targetPath);
37804
37815
  const relative = external_node_path_.relative(root, target);
37805
37816
  if (isPathRelativeEscape(relative)) {
@@ -37809,18 +37820,18 @@ async function mkdirPathComponentsWithGuards(params) {
37809
37820
  for (const part of relative.split(external_node_path_.sep).filter(Boolean)) {
37810
37821
  const next = external_node_path_.join(current, part);
37811
37822
  const parentGuard = await directory_guard_createAsyncDirectoryGuard(current);
37812
- await assertAsyncDirectoryGuard(parentGuard);
37823
+ await directory_guard_assertAsyncDirectoryGuard(parentGuard);
37813
37824
  await params.beforeComponent?.(next);
37814
37825
  try {
37815
- await promises_.mkdir(next);
37826
+ await promises_.mkdir(next, { mode: params.mode });
37816
37827
  }
37817
37828
  catch (error) {
37818
37829
  if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") {
37819
37830
  throw error;
37820
37831
  }
37821
37832
  }
37822
- const stat = await promises_.lstat(next);
37823
- if (!stat.isSymbolicLink() && !stat.isDirectory()) {
37833
+ const stat = external_node_fs_.lstatSync(next);
37834
+ if ((params.rejectSymlinks && stat.isSymbolicLink()) || (!stat.isSymbolicLink() && !stat.isDirectory())) {
37824
37835
  throw root_errors_directoryComponentNotDirectoryError();
37825
37836
  }
37826
37837
  // Node's recursive mkdir follows symlinks in missing components. Build one
@@ -37839,17 +37850,17 @@ async function mkdirPathComponentsWithGuards(params) {
37839
37850
  // every subsequent segment. Callers that need the final directory
37840
37851
  // (e.g. to guard it themselves after this function returns) must use
37841
37852
  // the returned resolved path, not their own lexical parent path.
37842
- const targetStat = await promises_.stat(nextReal);
37853
+ const targetStat = external_node_fs_.statSync(nextReal);
37843
37854
  if (!targetStat.isDirectory()) {
37844
37855
  throw root_errors_directoryComponentNotDirectoryError();
37845
37856
  }
37846
37857
  await directory_guard_createAsyncDirectoryGuard(nextReal);
37847
- await assertAsyncDirectoryGuard(parentGuard);
37858
+ await directory_guard_assertAsyncDirectoryGuard(parentGuard);
37848
37859
  current = nextReal;
37849
37860
  continue;
37850
37861
  }
37851
37862
  await directory_guard_createAsyncDirectoryGuard(next);
37852
- await assertAsyncDirectoryGuard(parentGuard);
37863
+ await directory_guard_assertAsyncDirectoryGuard(parentGuard);
37853
37864
  current = next;
37854
37865
  }
37855
37866
  return current;
@@ -37862,13 +37873,13 @@ async function mkdirPathComponentsWithGuards(params) {
37862
37873
 
37863
37874
  async function withAsyncDirectoryGuards(guards, mutate, options = {}) {
37864
37875
  for (const guard of guards) {
37865
- await assertAsyncDirectoryGuard(guard);
37876
+ await directory_guard_assertAsyncDirectoryGuard(guard);
37866
37877
  }
37867
37878
  const result = await mutate();
37868
37879
  if (options.verifyAfter !== false) {
37869
37880
  try {
37870
37881
  for (const guard of guards) {
37871
- await assertAsyncDirectoryGuard(guard);
37882
+ await directory_guard_assertAsyncDirectoryGuard(guard);
37872
37883
  }
37873
37884
  }
37874
37885
  catch (error) {
@@ -37906,9 +37917,13 @@ async function guardedRename(params) {
37906
37917
  ? await createNearestExistingDirectoryGuard(params.targetRoot, path.dirname(params.to))
37907
37918
  : await createAsyncDirectoryGuard(path.dirname(params.to));
37908
37919
  await withAsyncDirectoryGuards([sourceGuard, targetGuard], async () => {
37920
+ if (params.onSourceInspected) {
37921
+ params.onSourceInspected(fsSync.lstatSync(params.from, { bigint: true }));
37922
+ }
37909
37923
  // Authority must survive all awaited guards; do not yield before rename dispatch.
37910
37924
  params.assertBeforeRename?.();
37911
37925
  await fs.rename(params.from, params.to);
37926
+ params.onRenamed?.();
37912
37927
  }, { verifyAfter: params.verifyAfter });
37913
37928
  }
37914
37929
  function guardedRenameSync(params) {
@@ -37939,13 +37954,12 @@ function guardedRmSync(params) {
37939
37954
 
37940
37955
 
37941
37956
 
37942
-
37943
37957
  function isFilesystemRoot(candidate) {
37944
37958
  return external_node_path_.parse(candidate).root === candidate;
37945
37959
  }
37946
- async function pathExists(targetPath) {
37960
+ async function root_path_existing_pathExists(targetPath) {
37947
37961
  try {
37948
- await promises_.lstat(targetPath);
37962
+ external_node_fs_.lstatSync(targetPath);
37949
37963
  return true;
37950
37964
  }
37951
37965
  catch (error) {
@@ -37959,7 +37973,7 @@ async function resolvePathViaExistingAncestor(targetPath) {
37959
37973
  const normalized = external_node_path_.resolve(targetPath);
37960
37974
  let cursor = normalized;
37961
37975
  const missingSuffix = [];
37962
- while (!isFilesystemRoot(cursor) && !(await pathExists(cursor))) {
37976
+ while (!isFilesystemRoot(cursor) && !(await root_path_existing_pathExists(cursor))) {
37963
37977
  missingSuffix.unshift(external_node_path_.basename(cursor));
37964
37978
  const parent = external_node_path_.dirname(cursor);
37965
37979
  if (parent === cursor) {
@@ -37967,11 +37981,11 @@ async function resolvePathViaExistingAncestor(targetPath) {
37967
37981
  }
37968
37982
  cursor = parent;
37969
37983
  }
37970
- if (!(await pathExists(cursor))) {
37984
+ if (!(await root_path_existing_pathExists(cursor))) {
37971
37985
  return normalized;
37972
37986
  }
37973
37987
  try {
37974
- const resolvedAncestor = external_node_path_.resolve(await promises_.realpath(cursor));
37988
+ const resolvedAncestor = external_node_path_.resolve(external_node_fs_.realpathSync.native(cursor));
37975
37989
  return missingSuffix.length === 0
37976
37990
  ? resolvedAncestor
37977
37991
  : external_node_path_.resolve(resolvedAncestor, ...missingSuffix);
@@ -38081,10 +38095,15 @@ function mergeDenyMutationPolicies(defaultPolicy, callPolicy) {
38081
38095
 
38082
38096
 
38083
38097
 
38098
+
38084
38099
  function recordFileOpenFailure(error, filePath) {
38085
38100
  recordFileObservationFailure(error, `open:${filePath}`);
38086
38101
  throw error;
38087
38102
  }
38103
+ function recordExclusiveCreateFailure(error, filePath) {
38104
+ recordFileObservationFailure(error, `exclusive-create:${filePath}`);
38105
+ throw error;
38106
+ }
38088
38107
  function openedPathResolutionError(error = new errors_FsSafeError("path-mismatch", "unable to resolve opened file path")) {
38089
38108
  recordFileObservationFailure(error, "resolution");
38090
38109
  return error;
@@ -38094,8 +38113,8 @@ async function recordPreOpenFileChange(error, handle, filePath, before, opened)
38094
38113
  ![0n, 1n].includes(before.nlink) || ![0n, 1n].includes(opened.nlink))
38095
38114
  return;
38096
38115
  try {
38097
- await inspectFileIdentity(async () => before);
38098
- const current = await inspectFileIdentity(() => handle.stat({ bigint: true }), opened);
38116
+ await strict_file_identity_inspectFileIdentity(async () => before);
38117
+ const current = await strict_file_identity_inspectFileIdentity(() => external_node_fs_.fstatSync(handle.fd, { bigint: true }), opened);
38099
38118
  if (current.isFile() && [0n, 1n].includes(current.nlink) &&
38100
38119
  (before.dev !== current.dev || before.ino !== current.ino)) {
38101
38120
  // A stale pathname sample is not proof that its former inode was unlinked.
@@ -38111,7 +38130,7 @@ async function recordOpenedFileFailure(error, handle, filePath, identity) {
38111
38130
  !identity.isFile() || identity.nlink > 1n)
38112
38131
  return;
38113
38132
  try {
38114
- const current = await inspectFileIdentity(() => handle.stat({ bigint: true }), identity);
38133
+ const current = await strict_file_identity_inspectFileIdentity(() => external_node_fs_.fstatSync(handle.fd, { bigint: true }), identity);
38115
38134
  if (current.isFile() && current.nlink === 0n)
38116
38135
  recordFileObservationFailure(error, `unlinked:${filePath}`);
38117
38136
  }
@@ -38126,24 +38145,23 @@ async function recordOpenedFileFailure(error, handle, filePath, identity) {
38126
38145
 
38127
38146
 
38128
38147
 
38148
+
38129
38149
  async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
38130
- const handleStat = await handle.stat();
38131
- return await resolveOpenedFileRealPathForFd(handle.fd, handleStat, ioPath);
38150
+ const handleStat = external_node_fs_.fstatSync(handle.fd);
38151
+ return (await resolveOpenedFileRealPathForFd(handle.fd, handleStat, ioPath)).realPath;
38132
38152
  }
38133
38153
  async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
38134
38154
  const statOptions = typeof handleStat.dev === "bigint" || typeof handleStat.ino === "bigint"
38135
38155
  ? { bigint: true } : undefined;
38136
38156
  const fdCandidates = process.platform === "linux"
38137
38157
  ? [`/proc/self/fd/${fd}`, `/dev/fd/${fd}`]
38138
- : process.platform === "win32"
38139
- ? []
38140
- : [`/dev/fd/${fd}`];
38158
+ : [];
38141
38159
  for (const fdPath of fdCandidates) {
38142
38160
  try {
38143
- const fdRealPath = await promises_.realpath(fdPath);
38144
- const fdRealStat = statOptions ? await promises_.stat(fdRealPath, statOptions) : await promises_.stat(fdRealPath);
38161
+ const fdRealPath = external_node_fs_.realpathSync.native(fdPath);
38162
+ const fdRealStat = statOptions ? external_node_fs_.statSync(fdRealPath, statOptions) : external_node_fs_.statSync(fdRealPath);
38145
38163
  if (file_identity_sameFileIdentity(handleStat, fdRealStat)) {
38146
- return fdRealPath;
38164
+ return { realPath: fdRealPath, stat: fdRealStat };
38147
38165
  }
38148
38166
  }
38149
38167
  catch {
@@ -38151,10 +38169,10 @@ async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
38151
38169
  }
38152
38170
  }
38153
38171
  try {
38154
- const ioRealPath = await promises_.realpath(ioPath);
38155
- const ioRealStat = statOptions ? await promises_.stat(ioRealPath, statOptions) : await promises_.stat(ioRealPath);
38172
+ const ioRealPath = external_node_fs_.realpathSync.native(ioPath);
38173
+ const ioRealStat = statOptions ? external_node_fs_.statSync(ioRealPath, statOptions) : external_node_fs_.statSync(ioRealPath);
38156
38174
  if (file_identity_sameFileIdentity(handleStat, ioRealStat)) {
38157
- return ioRealPath;
38175
+ return { realPath: ioRealPath, stat: ioRealStat };
38158
38176
  }
38159
38177
  }
38160
38178
  catch (err) {
@@ -38177,7 +38195,7 @@ async function resolveOpenedFileRealPathForFd(fd, handleStat, ioPath) {
38177
38195
  async function resolveOpenedFileRealPathFromParent(handleStat, ioPath, statOptions) {
38178
38196
  let parentReal;
38179
38197
  try {
38180
- parentReal = await promises_.realpath(external_node_path_.dirname(ioPath));
38198
+ parentReal = external_node_fs_.realpathSync.native(external_node_path_.dirname(ioPath));
38181
38199
  }
38182
38200
  catch (err) {
38183
38201
  if (path_isNotFoundPathError(err)) {
@@ -38198,9 +38216,12 @@ async function resolveOpenedFileRealPathFromParent(handleStat, ioPath, statOptio
38198
38216
  for (const entry of entries.toSorted()) {
38199
38217
  const candidatePath = external_node_path_.join(parentReal, entry);
38200
38218
  try {
38201
- const candidateStat = statOptions ? await promises_.lstat(candidatePath, statOptions) : await promises_.lstat(candidatePath);
38219
+ const candidateStat = statOptions ? external_node_fs_.lstatSync(candidatePath, statOptions) : external_node_fs_.lstatSync(candidatePath);
38202
38220
  if (candidateStat.isFile() && file_identity_sameFileIdentity(handleStat, candidateStat)) {
38203
- return await promises_.realpath(candidatePath);
38221
+ const realPath = external_node_fs_.realpathSync.native(candidatePath);
38222
+ const stat = statOptions ? external_node_fs_.statSync(realPath, statOptions) : external_node_fs_.statSync(realPath);
38223
+ if (file_identity_sameFileIdentity(handleStat, stat))
38224
+ return { realPath, stat };
38204
38225
  }
38205
38226
  }
38206
38227
  catch (err) {
@@ -38212,6 +38233,27 @@ async function resolveOpenedFileRealPathFromParent(handleStat, ioPath, statOptio
38212
38233
  return null;
38213
38234
  }
38214
38235
 
38236
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/file-sync.js
38237
+
38238
+ async function syncFileBestEffort(handle) {
38239
+ try {
38240
+ await handle.sync();
38241
+ }
38242
+ catch (error) {
38243
+ if (error?.code !== "EPERM")
38244
+ throw error;
38245
+ }
38246
+ }
38247
+ function syncFileBestEffortSync(fd, fsModule = external_node_fs_) {
38248
+ try {
38249
+ fsModule.fsyncSync(fd);
38250
+ }
38251
+ catch (error) {
38252
+ if (error?.code !== "EPERM")
38253
+ throw error;
38254
+ }
38255
+ }
38256
+
38215
38257
  // EXTERNAL MODULE: external "node:module"
38216
38258
  var external_node_module_ = __webpack_require__(8995);
38217
38259
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/native-config.js
@@ -38471,7 +38513,7 @@ function getNativeBinding() {
38471
38513
  }
38472
38514
  return undefined;
38473
38515
  }
38474
- function requireNativeBinding() {
38516
+ function native_requireNativeBinding() {
38475
38517
  const native = getNativeBinding();
38476
38518
  if (!native) {
38477
38519
  throw new FsSafeError("helper-unavailable", "native fs-safe helper is unavailable", {
@@ -38558,15 +38600,14 @@ function removeNativeCreatedFileIfStillPinned(params) {
38558
38600
  return;
38559
38601
  }
38560
38602
  try {
38561
- const parentPathStat = external_node_fs_.lstatSync(params.parentPath);
38562
- const parentFdStat = params.binding.fstatIdentity(params.parentFd);
38603
+ const parentPathStat = external_node_fs_.lstatSync(params.parentPath, { bigint: true });
38604
+ const parentFdStat = external_node_fs_.fstatSync(params.parentFd, { bigint: true });
38563
38605
  const targetPath = external_node_path_.join(params.parentPath, params.basename);
38564
- const target = external_node_fs_.lstatSync(targetPath);
38565
- if (!parentPathStat.isSymbolicLink() &&
38566
- parentPathStat.dev === parentFdStat.dev &&
38567
- parentPathStat.ino === parentFdStat.ino &&
38568
- !target.isSymbolicLink() &&
38569
- sameFileIdentityForCleanup(target, params.created)) {
38606
+ const target = external_node_fs_.lstatSync(targetPath, { bigint: true });
38607
+ if (!parentPathStat.isSymbolicLink() && parentPathStat.isDirectory() &&
38608
+ file_identity_sameFileIdentityForCleanup(parentPathStat, parentFdStat) &&
38609
+ !target.isSymbolicLink() && target.isFile() &&
38610
+ file_identity_sameFileIdentityForCleanup(target, params.created)) {
38570
38611
  external_node_fs_.rmSync(targetPath);
38571
38612
  }
38572
38613
  }
@@ -38603,7 +38644,7 @@ async function createNativeExclusiveFile(targetPath, mode) {
38603
38644
  }
38604
38645
  fd = opened.fd;
38605
38646
  external_node_fs_.fchmodSync(fd, mode);
38606
- created = external_node_fs_.fstatSync(fd);
38647
+ created = external_node_fs_.fstatSync(fd, { bigint: true });
38607
38648
  return wrapNativeFd(fd, opened.containment);
38608
38649
  }
38609
38650
  catch (error) {
@@ -38615,7 +38656,6 @@ async function createNativeExclusiveFile(targetPath, mode) {
38615
38656
  // Preserve the original error.
38616
38657
  }
38617
38658
  removeNativeCreatedFileIfStillPinned({
38618
- binding,
38619
38659
  parentPath,
38620
38660
  parentFd: parent.fd,
38621
38661
  basename,
@@ -38628,22 +38668,14 @@ async function createNativeExclusiveFile(targetPath, mode) {
38628
38668
  await parent.close().catch(() => undefined);
38629
38669
  }
38630
38670
  }
38631
- function syncNativeFileBestEffort(fd) {
38632
- try {
38633
- external_node_fs_.fsyncSync(fd);
38634
- }
38635
- catch (error) {
38636
- if (error.code !== "EPERM") {
38637
- throw error;
38638
- }
38639
- }
38640
- }
38641
38671
 
38642
38672
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/native-pinned-write-windows.js
38643
38673
 
38644
38674
 
38645
38675
 
38646
38676
 
38677
+
38678
+
38647
38679
  function sameNativeIdentity(left, right) {
38648
38680
  return left.dev === right.dev && left.ino === right.ino;
38649
38681
  }
@@ -38668,14 +38700,15 @@ async function runPinnedWriteWindows(binding, params, root, parentFd, parentGuar
38668
38700
  try {
38669
38701
  tempName = `.fs-safe-${(0,external_node_crypto_.randomUUID)()}.tmp`;
38670
38702
  tempFd = binding.openBeneath(parentFd, tempName, nativeOpenFlags(external_node_fs_.constants.O_WRONLY | external_node_fs_.constants.O_CREAT | external_node_fs_.constants.O_EXCL)).fd;
38671
- tempIdentity = external_node_fs_.fstatSync(tempFd);
38672
- const verificationIdentity = external_node_fs_.fstatSync(tempFd, { bigint: true });
38703
+ const verificationIdentity = strict_file_identity_inspectFileIdentitySync(() => external_node_fs_.fstatSync(tempFd, { bigint: true }));
38704
+ tempIdentity = verificationIdentity;
38673
38705
  // Creation is requested at 0600 in the binding, but a restrictive umask
38674
38706
  // can remove owner access. Keep the unpublished inode private and
38675
38707
  // reopenable until the published name has been identity-fenced.
38676
38708
  external_node_fs_.fchmodSync(tempFd, 0o600);
38677
38709
  await writeNativeInput(tempFd, params.input, params.maxBytes);
38678
- syncNativeFileBestEffort(tempFd);
38710
+ if (params.sync !== false)
38711
+ syncFileBestEffortSync(tempFd);
38679
38712
  if (params.overwrite === false) {
38680
38713
  binding.renameNoReplace(parentFd, tempName, parentFd, params.basename);
38681
38714
  }
@@ -38684,8 +38717,9 @@ async function runPinnedWriteWindows(binding, params, root, parentFd, parentGuar
38684
38717
  }
38685
38718
  renamed = true;
38686
38719
  targetFd = binding.openBeneath(parentFd, params.basename, nativeOpenFlags(external_node_fs_.constants.O_RDONLY)).fd;
38720
+ const targetStat = strict_file_identity_inspectFileIdentitySync(() => external_node_fs_.fstatSync(targetFd, { bigint: true }), verificationIdentity);
38687
38721
  const targetIdentity = binding.fstatIdentity(targetFd);
38688
- if (!targetIdentity.isFile || !sameNativeIdentity(tempIdentity, targetIdentity)) {
38722
+ if (!targetStat.isFile()) {
38689
38723
  throw new errors_FsSafeError("path-mismatch", "native write target changed after rename");
38690
38724
  }
38691
38725
  // Native exclusive creation starts at 0600. Apply the requested mode only
@@ -38693,13 +38727,13 @@ async function runPinnedWriteWindows(binding, params, root, parentFd, parentGuar
38693
38727
  // verifiable and so broader modes are never exposed before that fence.
38694
38728
  try {
38695
38729
  external_node_fs_.fchmodSync(targetFd, params.mode);
38696
- syncNativeFileBestEffort(targetFd);
38730
+ if (params.sync !== false)
38731
+ syncFileBestEffortSync(targetFd);
38697
38732
  }
38698
38733
  catch (error) {
38699
38734
  closeWriteFd(targetFd);
38700
38735
  targetFd = undefined;
38701
38736
  removeNativeCreatedFileIfStillPinned({
38702
- binding,
38703
38737
  parentPath,
38704
38738
  parentFd,
38705
38739
  basename: params.basename,
@@ -38707,7 +38741,8 @@ async function runPinnedWriteWindows(binding, params, root, parentFd, parentGuar
38707
38741
  });
38708
38742
  throw error;
38709
38743
  }
38710
- syncNativeFileBestEffort(parentFd);
38744
+ if (params.sync !== false)
38745
+ syncFileBestEffortSync(parentFd);
38711
38746
  // Verification follows publication and final chmod, outside rollback handling.
38712
38747
  await params.verifyPublished?.(targetFd, verificationIdentity, parentGuard);
38713
38748
  completed = true;
@@ -38718,7 +38753,6 @@ async function runPinnedWriteWindows(binding, params, root, parentFd, parentGuar
38718
38753
  const tempCloseError = closeWriteFd(tempFd);
38719
38754
  if (!renamed) {
38720
38755
  removeNativeCreatedFileIfStillPinned({
38721
- binding,
38722
38756
  parentPath,
38723
38757
  parentFd,
38724
38758
  basename: tempName,
@@ -38763,7 +38797,7 @@ function assertStagedDirectoryCurrent(receipt) {
38763
38797
  throw new errors_FsSafeError("path-mismatch", "staging directory pathname changed");
38764
38798
  }
38765
38799
  }
38766
- function openStagedDirectory(directory) {
38800
+ function staged_directory_openStagedDirectory(directory) {
38767
38801
  // Copy supplied facts before any asynchronous work; receipts are not authority.
38768
38802
  const pathname = path.resolve(typeof directory === "string" ? directory : directory.path);
38769
38803
  const expected = typeof directory === "string" ? undefined : {
@@ -38853,6 +38887,8 @@ var __disposeResources = (undefined && undefined.__disposeResources) || (functio
38853
38887
 
38854
38888
 
38855
38889
 
38890
+
38891
+
38856
38892
  function assertNativeStaging(binding) {
38857
38893
  if ([
38858
38894
  binding.createStagedFile,
@@ -38888,23 +38924,25 @@ class NativeStagedFile {
38888
38924
  #directory;
38889
38925
  #portableNames;
38890
38926
  #publishedMode;
38927
+ #sync;
38891
38928
  #name = `.fs-safe-${(0,external_node_crypto_.randomUUID)()}.tmp`;
38892
38929
  #state = { status: "open", publication: NOT_PUBLISHED };
38893
38930
  #receipt;
38894
- constructor(binding, parentFd, directory, portableNames, publishedMode) {
38931
+ constructor(binding, parentFd, directory, portableNames, publishedMode, sync) {
38895
38932
  this.#binding = binding;
38896
38933
  this.#parentFd = parentFd;
38897
38934
  this.#directory = directory;
38898
38935
  this.#portableNames = portableNames;
38899
38936
  this.#publishedMode = publishedMode;
38937
+ this.#sync = sync;
38900
38938
  }
38901
38939
  // Takes ownership of parentFd, including all construction and preparation failures.
38902
38940
  static async create(binding, parentFd, directory, input, mode, maxBytes,
38903
38941
  // Public staging uses portable names; existing POSIX writes accept literal names.
38904
- portableNames = true) {
38942
+ portableNames = true, sync = true) {
38905
38943
  let staged;
38906
38944
  try {
38907
- staged = new NativeStagedFile(binding, parentFd, directory, portableNames, mode);
38945
+ staged = new NativeStagedFile(binding, parentFd, directory, portableNames, mode, sync);
38908
38946
  }
38909
38947
  catch (error) {
38910
38948
  try {
@@ -38923,7 +38961,7 @@ class NativeStagedFile {
38923
38961
  try {
38924
38962
  // This owner never escapes. Only the internal verifier borrows its fd;
38925
38963
  // public descriptor methods remain await-free and cannot race disposal.
38926
- const staged = __addDisposableResource(env_1, await NativeStagedFile.create(binding, parentFd, directory, params.input, params.mode, params.maxBytes, false), true);
38964
+ const staged = __addDisposableResource(env_1, await NativeStagedFile.create(binding, parentFd, directory, params.input, params.mode, params.maxBytes, false, params.sync), true);
38927
38965
  const published = await staged.publish(params.basename, { overwrite: params.overwrite !== false });
38928
38966
  const identity = published.staged.identity;
38929
38967
  await params.verifyPublished?.(staged.#file(), identity, parentGuard);
@@ -38960,10 +38998,12 @@ class NativeStagedFile {
38960
38998
  }
38961
38999
  #assertNamed(name) {
38962
39000
  const fd = this.#file();
38963
- if (!this.#binding.stagedFileMatches(this.#parentFd, name, fd) ||
38964
- external_node_fs_.fstatSync(fd, { bigint: true }).nlink !== 1n) {
39001
+ const stat = this.#binding.stagedFileMatches(this.#parentFd, name, fd)
39002
+ ? external_node_fs_.fstatSync(fd, { bigint: true }) : undefined;
39003
+ if (!stat || stat.nlink !== 1n) {
38965
39004
  throw new errors_FsSafeError("path-mismatch", "staged entry no longer names the exclusive created file");
38966
39005
  }
39006
+ return Number(stat.mode & 4095n);
38967
39007
  }
38968
39008
  #assertCurrent() {
38969
39009
  if (this.#open().publication.status !== "not-published") {
@@ -38986,7 +39026,8 @@ class NativeStagedFile {
38986
39026
  const fd = state.fileFd;
38987
39027
  external_node_fs_.fchmodSync(fd, 0o600);
38988
39028
  await writeNativeInput(fd, input, maxBytes);
38989
- syncNativeFileBestEffort(fd);
39029
+ if (this.#sync)
39030
+ syncFileBestEffortSync(fd);
38990
39031
  const stat = external_node_fs_.fstatSync(fd, { bigint: true });
38991
39032
  this.#receipt = Object.freeze({
38992
39033
  directory: this.#directory,
@@ -39053,14 +39094,21 @@ class NativeStagedFile {
39053
39094
  overwrite,
39054
39095
  });
39055
39096
  state.publication = receipt;
39056
- this.#assertNamed(basename);
39097
+ const stagedMode = this.#assertNamed(basename);
39057
39098
  assertStagedDirectoryCurrent(this.#directory);
39058
39099
  // Keep contents private until the published name passes its identity
39059
39100
  // fence. Mode changes use the owned fd, including for final mode 000.
39060
39101
  const fd = this.#file();
39061
- external_node_fs_.fchmodSync(fd, this.#publishedMode);
39062
- syncNativeFileBestEffort(fd);
39063
- syncNativeFileBestEffort(this.#parentFd);
39102
+ if (this.#publishedMode !== 0o600 || stagedMode !== 0o600)
39103
+ external_node_fs_.fchmodSync(fd, this.#publishedMode);
39104
+ // With sync enabled, content was synced before rename. A lost chmod leaves staged 0600,
39105
+ // no wider than modes retaining owner rw. Restrictive modes and observed
39106
+ // widening of the stage still need the permission correction made durable.
39107
+ if (this.#sync && ((this.#publishedMode & 0o600) !== 0o600 || (stagedMode & ~this.#publishedMode) !== 0)) {
39108
+ syncFileBestEffortSync(fd);
39109
+ }
39110
+ if (this.#sync)
39111
+ syncFileBestEffortSync(this.#parentFd);
39064
39112
  this.#assertNamed(basename);
39065
39113
  assertStagedDirectoryCurrent(this.#directory);
39066
39114
  return receipt;
@@ -39133,6 +39181,17 @@ class NativeStagedFile {
39133
39181
  }
39134
39182
  const createNativeStage = NativeStagedFile.create;
39135
39183
  const writeNativeStage = NativeStagedFile.write;
39184
+ async function stageFileInDirectory(options) {
39185
+ if (process.platform !== "linux" && process.platform !== "darwin") {
39186
+ throw new FsSafeError("unsupported-platform", "retained-directory staging requires Linux or macOS");
39187
+ }
39188
+ const binding = requireNativeBinding();
39189
+ assertNativeStaging(binding);
39190
+ const input = { kind: "buffer", data: Buffer.from(options.content) };
39191
+ const mode = options.mode ?? 0o600;
39192
+ const parent = openStagedDirectory(options.directory);
39193
+ return await createNativeStage(binding, parent.fd, parent.receipt, input, mode);
39194
+ }
39136
39195
 
39137
39196
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/native-pinned-write.js
39138
39197
  var native_pinned_write_addDisposableResource = (undefined && undefined.__addDisposableResource) || function (env, value, async) {
@@ -39194,6 +39253,8 @@ var native_pinned_write_disposeResources = (undefined && undefined.__disposeReso
39194
39253
 
39195
39254
 
39196
39255
 
39256
+
39257
+
39197
39258
  async function runPinnedWriteNative(binding, params) {
39198
39259
  const env_1 = { stack: [], error: void 0, hasError: false };
39199
39260
  try {
@@ -39216,8 +39277,14 @@ async function runPinnedWriteNative(binding, params) {
39216
39277
  },
39217
39278
  }, false);
39218
39279
  try {
39280
+ const exactRoot = typeof params.rootIdentity?.dev === "bigint" && typeof params.rootIdentity.ino === "bigint"
39281
+ ? { dev: params.rootIdentity.dev, ino: params.rootIdentity.ino } : undefined;
39219
39282
  let rootMatches;
39220
- if (windows) {
39283
+ if (exactRoot) {
39284
+ strict_file_identity_inspectFileIdentitySync(() => external_node_fs_.fstatSync(root.fd, { bigint: true }), exactRoot);
39285
+ rootMatches = true;
39286
+ }
39287
+ else if (windows) {
39221
39288
  const identity = binding.fstatIdentity(root.fd);
39222
39289
  rootMatches = !params.rootIdentity || sameNativeIdentity(params.rootIdentity, identity);
39223
39290
  }
@@ -39232,24 +39299,26 @@ async function runPinnedWriteNative(binding, params) {
39232
39299
  binding.mkdirBeneath(root.fd, params.relativeParentPath, 0o777);
39233
39300
  }
39234
39301
  parentFd = binding.openBeneath(root.fd, params.relativeParentPath, directoryFlags).fd;
39235
- const parentPath = await promises_.realpath(params.relativeParentPath
39302
+ const parentPath = external_node_fs_.realpathSync.native(params.relativeParentPath
39236
39303
  ? external_node_path_.join(params.rootPath, ...params.relativeParentPath.split("/"))
39237
39304
  : params.rootPath);
39238
39305
  const directory = windows ? undefined : describeStagedDirectory(parentFd, parentPath);
39239
- const parentPathStat = await promises_.lstat(parentPath);
39240
- if (windows) {
39306
+ const parentPathStat = exactRoot
39307
+ ? await inspectDirectoryIdentity(parentPath, strict_file_identity_inspectFileIdentitySync(() => external_node_fs_.fstatSync(parentFd, { bigint: true })))
39308
+ : external_node_fs_.lstatSync(parentPath);
39309
+ if (windows && !exactRoot) {
39241
39310
  const parentIdentity = binding.fstatIdentity(parentFd);
39242
39311
  if (parentPathStat.isSymbolicLink() || !sameNativeIdentity(parentPathStat, parentIdentity)) {
39243
39312
  throw new errors_FsSafeError("path-mismatch", "native write parent changed during resolution");
39244
39313
  }
39245
39314
  }
39246
- else if (parentPathStat.isSymbolicLink() || !exactIdentityMatches(parentPathStat, directory.identity)) {
39315
+ else if (!windows && (parentPathStat.isSymbolicLink() || !exactIdentityMatches(parentPathStat, directory.identity))) {
39247
39316
  throw new errors_FsSafeError("path-mismatch", "native write parent changed during resolution");
39248
39317
  }
39249
39318
  const verificationGuard = { dir: parentPath, realPath: parentPath, stat: parentPathStat };
39250
39319
  if (params.overwrite === false) {
39251
39320
  try {
39252
- await promises_.lstat(external_node_path_.join(parentPath, params.basename));
39321
+ external_node_fs_.lstatSync(external_node_path_.join(parentPath, params.basename));
39253
39322
  throw Object.assign(new Error("destination already exists"), { code: "EEXIST" });
39254
39323
  }
39255
39324
  catch (error) {
@@ -39339,6 +39408,384 @@ function read_open_flags_resolveReadOpenFlags(options) {
39339
39408
  return constants.O_RDONLY | noFollow | nonBlocking;
39340
39409
  }
39341
39410
 
39411
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/replace-file-temp-owner.js
39412
+
39413
+
39414
+
39415
+
39416
+
39417
+
39418
+
39419
+
39420
+ const PUBLISHED_READ_FLAGS = read_open_flags_resolveReadOpenFlags();
39421
+ function assertOwnedFile(stat, pathname, pathnameEntry) {
39422
+ if (stat.isSymbolicLink()) {
39423
+ throw new FsSafeError("symlink", `Atomic replace owned file became a symlink: ${pathname}`);
39424
+ }
39425
+ if (!stat.isFile()) {
39426
+ throw new FsSafeError("not-file", `Atomic replace owned file must remain regular: ${pathname}`);
39427
+ }
39428
+ if (stat.nlink > 1n || (pathnameEntry && stat.nlink !== 1n)) {
39429
+ throw new FsSafeError("hardlink", `Atomic replace owned file must retain one link: ${pathname}`);
39430
+ }
39431
+ }
39432
+ function missingOwnedFile(pathname, cause) {
39433
+ return new FsSafeError("path-mismatch", `Atomic replace owned file disappeared: ${pathname}`, {
39434
+ cause,
39435
+ });
39436
+ }
39437
+ function cleanupFailure(originalError, cleanupError) {
39438
+ if (originalError !== undefined) {
39439
+ return new Error(`Atomic file replace failed (${String(originalError)}); cleanup also failed (${String(cleanupError)})`, { cause: originalError });
39440
+ }
39441
+ return cleanupError instanceof Error ? cleanupError : new Error(String(cleanupError));
39442
+ }
39443
+ async function cleanupOwnedPath(params) {
39444
+ if (!params.identity)
39445
+ return true;
39446
+ try {
39447
+ const current = params.fsModule === promises_
39448
+ ? external_node_fs_.lstatSync(params.pathname, { bigint: true })
39449
+ : await params.fsModule.lstat(params.pathname, { bigint: true });
39450
+ if (current.isSymbolicLink() ||
39451
+ !current.isFile() ||
39452
+ current.nlink !== 1n ||
39453
+ !file_identity_sameFileIdentityForCleanup(current, params.identity)) {
39454
+ return true;
39455
+ }
39456
+ await params.fsModule.unlink(params.pathname);
39457
+ return true;
39458
+ }
39459
+ catch (cleanupError) {
39460
+ if (cleanupError.code === "ENOENT")
39461
+ return true;
39462
+ if (params.throwOnCleanupError) {
39463
+ throw cleanupFailure(params.originalError, cleanupError);
39464
+ }
39465
+ return false;
39466
+ }
39467
+ }
39468
+ // Borrowed handle: the caller retains it until this best-effort cleanup finishes.
39469
+ async function cleanupPinnedFilePath(params) {
39470
+ if (!params.identity)
39471
+ return;
39472
+ try {
39473
+ const guard = params.parentGuard;
39474
+ if ([guard.stat.dev, guard.stat.ino].some((value) => typeof value === "number" && !Number.isSafeInteger(value)))
39475
+ return;
39476
+ await directory_guard_assertAsyncDirectoryGuard(guard);
39477
+ const parent = external_node_fs_.lstatSync(guard.dir, { bigint: true });
39478
+ if (parent.isSymbolicLink() || !parent.isDirectory() ||
39479
+ !file_identity_sameFileIdentityForCleanup(parent, guard.stat))
39480
+ return;
39481
+ const opened = external_node_fs_.fstatSync(params.handle.fd, { bigint: true });
39482
+ if (!opened.isFile() || opened.nlink !== 1n ||
39483
+ !file_identity_sameFileIdentityForCleanup(opened, params.identity))
39484
+ return;
39485
+ await cleanupOwnedPath({
39486
+ fsModule: promises_,
39487
+ pathname: params.pathname,
39488
+ identity: params.identity,
39489
+ throwOnCleanupError: false,
39490
+ });
39491
+ }
39492
+ catch {
39493
+ // Unverifiable authority must preserve the path and the original write failure.
39494
+ }
39495
+ }
39496
+ function cleanupOwnedPathSync(params) {
39497
+ if (!params.identity)
39498
+ return true;
39499
+ try {
39500
+ const current = params.fsModule.lstatSync(params.pathname, { bigint: true });
39501
+ if (current.isSymbolicLink() ||
39502
+ !current.isFile() ||
39503
+ current.nlink !== 1n ||
39504
+ !sameFileIdentityForCleanup(current, params.identity)) {
39505
+ return true;
39506
+ }
39507
+ params.fsModule.unlinkSync(params.pathname);
39508
+ return true;
39509
+ }
39510
+ catch (cleanupError) {
39511
+ if (cleanupError.code === "ENOENT")
39512
+ return true;
39513
+ if (params.throwOnCleanupError) {
39514
+ throw cleanupFailure(params.originalError, cleanupError);
39515
+ }
39516
+ return false;
39517
+ }
39518
+ }
39519
+ class AsyncAtomicTempOwner {
39520
+ pathname;
39521
+ #handle;
39522
+ #identity;
39523
+ #exists = false;
39524
+ #unregister;
39525
+ constructor(pathname) {
39526
+ this.pathname = pathname;
39527
+ this.#unregister = registerTempPathForExit(pathname, { singleLinkFile: true });
39528
+ }
39529
+ start() {
39530
+ this.#exists = true;
39531
+ }
39532
+ onIdentity = (identity) => {
39533
+ this.#identity = identity;
39534
+ this.#unregister.setIdentity(identity);
39535
+ };
39536
+ adopt(temp) {
39537
+ this.#handle = temp.handle;
39538
+ this.onIdentity(temp.identity);
39539
+ }
39540
+ get identity() {
39541
+ if (!this.#identity)
39542
+ throw new Error("Atomic temp owner has no identity");
39543
+ return this.#identity;
39544
+ }
39545
+ async assertCurrent(fsModule, pathname = this.pathname) {
39546
+ const opened = await inspectFileIdentity(async () => {
39547
+ const stat = fsModule === fs ? syncFs.fstatSync(this.#handle.fd, { bigint: true })
39548
+ : await this.#handle.stat({ bigint: true });
39549
+ assertOwnedFile(stat, pathname, false);
39550
+ return stat;
39551
+ }, this.identity);
39552
+ try {
39553
+ await inspectFileIdentity(async () => {
39554
+ const stat = fsModule === fs ? syncFs.lstatSync(pathname, { bigint: true })
39555
+ : await fsModule.lstat(pathname, { bigint: true });
39556
+ assertOwnedFile(stat, pathname, true);
39557
+ return stat;
39558
+ }, opened);
39559
+ }
39560
+ catch (error) {
39561
+ if (error.code === "ENOENT") {
39562
+ throw missingOwnedFile(pathname, error);
39563
+ }
39564
+ throw error;
39565
+ }
39566
+ }
39567
+ async assertPublished(fsModule, pathname, expectedHash) {
39568
+ try {
39569
+ await this.assertCurrent(fsModule, pathname);
39570
+ return;
39571
+ }
39572
+ catch (error) {
39573
+ if (!(error instanceof FsSafeError) || error.code !== "path-mismatch" || !expectedHash) {
39574
+ throw error;
39575
+ }
39576
+ }
39577
+ let published;
39578
+ try {
39579
+ try {
39580
+ published = await fsModule.open(pathname, PUBLISHED_READ_FLAGS);
39581
+ }
39582
+ catch (error) {
39583
+ if (error.code === "ELOOP") {
39584
+ throw new FsSafeError("symlink", `Atomic replace published file became a symlink: ${pathname}`, {
39585
+ cause: error,
39586
+ });
39587
+ }
39588
+ throw error;
39589
+ }
39590
+ const identity = await inspectFileIdentity(async () => {
39591
+ const stat = fsModule === fs ? syncFs.fstatSync(published.fd, { bigint: true })
39592
+ : await published.stat({ bigint: true });
39593
+ assertOwnedFile(stat, pathname, false);
39594
+ return stat;
39595
+ });
39596
+ await inspectFileIdentity(async () => {
39597
+ const stat = fsModule === fs ? syncFs.lstatSync(pathname, { bigint: true })
39598
+ : await fsModule.lstat(pathname, { bigint: true });
39599
+ assertOwnedFile(stat, pathname, true);
39600
+ return stat;
39601
+ }, identity);
39602
+ if (sha256Hex(await published.readFile()) !== expectedHash) {
39603
+ throw new FsSafeError("path-mismatch", `Atomic replace published content changed: ${pathname}`);
39604
+ }
39605
+ await this.#handle?.close();
39606
+ this.#handle = published;
39607
+ this.#identity = identity;
39608
+ published = undefined;
39609
+ }
39610
+ finally {
39611
+ await published?.close().catch(() => undefined);
39612
+ }
39613
+ }
39614
+ markRenamed() {
39615
+ this.#exists = false;
39616
+ this.#unregister();
39617
+ }
39618
+ async finish(params) {
39619
+ let deferredError;
39620
+ let cleanupComplete = !this.#exists;
39621
+ if (this.#exists) {
39622
+ try {
39623
+ cleanupComplete = await cleanupOwnedPath({
39624
+ fsModule: params.fsModule,
39625
+ pathname: this.pathname,
39626
+ identity: this.#identity,
39627
+ originalError: params.originalError,
39628
+ throwOnCleanupError: params.throwOnCleanupError,
39629
+ });
39630
+ }
39631
+ catch (error) {
39632
+ deferredError = error;
39633
+ }
39634
+ }
39635
+ if (cleanupComplete)
39636
+ this.#unregister();
39637
+ try {
39638
+ await this.#handle?.close();
39639
+ }
39640
+ catch (closeError) {
39641
+ deferredError = deferredError
39642
+ ? new AggregateError([deferredError, closeError], "Atomic temp cleanup and close failed")
39643
+ : params.originalError !== undefined
39644
+ ? new AggregateError([params.originalError, closeError], "Atomic file replace and close failed")
39645
+ : closeError;
39646
+ }
39647
+ if (deferredError)
39648
+ throw deferredError;
39649
+ }
39650
+ }
39651
+ class SyncAtomicTempOwner {
39652
+ pathname;
39653
+ #fd;
39654
+ #identity;
39655
+ #exists = false;
39656
+ #unregister;
39657
+ constructor(pathname) {
39658
+ this.pathname = pathname;
39659
+ this.#unregister = registerTempPathForExit(pathname, { singleLinkFile: true });
39660
+ }
39661
+ start() {
39662
+ this.#exists = true;
39663
+ }
39664
+ onIdentity = (identity) => {
39665
+ this.#identity = identity;
39666
+ this.#unregister.setIdentity(identity);
39667
+ };
39668
+ adopt(temp) {
39669
+ this.#fd = temp.fd;
39670
+ this.onIdentity(temp.identity);
39671
+ }
39672
+ get identity() {
39673
+ if (!this.#identity)
39674
+ throw new Error("Atomic temp owner has no identity");
39675
+ return this.#identity;
39676
+ }
39677
+ assertCurrent(fsModule, pathname = this.pathname) {
39678
+ const opened = inspectFileIdentitySync(() => {
39679
+ const stat = fsModule.fstatSync(this.#fd, { bigint: true });
39680
+ assertOwnedFile(stat, pathname, false);
39681
+ return stat;
39682
+ }, this.identity);
39683
+ try {
39684
+ inspectFileIdentitySync(() => {
39685
+ const stat = fsModule.lstatSync(pathname, { bigint: true });
39686
+ assertOwnedFile(stat, pathname, true);
39687
+ return stat;
39688
+ }, opened);
39689
+ }
39690
+ catch (error) {
39691
+ if (error.code === "ENOENT") {
39692
+ throw missingOwnedFile(pathname, error);
39693
+ }
39694
+ throw error;
39695
+ }
39696
+ }
39697
+ assertPublished(fsModule, pathname, expectedHash) {
39698
+ try {
39699
+ this.assertCurrent(fsModule, pathname);
39700
+ return;
39701
+ }
39702
+ catch (error) {
39703
+ if (!(error instanceof FsSafeError) || error.code !== "path-mismatch" || !expectedHash) {
39704
+ throw error;
39705
+ }
39706
+ }
39707
+ let publishedFd;
39708
+ try {
39709
+ try {
39710
+ publishedFd = fsModule.openSync(pathname, PUBLISHED_READ_FLAGS);
39711
+ }
39712
+ catch (error) {
39713
+ if (error.code === "ELOOP") {
39714
+ throw new FsSafeError("symlink", `Atomic replace published file became a symlink: ${pathname}`, {
39715
+ cause: error,
39716
+ });
39717
+ }
39718
+ throw error;
39719
+ }
39720
+ const identity = inspectFileIdentitySync(() => {
39721
+ const stat = fsModule.fstatSync(publishedFd, { bigint: true });
39722
+ assertOwnedFile(stat, pathname, false);
39723
+ return stat;
39724
+ });
39725
+ inspectFileIdentitySync(() => {
39726
+ const stat = fsModule.lstatSync(pathname, { bigint: true });
39727
+ assertOwnedFile(stat, pathname, true);
39728
+ return stat;
39729
+ }, identity);
39730
+ if (sha256Hex(fsModule.readFileSync(publishedFd)) !== expectedHash) {
39731
+ throw new FsSafeError("path-mismatch", `Atomic replace published content changed: ${pathname}`);
39732
+ }
39733
+ fsModule.closeSync(this.#fd);
39734
+ this.#fd = publishedFd;
39735
+ this.#identity = identity;
39736
+ publishedFd = undefined;
39737
+ }
39738
+ finally {
39739
+ if (publishedFd !== undefined) {
39740
+ try {
39741
+ fsModule.closeSync(publishedFd);
39742
+ }
39743
+ catch {
39744
+ // Best-effort close after a rejected content verification.
39745
+ }
39746
+ }
39747
+ }
39748
+ }
39749
+ markRenamed() {
39750
+ this.#exists = false;
39751
+ this.#unregister();
39752
+ }
39753
+ finish(params) {
39754
+ let deferredError;
39755
+ let cleanupComplete = !this.#exists;
39756
+ if (this.#exists) {
39757
+ try {
39758
+ cleanupComplete = cleanupOwnedPathSync({
39759
+ fsModule: params.fsModule,
39760
+ pathname: this.pathname,
39761
+ identity: this.#identity,
39762
+ originalError: params.originalError,
39763
+ throwOnCleanupError: params.throwOnCleanupError,
39764
+ });
39765
+ }
39766
+ catch (error) {
39767
+ deferredError = error;
39768
+ }
39769
+ }
39770
+ if (cleanupComplete)
39771
+ this.#unregister();
39772
+ if (this.#fd !== undefined) {
39773
+ try {
39774
+ params.fsModule.closeSync(this.#fd);
39775
+ }
39776
+ catch (closeError) {
39777
+ deferredError = deferredError
39778
+ ? new AggregateError([deferredError, closeError], "Atomic temp cleanup and close failed")
39779
+ : params.originalError !== undefined
39780
+ ? new AggregateError([params.originalError, closeError], "Atomic file replace and close failed")
39781
+ : closeError;
39782
+ }
39783
+ }
39784
+ if (deferredError)
39785
+ throw deferredError;
39786
+ }
39787
+ }
39788
+
39342
39789
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/bounded-read.js
39343
39790
 
39344
39791
 
@@ -39363,11 +39810,24 @@ function appendChunk(params) {
39363
39810
  params.chunks.push(Buffer.from(params.scratch.subarray(0, params.bytesRead)));
39364
39811
  return total;
39365
39812
  }
39366
- async function readBoundedAsync(maxBytes, readChunk) {
39813
+ async function readBoundedAsync(maxBytes, readChunk, observeRegularFileSize) {
39367
39814
  byte_budget_normalizeMaxBytes(maxBytes);
39368
39815
  const chunks = [];
39369
- const scratch = createScratchBuffer(maxBytes);
39370
39816
  let total = 0;
39817
+ const size = observeRegularFileSize?.();
39818
+ if (size !== undefined) {
39819
+ const first = Buffer.allocUnsafe(Math.min(maxBytes, size) + 1);
39820
+ const bytesRead = await readChunk(first, first.length);
39821
+ if (bytesRead === 0)
39822
+ return first.subarray(0, 0);
39823
+ // Short reads can occur before EOF. Only accept one when a fresh fd size
39824
+ // observation proves we consumed at least the entire current file size.
39825
+ const currentSize = bytesRead < first.length ? observeRegularFileSize?.() : undefined;
39826
+ if (currentSize !== undefined && bytesRead >= currentSize)
39827
+ return first.subarray(0, bytesRead);
39828
+ total = appendChunk({ chunks, scratch: first, bytesRead, total, maxBytes });
39829
+ }
39830
+ const scratch = createScratchBuffer(maxBytes);
39371
39831
  while (true) {
39372
39832
  const length = nextReadLength(total, maxBytes, scratch.length);
39373
39833
  const bytesRead = await readChunk(scratch, length);
@@ -39383,9 +39843,22 @@ async function readBoundedAsync(maxBytes, readChunk) {
39383
39843
  * force an unbounded allocation.
39384
39844
  */
39385
39845
  async function readFileHandleBounded(handle, maxBytes) {
39846
+ byte_budget_normalizeMaxBytes(maxBytes);
39847
+ const fd = "fd" in handle && typeof handle.fd === "number" ? handle.fd : undefined;
39386
39848
  return await readBoundedAsync(maxBytes, async (scratch, length) => {
39387
39849
  return (await handle.read(scratch, 0, length, null)).bytesRead;
39388
- });
39850
+ }, fd === undefined ? undefined : () => regularFileSize(fd));
39851
+ }
39852
+ function regularFileSize(fd) {
39853
+ try {
39854
+ const stat = external_node_fs_.fstatSync(fd);
39855
+ return stat.isFile() && Number.isSafeInteger(stat.size) && stat.size >= 0
39856
+ ? stat.size : undefined;
39857
+ }
39858
+ catch {
39859
+ // Size is only an optimization hint; retain the reader's original errors.
39860
+ return undefined;
39861
+ }
39389
39862
  }
39390
39863
  function readDescriptorChunk(fd, scratch, length) {
39391
39864
  return new Promise((resolve, reject) => {
@@ -39400,9 +39873,10 @@ function readDescriptorChunk(fd, scratch, length) {
39400
39873
  }
39401
39874
  /** Async bounded read from a numeric descriptor. The caller owns the descriptor. */
39402
39875
  async function readFileDescriptorBounded(fd, maxBytes) {
39876
+ normalizeMaxBytes(maxBytes);
39403
39877
  return await readBoundedAsync(maxBytes, async (scratch, length) => {
39404
39878
  return await readDescriptorChunk(fd, scratch, length);
39405
- });
39879
+ }, () => regularFileSize(fd));
39406
39880
  }
39407
39881
  /** Sync bounded read from a numeric descriptor. The caller owns the descriptor. */
39408
39882
  function bounded_read_readFileDescriptorBoundedSync(fd, maxBytes) {
@@ -39420,11 +39894,19 @@ function bounded_read_readFileDescriptorBoundedSync(fd, maxBytes) {
39420
39894
  }
39421
39895
  }
39422
39896
 
39897
+ // EXTERNAL MODULE: external "node:os"
39898
+ var external_node_os_ = __webpack_require__(8161);
39423
39899
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/error-detail.js
39900
+
39424
39901
  const UNSAFE_ERROR_DETAIL_CHARACTERS = /[\u0000-\u001f\u007f-\u009f\u2028\u2029]/gu;
39425
39902
  function formatErrorDetail(value) {
39426
39903
  return value.replace(UNSAFE_ERROR_DETAIL_CHARACTERS, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`);
39427
39904
  }
39905
+ function shortPath(value) {
39906
+ const home = external_node_os_.homedir();
39907
+ const shortened = value.startsWith(home) ? `~${value.slice(home.length)}` : value;
39908
+ return formatErrorDetail(shortened);
39909
+ }
39428
39910
 
39429
39911
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/root-path-symlink.js
39430
39912
 
@@ -39432,9 +39914,9 @@ function formatErrorDetail(value) {
39432
39914
 
39433
39915
 
39434
39916
 
39435
-
39436
- function normalizeSymlinkResolutionError(error) {
39437
- if (isSymlinkOpenError(error)) {
39917
+ function normalizeSymlinkResolutionError(error, options) {
39918
+ if (isSymlinkOpenError(error) ||
39919
+ (options.rejectUnresolved && path_isNotFoundPathError(error))) {
39438
39920
  throw new errors_FsSafeError("symlink", "symlink path could not be resolved", {
39439
39921
  cause: error instanceof Error ? error : undefined,
39440
39922
  });
@@ -39442,22 +39924,22 @@ function normalizeSymlinkResolutionError(error) {
39442
39924
  if (!path_isNotFoundPathError(error))
39443
39925
  throw error;
39444
39926
  }
39445
- async function resolveSymlinkHopPath(symlinkPath) {
39927
+ async function resolveSymlinkHopPath(symlinkPath, options = {}) {
39446
39928
  try {
39447
- return external_node_path_.resolve(await promises_.realpath(symlinkPath));
39929
+ return external_node_path_.resolve(external_node_fs_.realpathSync.native(symlinkPath));
39448
39930
  }
39449
39931
  catch (error) {
39450
- normalizeSymlinkResolutionError(error);
39451
- const linkTarget = await promises_.readlink(symlinkPath);
39932
+ normalizeSymlinkResolutionError(error, options);
39933
+ const linkTarget = external_node_fs_.readlinkSync(symlinkPath);
39452
39934
  return resolvePathViaExistingAncestor(external_node_path_.resolve(external_node_path_.dirname(symlinkPath), linkTarget));
39453
39935
  }
39454
39936
  }
39455
- function root_path_symlink_resolveSymlinkHopPathSync(symlinkPath) {
39937
+ function root_path_symlink_resolveSymlinkHopPathSync(symlinkPath, options = {}) {
39456
39938
  try {
39457
39939
  return path.resolve(fs.realpathSync(symlinkPath));
39458
39940
  }
39459
39941
  catch (error) {
39460
- normalizeSymlinkResolutionError(error);
39942
+ normalizeSymlinkResolutionError(error, options);
39461
39943
  const linkTarget = fs.readlinkSync(symlinkPath);
39462
39944
  return resolvePathViaExistingAncestorSync(path.resolve(path.dirname(symlinkPath), linkTarget));
39463
39945
  }
@@ -39540,17 +40022,6 @@ function assertSafePathPrefix(prefix, options = {}) {
39540
40022
  });
39541
40023
  }
39542
40024
 
39543
- // EXTERNAL MODULE: external "node:os"
39544
- var external_node_os_ = __webpack_require__(8161);
39545
- ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/short-path.js
39546
-
39547
-
39548
- function shortPath(value) {
39549
- const home = external_node_os_.homedir();
39550
- const shortened = value.startsWith(home) ? `~${value.slice(home.length)}` : value;
39551
- return formatErrorDetail(shortened);
39552
- }
39553
-
39554
40025
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/root-path.js
39555
40026
 
39556
40027
 
@@ -39561,8 +40032,6 @@ function shortPath(value) {
39561
40032
 
39562
40033
 
39563
40034
 
39564
-
39565
-
39566
40035
  const ROOT_PATH_ALIAS_POLICIES = {
39567
40036
  strict: Object.freeze({
39568
40037
  allowFinalSymlinkForUnlink: false,
@@ -39573,7 +40042,7 @@ const ROOT_PATH_ALIAS_POLICIES = {
39573
40042
  allowFinalHardlinkForUnlink: true,
39574
40043
  }),
39575
40044
  };
39576
- async function resolveRootPath(params) {
40045
+ async function root_path_resolveRootPath(params) {
39577
40046
  try {
39578
40047
  return await resolveRootPathInternal(params);
39579
40048
  }
@@ -39674,12 +40143,6 @@ function assertNoEmbeddedDriveRelativeSegment(filePath, label) {
39674
40143
  const root = external_node_path_.parse(filePath).root;
39675
40144
  assertNoDriveRelativePathSegments(filePath.slice(root.length).replaceAll("\\", "/"), label);
39676
40145
  }
39677
- function isPromiseLike(value) {
39678
- return Boolean(value &&
39679
- (typeof value === "object" || typeof value === "function") &&
39680
- "then" in value &&
39681
- typeof value.then === "function");
39682
- }
39683
40146
  function createLexicalTraversalState(params) {
39684
40147
  const rawAbsolutePath = params.params.absolutePath;
39685
40148
  const rawRelativePath = rawPathRelativeToRoot(params.rootPath, rawAbsolutePath);
@@ -39759,26 +40222,13 @@ function handleLexicalLstatFailure(context, error, missingFromIndex) {
39759
40222
  applyMissingSuffixToCanonicalCursor(context, missingFromIndex);
39760
40223
  return true;
39761
40224
  }
39762
- function handleLexicalStatReadFailure(context, error, missingFromIndex) {
39763
- if (handleLexicalLstatFailure(context, error, missingFromIndex)) {
39764
- return null;
39765
- }
39766
- throw error;
39767
- }
39768
- function handleLexicalStatDisposition(context, params) {
39769
- if (!params.isSymbolicLink) {
39770
- advanceCanonicalCursorForSegment(context, params.segment);
40225
+ function lexicalStatDisposition(params) {
40226
+ if (!params.isSymbolicLink)
39771
40227
  return "continue";
39772
- }
39773
- if (context.resolveParams.rejectSymlinks === true && params.isLast) {
40228
+ if (params.rejectSymlinks === true && params.isLast) {
39774
40229
  throw new errors_FsSafeError("symlink", "symlink path component not allowed");
39775
40230
  }
39776
- if (context.state.allowFinalSymlink && params.isLast) {
39777
- context.state.preserveFinalSymlink = true;
39778
- advanceCanonicalCursorForSegment(context, params.segment);
39779
- return "break";
39780
- }
39781
- return "resolve-link";
40231
+ return params.allowFinalSymlink && params.isLast ? "break" : "resolve-link";
39782
40232
  }
39783
40233
  function applyResolvedSymlinkHop(context, linkCanonical) {
39784
40234
  if (!path_isPathInside(context.rootCanonicalPath, linkCanonical)) {
@@ -39791,68 +40241,48 @@ function applyResolvedSymlinkHop(context, linkCanonical) {
39791
40241
  context.state.canonicalCursor = linkCanonical;
39792
40242
  context.state.lexicalCursor = linkCanonical;
39793
40243
  }
39794
- function readLexicalStat(context, params) {
39795
- try {
39796
- const stat = params.read(context.state.lexicalCursor);
39797
- if (isPromiseLike(stat)) {
39798
- return Promise.resolve(stat).catch((error) => handleLexicalStatReadFailure(context, error, params.missingFromIndex));
39799
- }
39800
- return stat;
39801
- }
39802
- catch (error) {
39803
- return handleLexicalStatReadFailure(context, error, params.missingFromIndex);
39804
- }
39805
- }
39806
- function resolveAndApplySymlinkHop(context, params) {
39807
- const linkCanonical = params.resolveLinkCanonical(context.state.lexicalCursor);
39808
- if (isPromiseLike(linkCanonical)) {
39809
- return Promise.resolve(linkCanonical).then((value) => {
39810
- applyResolvedSymlinkHop(context, value);
39811
- });
39812
- }
39813
- applyResolvedSymlinkHop(context, linkCanonical);
39814
- }
39815
40244
  function applyParentTraversalStep(context) {
39816
40245
  context.state.lexicalCursor = external_node_path_.resolve(context.state.lexicalCursor, "..");
39817
40246
  advanceCanonicalCursorForSegment(context, "..");
39818
40247
  }
39819
- function* iterateLexicalTraversal(state) {
39820
- for (let idx = 0; idx < state.segments.length; idx += 1) {
39821
- const segment = state.segments[idx] ?? "";
39822
- const isLast = idx === state.segments.length - 1;
39823
- yield { idx, segment, isLast };
39824
- }
39825
- }
39826
40248
  async function resolveRootPathLexicalAsync(params) {
39827
40249
  const context = createLexicalTraversalContext(params);
39828
40250
  const { state } = context;
39829
- for (const { idx, segment, isLast } of iterateLexicalTraversal(state)) {
40251
+ for (let idx = 0; idx < state.segments.length; idx += 1) {
40252
+ const segment = state.segments[idx] ?? "";
40253
+ const isLast = idx === state.segments.length - 1;
39830
40254
  if (segment === "..") {
39831
40255
  applyParentTraversalStep(context);
39832
40256
  continue;
39833
40257
  }
39834
40258
  state.lexicalCursor = external_node_path_.join(state.lexicalCursor, segment);
39835
- const stat = await readLexicalStat(context, {
39836
- missingFromIndex: idx,
39837
- read: (cursor) => promises_.lstat(cursor),
39838
- });
39839
- if (!stat) {
39840
- break;
40259
+ let stat;
40260
+ try {
40261
+ stat = external_node_fs_.lstatSync(state.lexicalCursor);
39841
40262
  }
39842
- const disposition = handleLexicalStatDisposition(context, {
39843
- isSymbolicLink: stat.isSymbolicLink(),
39844
- segment,
40263
+ catch (error) {
40264
+ if (handleLexicalLstatFailure(context, error, idx))
40265
+ break;
40266
+ throw error;
40267
+ }
40268
+ const isSymbolicLink = stat.isSymbolicLink();
40269
+ const disposition = lexicalStatDisposition({
40270
+ isSymbolicLink,
39845
40271
  isLast,
40272
+ rejectSymlinks: isSymbolicLink ? context.resolveParams.rejectSymlinks : undefined,
40273
+ allowFinalSymlink: state.allowFinalSymlink,
39846
40274
  });
39847
- if (disposition === "continue") {
40275
+ if (disposition !== "resolve-link") {
40276
+ state.preserveFinalSymlink = disposition === "break";
40277
+ advanceCanonicalCursorForSegment(context, segment);
40278
+ if (state.preserveFinalSymlink)
40279
+ break;
39848
40280
  continue;
39849
40281
  }
39850
- if (disposition === "break") {
39851
- break;
39852
- }
39853
- await resolveAndApplySymlinkHop(context, {
39854
- resolveLinkCanonical: (cursor) => resolveSymlinkHopPath(cursor),
40282
+ const linkCanonical = await resolveSymlinkHopPath(state.lexicalCursor, {
40283
+ rejectUnresolved: context.resolveParams.rejectUnresolvedSymlinks,
39855
40284
  });
40285
+ applyResolvedSymlinkHop(context, linkCanonical);
39856
40286
  if (context.resolveParams.rejectSymlinks === true) {
39857
40287
  throw new errors_FsSafeError("symlink", "symlink path component not allowed");
39858
40288
  }
@@ -39871,34 +40301,33 @@ function resolveRootPathLexicalSync(params) {
39871
40301
  continue;
39872
40302
  }
39873
40303
  state.lexicalCursor = path.join(state.lexicalCursor, segment);
39874
- const maybeStat = readLexicalStat(context, {
39875
- missingFromIndex: idx,
39876
- read: (cursor) => fs.lstatSync(cursor),
39877
- });
39878
- if (isPromiseLike(maybeStat)) {
39879
- throw new Error("Unexpected async lexical stat");
40304
+ let stat;
40305
+ try {
40306
+ stat = fs.lstatSync(state.lexicalCursor);
39880
40307
  }
39881
- const stat = maybeStat;
39882
- if (!stat) {
39883
- break;
40308
+ catch (error) {
40309
+ if (handleLexicalLstatFailure(context, error, idx))
40310
+ break;
40311
+ throw error;
39884
40312
  }
39885
- const disposition = handleLexicalStatDisposition(context, {
39886
- isSymbolicLink: stat.isSymbolicLink(),
39887
- segment,
40313
+ const isSymbolicLink = stat.isSymbolicLink();
40314
+ const disposition = lexicalStatDisposition({
40315
+ isSymbolicLink,
39888
40316
  isLast,
40317
+ rejectSymlinks: isSymbolicLink ? context.resolveParams.rejectSymlinks : undefined,
40318
+ allowFinalSymlink: state.allowFinalSymlink,
39889
40319
  });
39890
- if (disposition === "continue") {
40320
+ if (disposition !== "resolve-link") {
40321
+ state.preserveFinalSymlink = disposition === "break";
40322
+ advanceCanonicalCursorForSegment(context, segment);
40323
+ if (state.preserveFinalSymlink)
40324
+ break;
39891
40325
  continue;
39892
40326
  }
39893
- if (disposition === "break") {
39894
- break;
39895
- }
39896
- const maybeApplied = resolveAndApplySymlinkHop(context, {
39897
- resolveLinkCanonical: (cursor) => resolveSymlinkHopPathSync(cursor),
40327
+ const linkCanonical = resolveSymlinkHopPathSync(state.lexicalCursor, {
40328
+ rejectUnresolved: context.resolveParams.rejectUnresolvedSymlinks,
39898
40329
  });
39899
- if (isPromiseLike(maybeApplied)) {
39900
- throw new Error("Unexpected async symlink resolution");
39901
- }
40330
+ applyResolvedSymlinkHop(context, linkCanonical);
39902
40331
  if (context.resolveParams.rejectSymlinks === true) {
39903
40332
  throw new FsSafeError("symlink", "symlink path component not allowed");
39904
40333
  }
@@ -40018,8 +40447,8 @@ function buildResolvedRootPath(params) {
40018
40447
  async function getPathKind(absolutePath, preserveFinalSymlink) {
40019
40448
  try {
40020
40449
  const stat = preserveFinalSymlink
40021
- ? await promises_.lstat(absolutePath)
40022
- : await promises_.stat(absolutePath);
40450
+ ? external_node_fs_.lstatSync(absolutePath)
40451
+ : external_node_fs_.statSync(absolutePath);
40023
40452
  return { exists: true, kind: toResolvedKind(stat) };
40024
40453
  }
40025
40454
  catch (error) {
@@ -40085,7 +40514,7 @@ function symlinkEscapeError(params) {
40085
40514
 
40086
40515
  async function openSidecarRoot(lockRoot, relative, discardObservation, onOpenFailure) {
40087
40516
  const resolved = await lockRoot.resolve(relative);
40088
- const canonicalPath = async () => (await resolveRootPath({
40517
+ const canonicalPath = async () => (await root_path_resolveRootPath({
40089
40518
  absolutePath: resolved,
40090
40519
  rootPath: lockRoot.rootReal,
40091
40520
  rootCanonicalPath: lockRoot.rootReal,
@@ -40202,10 +40631,12 @@ function readSidecarLockOwnershipToken(raw) {
40202
40631
  }
40203
40632
  function serializeSidecarLockPayload(payload) {
40204
40633
  const ownershipToken = createSidecarLockOwnershipToken();
40205
- return {
40206
- raw: `${JSON.stringify(payload, null, 2)}\n${ownershipToken}\n`,
40207
- ownershipToken,
40208
- };
40634
+ const raw = `${JSON.stringify(payload, null, 2)}\n${ownershipToken}\n`;
40635
+ const bytes = Buffer.byteLength(raw, "utf8");
40636
+ if (bytes > MAX_LOCK_PAYLOAD_BYTES) {
40637
+ throw new errors_FsSafeError("too-large", `sidecar lock payload exceeds limit of ${MAX_LOCK_PAYLOAD_BYTES} bytes (got ${bytes})`);
40638
+ }
40639
+ return { raw, ownershipToken };
40209
40640
  }
40210
40641
  function relativeSidecarLockPath(lockRoot, lockPath) {
40211
40642
  const resolved = external_node_path_.resolve(lockPath);
@@ -40260,7 +40691,13 @@ async function readSidecarLockRawSnapshot(lockPath, options = {}) {
40260
40691
  await opened.handle.close().catch(() => undefined);
40261
40692
  }
40262
40693
  }
40263
- const before = await promises_.lstat(lockPath).catch(missingSnapshotPath);
40694
+ let before;
40695
+ try {
40696
+ before = external_node_fs_.lstatSync(lockPath);
40697
+ }
40698
+ catch (error) {
40699
+ before = missingSnapshotPath(error);
40700
+ }
40264
40701
  if (!before)
40265
40702
  return null;
40266
40703
  if (!before.isFile() || before.isSymbolicLink()) {
@@ -40289,7 +40726,7 @@ async function readSidecarLockRawSnapshot(lockPath, options = {}) {
40289
40726
  options.onOpenFailure?.(error);
40290
40727
  throw error;
40291
40728
  }
40292
- const opened = await handle.stat();
40729
+ const opened = external_node_fs_.fstatSync(handle.fd);
40293
40730
  if (!opened.isFile()) {
40294
40731
  if (options.rejectNonFile) {
40295
40732
  throw new errors_FsSafeError("not-file", `sidecar lock is not a regular file: ${lockPath}`);
@@ -40299,7 +40736,13 @@ async function readSidecarLockRawSnapshot(lockPath, options = {}) {
40299
40736
  if (!options.allowDescriptorIdentityDrift && !file_identity_sameFileIdentity(before, opened))
40300
40737
  return null;
40301
40738
  const raw = (await readFileHandleBounded(handle, MAX_LOCK_PAYLOAD_BYTES)).toString("utf8");
40302
- const after = await promises_.lstat(lockPath).catch(missingSnapshotPath);
40739
+ let after;
40740
+ try {
40741
+ after = external_node_fs_.lstatSync(lockPath);
40742
+ }
40743
+ catch (error) {
40744
+ after = missingSnapshotPath(error);
40745
+ }
40303
40746
  if (!after || !after.isFile() || !file_identity_sameFileIdentity(before, after))
40304
40747
  return null;
40305
40748
  return { raw, stat: after };
@@ -40411,7 +40854,7 @@ async function sidecarLockSnapshotStillPresent(lockPath, observed, options = {})
40411
40854
  }
40412
40855
  async function sidecarReclaimGuardExists(pathname) {
40413
40856
  try {
40414
- await promises_.lstat(pathname);
40857
+ external_node_fs_.lstatSync(pathname);
40415
40858
  return true;
40416
40859
  }
40417
40860
  catch (err) {
@@ -40474,6 +40917,315 @@ async function removeStaleSidecarLockIfAllowed(params) {
40474
40917
  }
40475
40918
  }
40476
40919
 
40920
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/absolute-path.js
40921
+
40922
+
40923
+
40924
+
40925
+
40926
+
40927
+
40928
+ function resolveSymlinkPolicy(policy) {
40929
+ if (policy === undefined)
40930
+ return "reject";
40931
+ if (policy !== "reject" && policy !== "follow") {
40932
+ throw new TypeError(`invalid absolute path symlink policy: ${String(policy)}`);
40933
+ }
40934
+ return policy;
40935
+ }
40936
+ function ensureDirectoryFailure(code, message, cause) {
40937
+ return {
40938
+ ok: false,
40939
+ code,
40940
+ error: new FsSafeError(code, message, { cause }),
40941
+ };
40942
+ }
40943
+ async function assertGuardResult(guard, scopeLabel) {
40944
+ try {
40945
+ await assertAsyncDirectoryGuard(guard);
40946
+ return { ok: true };
40947
+ }
40948
+ catch (err) {
40949
+ if (err instanceof FsSafeError) {
40950
+ return await directoryGuardFailure(err, guard.dir, scopeLabel);
40951
+ }
40952
+ throw err;
40953
+ }
40954
+ }
40955
+ async function createDirectoryGuardResult(dir, scopeLabel) {
40956
+ try {
40957
+ return { ok: true, guard: await createAsyncDirectoryGuard(dir) };
40958
+ }
40959
+ catch (err) {
40960
+ if (err instanceof FsSafeError) {
40961
+ return await directoryGuardFailure(err, dir, scopeLabel);
40962
+ }
40963
+ throw err;
40964
+ }
40965
+ }
40966
+ function classifyDirectoryLookupError(err, scopeLabel) {
40967
+ const code = err.code;
40968
+ if (code === "ENOENT") {
40969
+ return ensureDirectoryFailure("not-found", `directory path must have a real existing ancestor within ${scopeLabel}`, err);
40970
+ }
40971
+ if (code === "ENOTDIR") {
40972
+ return ensureDirectoryFailure("not-file", `path must be a real directory within ${scopeLabel}`, err);
40973
+ }
40974
+ return null;
40975
+ }
40976
+ function classifyExistingDirectorySegment(stat, scopeLabel) {
40977
+ if (stat.isSymbolicLink()) {
40978
+ return ensureDirectoryFailure("symlink", `directory path traverses a symlink within ${scopeLabel}`);
40979
+ }
40980
+ if (!stat.isDirectory()) {
40981
+ return ensureDirectoryFailure("not-file", `path must be a real directory within ${scopeLabel}`);
40982
+ }
40983
+ return null;
40984
+ }
40985
+ async function directoryGuardFailure(err, dir, scopeLabel) {
40986
+ if (err.code !== "not-file") {
40987
+ return { ok: false, code: err.code, error: err };
40988
+ }
40989
+ try {
40990
+ const stat = fsSync.lstatSync(dir);
40991
+ const failure = classifyExistingDirectorySegment(stat, scopeLabel);
40992
+ if (failure) {
40993
+ return failure;
40994
+ }
40995
+ }
40996
+ catch (lookupErr) {
40997
+ const failure = classifyDirectoryLookupError(lookupErr, scopeLabel);
40998
+ if (failure) {
40999
+ return failure;
41000
+ }
41001
+ throw lookupErr;
41002
+ }
41003
+ return { ok: false, code: err.code, error: err };
41004
+ }
41005
+ async function resolveTrustedDirectoryPrefix(targetPath, scopeLabel) {
41006
+ const root = path.parse(targetPath).root;
41007
+ let current = root;
41008
+ let currentStat;
41009
+ try {
41010
+ currentStat = fsSync.lstatSync(current);
41011
+ }
41012
+ catch (err) {
41013
+ const failure = classifyDirectoryLookupError(err, scopeLabel);
41014
+ if (failure) {
41015
+ return failure;
41016
+ }
41017
+ throw err;
41018
+ }
41019
+ const rootFailure = classifyExistingDirectorySegment(currentStat, scopeLabel);
41020
+ if (rootFailure) {
41021
+ return rootFailure;
41022
+ }
41023
+ // Walk forward with lstat. Looking backward for the "nearest existing
41024
+ // ancestor" can cross an existing suffix through a symlinked parent before
41025
+ // this helper gets a chance to reject that parent.
41026
+ const segments = path.relative(root, targetPath).split(path.sep).filter(Boolean);
41027
+ for (let index = 0; index < segments.length; index += 1) {
41028
+ const segment = segments[index];
41029
+ if (!segment) {
41030
+ continue;
41031
+ }
41032
+ const next = path.join(current, segment);
41033
+ try {
41034
+ const nextStat = fsSync.lstatSync(next);
41035
+ const segmentFailure = classifyExistingDirectorySegment(nextStat, scopeLabel);
41036
+ if (segmentFailure) {
41037
+ return segmentFailure;
41038
+ }
41039
+ current = next;
41040
+ currentStat = nextStat;
41041
+ }
41042
+ catch (err) {
41043
+ const code = err.code;
41044
+ if (code === "ENOENT") {
41045
+ return {
41046
+ ok: true,
41047
+ ancestorPath: current,
41048
+ missingSegments: segments.slice(index),
41049
+ };
41050
+ }
41051
+ const failure = classifyDirectoryLookupError(err, scopeLabel);
41052
+ if (failure) {
41053
+ return failure;
41054
+ }
41055
+ throw err;
41056
+ }
41057
+ }
41058
+ return { ok: true, ancestorPath: current, missingSegments: [] };
41059
+ }
41060
+ function assertAbsolutePathInput(filePath) {
41061
+ if (!filePath) {
41062
+ throw new FsSafeError("invalid-path", "path is required");
41063
+ }
41064
+ if (filePath.includes("\0")) {
41065
+ throw new FsSafeError("invalid-path", "path must not contain NUL bytes");
41066
+ }
41067
+ if (!path.isAbsolute(filePath)) {
41068
+ throw new FsSafeError("invalid-path", "path must be absolute");
41069
+ }
41070
+ return path.normalize(filePath);
41071
+ }
41072
+ async function findExistingAncestor(filePath) {
41073
+ return (await findExistingAncestorWithStat(filePath))?.path ?? null;
41074
+ }
41075
+ async function findExistingAncestorWithStat(filePath) {
41076
+ let current = external_node_path_.resolve(filePath);
41077
+ while (true) {
41078
+ try {
41079
+ return { path: current, stat: external_node_fs_.lstatSync(current) };
41080
+ }
41081
+ catch (err) {
41082
+ if (err.code !== "ENOENT") {
41083
+ throw err;
41084
+ }
41085
+ }
41086
+ const parent = external_node_path_.dirname(current);
41087
+ if (parent === current) {
41088
+ return null;
41089
+ }
41090
+ current = parent;
41091
+ }
41092
+ }
41093
+ async function absolute_path_ensureAbsoluteDirectory(dirPath, options = {}) {
41094
+ const scopeLabel = options.scopeLabel ?? "directory";
41095
+ let targetPath;
41096
+ try {
41097
+ targetPath = assertAbsolutePathInput(dirPath);
41098
+ }
41099
+ catch (err) {
41100
+ if (err instanceof FsSafeError) {
41101
+ return { ok: false, code: err.code, error: err };
41102
+ }
41103
+ throw err;
41104
+ }
41105
+ const prefix = await resolveTrustedDirectoryPrefix(targetPath, scopeLabel);
41106
+ if (!prefix.ok) {
41107
+ return prefix;
41108
+ }
41109
+ let current = prefix.ancestorPath;
41110
+ const initialGuard = await createDirectoryGuardResult(prefix.ancestorPath, scopeLabel);
41111
+ if (!initialGuard.ok) {
41112
+ return initialGuard;
41113
+ }
41114
+ let currentGuard = initialGuard.guard;
41115
+ for (const segment of prefix.missingSegments) {
41116
+ current = path.join(current, segment);
41117
+ while (true) {
41118
+ const guardResult = await assertGuardResult(currentGuard, scopeLabel);
41119
+ if (!guardResult.ok) {
41120
+ return guardResult;
41121
+ }
41122
+ try {
41123
+ const stat = fsSync.lstatSync(current);
41124
+ if (stat.isSymbolicLink()) {
41125
+ return ensureDirectoryFailure("symlink", `directory path traverses a symlink within ${scopeLabel}`);
41126
+ }
41127
+ if (!stat.isDirectory()) {
41128
+ return ensureDirectoryFailure("not-file", `path must be a real directory within ${scopeLabel}`);
41129
+ }
41130
+ break;
41131
+ }
41132
+ catch (err) {
41133
+ if (err.code !== "ENOENT") {
41134
+ throw err;
41135
+ }
41136
+ const parentStillValid = await assertGuardResult(currentGuard, scopeLabel);
41137
+ if (!parentStillValid.ok) {
41138
+ return parentStillValid;
41139
+ }
41140
+ try {
41141
+ await fs.mkdir(current, { mode: options.mode });
41142
+ }
41143
+ catch (mkdirErr) {
41144
+ if (mkdirErr.code === "EEXIST") {
41145
+ continue;
41146
+ }
41147
+ throw mkdirErr;
41148
+ }
41149
+ }
41150
+ }
41151
+ const nextGuard = await createDirectoryGuardResult(current, scopeLabel);
41152
+ if (!nextGuard.ok) {
41153
+ return nextGuard;
41154
+ }
41155
+ const previousGuardStillValid = await assertGuardResult(currentGuard, scopeLabel);
41156
+ if (!previousGuardStillValid.ok) {
41157
+ return previousGuardStillValid;
41158
+ }
41159
+ currentGuard = nextGuard.guard;
41160
+ }
41161
+ const finalGuardResult = await assertGuardResult(currentGuard, scopeLabel);
41162
+ if (!finalGuardResult.ok) {
41163
+ return finalGuardResult;
41164
+ }
41165
+ return { ok: true, path: targetPath };
41166
+ }
41167
+ async function canonicalPathFromExistingAncestor(filePath) {
41168
+ const ancestor = await findExistingAncestor(filePath);
41169
+ if (!ancestor) {
41170
+ return external_node_path_.resolve(filePath);
41171
+ }
41172
+ let canonicalAncestor = ancestor;
41173
+ try {
41174
+ canonicalAncestor = external_node_fs_.realpathSync.native(ancestor);
41175
+ }
41176
+ catch {
41177
+ // Keep lexical path when the existing ancestor cannot be canonicalized.
41178
+ }
41179
+ const relative = external_node_path_.relative(ancestor, filePath);
41180
+ return relative ? external_node_path_.join(canonicalAncestor, relative) : canonicalAncestor;
41181
+ }
41182
+ async function resolveAbsolutePathForRead(filePath, options = {}) {
41183
+ const symlinks = resolveSymlinkPolicy(options.symlinks);
41184
+ const normalized = assertAbsolutePathInput(filePath);
41185
+ let canonicalPath;
41186
+ try {
41187
+ canonicalPath = fsSync.realpathSync.native(normalized);
41188
+ }
41189
+ catch (err) {
41190
+ if (err.code === "ENOENT") {
41191
+ throw new FsSafeError("not-found", "path not found", { cause: err });
41192
+ }
41193
+ throw err;
41194
+ }
41195
+ if (symlinks === "reject" && canonicalPath !== normalized) {
41196
+ throw new FsSafeError("symlink", "path traverses a symlink", { cause: { canonicalPath } });
41197
+ }
41198
+ return { path: normalized, canonicalPath };
41199
+ }
41200
+ async function resolveAbsolutePathForWrite(filePath, options = {}) {
41201
+ const symlinks = resolveSymlinkPolicy(options.symlinks);
41202
+ const normalized = assertAbsolutePathInput(filePath);
41203
+ const parentDir = path.dirname(normalized);
41204
+ const parentExists = await pathExists(parentDir);
41205
+ if (symlinks === "reject") {
41206
+ const filesystemRoot = path.parse(normalized).root;
41207
+ await resolveRootPath({
41208
+ absolutePath: normalized,
41209
+ rootPath: filesystemRoot,
41210
+ rootCanonicalPath: filesystemRoot,
41211
+ boundaryLabel: "absolute path",
41212
+ rejectSymlinks: true,
41213
+ });
41214
+ }
41215
+ const canonicalPath = await canonicalPathFromExistingAncestor(normalized);
41216
+ if (symlinks === "reject" && canonicalPath !== normalized) {
41217
+ throw new FsSafeError("symlink", "path traverses a symlink", {
41218
+ cause: { canonicalPath },
41219
+ });
41220
+ }
41221
+ return {
41222
+ path: normalized,
41223
+ canonicalPath,
41224
+ parentDir,
41225
+ parentExists,
41226
+ };
41227
+ }
41228
+
40477
41229
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/sidecar-lock-policy.js
40478
41230
 
40479
41231
  function assertFiniteNonNegative(value, label) {
@@ -40525,10 +41277,6 @@ function isTransientLockFileDenial(error, lockPath) {
40525
41277
  const denial = error;
40526
41278
  return process.platform === "win32" && denial?.code === "EPERM" && denial.path === lockPath;
40527
41279
  }
40528
- function sidecarLockPayloadIsStale(payload, staleMs, nowMs) {
40529
- const createdAtMs = sidecarLockPayloadCreatedAtMs(payload);
40530
- return createdAtMs !== null && nowMs - createdAtMs > staleMs;
40531
- }
40532
41280
  function sidecarLockPayloadCreatedAtMs(payload) {
40533
41281
  const createdAt = payload &&
40534
41282
  typeof payload === "object" &&
@@ -40544,7 +41292,7 @@ async function defaultSidecarLockShouldReclaim(params) {
40544
41292
  if (createdAtMs !== null)
40545
41293
  return params.nowMs - createdAtMs > params.staleMs;
40546
41294
  try {
40547
- return params.nowMs - (await promises_.stat(params.lockPath)).mtimeMs > params.staleMs;
41295
+ return params.nowMs - external_node_fs_.statSync(params.lockPath).mtimeMs > params.staleMs;
40548
41296
  }
40549
41297
  catch {
40550
41298
  return true;
@@ -40578,12 +41326,23 @@ function createSuppressedError(error, suppressed, message) {
40578
41326
 
40579
41327
 
40580
41328
 
40581
- async function resolveNormalizedTargetPath(targetPath) {
41329
+
41330
+
41331
+
41332
+ async function resolveNormalizedTargetPath(targetPath, lockRoot) {
40582
41333
  const resolved = external_node_path_.resolve(targetPath);
40583
41334
  const dir = external_node_path_.dirname(resolved);
41335
+ if (lockRoot) {
41336
+ // The target is an arbitration key, not necessarily inside the lock Root.
41337
+ // Leave parent creation to the Root-backed sidecar write.
41338
+ await lockRoot.resolve(".");
41339
+ const parent = await canonicalPathFromExistingAncestor(dir);
41340
+ await lockRoot.resolve(".");
41341
+ return external_node_path_.join(parent, external_node_path_.basename(resolved));
41342
+ }
40584
41343
  await promises_.mkdir(dir, { recursive: true });
40585
41344
  try {
40586
- return external_node_path_.join(await promises_.realpath(dir), external_node_path_.basename(resolved));
41345
+ return external_node_path_.join(external_node_fs_.realpathSync.native(dir), external_node_path_.basename(resolved));
40587
41346
  }
40588
41347
  catch {
40589
41348
  return resolved;
@@ -40594,7 +41353,7 @@ async function acquireSidecarLock(options, context) {
40594
41353
  validateSidecarLockRetryOptions(retry);
40595
41354
  validateSidecarLockTimeoutMs(options.timeoutMs);
40596
41355
  context.ensureExitCleanupRegistered();
40597
- const normalizedTargetPath = await resolveNormalizedTargetPath(options.targetPath);
41356
+ const normalizedTargetPath = await resolveNormalizedTargetPath(options.targetPath, options.lockRoot);
40598
41357
  const lockPath = options.lockPath ?? `${normalizedTargetPath}.lock`;
40599
41358
  let held = context.held.get(normalizedTargetPath);
40600
41359
  if (held &&
@@ -40614,11 +41373,15 @@ async function acquireSidecarLock(options, context) {
40614
41373
  held.reentrantOwner !== undefined &&
40615
41374
  options.reentrantOwner === held.reentrantOwner) {
40616
41375
  held.refCount += 1;
41376
+ // Retention is monotonic: any same-owner request to keep the sidecar on
41377
+ // exit upgrades the held lock; a later default acquisition never revokes it.
41378
+ if (options.retainOnExit === true) {
41379
+ held.retainOnExit = true;
41380
+ }
40617
41381
  return context.handleForHeldLock(normalizedTargetPath, held);
40618
41382
  }
40619
41383
  }
40620
41384
  const startedAt = Date.now();
40621
- const maxRetries = options.timeoutMs === Number.POSITIVE_INFINITY ? undefined : retry.retries;
40622
41385
  const reclaimGuardPath = `${lockPath}.reclaim`;
40623
41386
  let ownsReclaimGuard = false;
40624
41387
  let attempt = 0;
@@ -40630,7 +41393,7 @@ async function acquireSidecarLock(options, context) {
40630
41393
  if ((options.timeoutMs !== undefined &&
40631
41394
  options.timeoutMs !== Number.POSITIVE_INFINITY &&
40632
41395
  elapsed >= options.timeoutMs) ||
40633
- (maxRetries !== undefined && attempt >= maxRetries)) {
41396
+ (retry.retries !== undefined && attempt >= retry.retries)) {
40634
41397
  throw Object.assign(new Error(`file lock timeout for ${normalizedTargetPath}`), {
40635
41398
  code: "file_lock_timeout",
40636
41399
  lockPath,
@@ -40672,10 +41435,14 @@ async function acquireSidecarLock(options, context) {
40672
41435
  if (options.lockRoot) {
40673
41436
  const lockRoot = options.lockRoot;
40674
41437
  const relativeLockPath = relativeSidecarLockPath(lockRoot, lockPath);
41438
+ const observation = fileObservation();
40675
41439
  try {
40676
- await lockRoot.create(relativeLockPath, raw, { mkdir: true, mode: 0o600 });
41440
+ await observation.run(() => lockRoot.create(relativeLockPath, raw, { mkdir: true, mode: 0o600 }));
40677
41441
  }
40678
41442
  catch (error) {
41443
+ // Only this invocation's failed exclusive open grants denial retry authority.
41444
+ lockFileCreateDenied = observation.has(error, `exclusive-create:${lockPath}`) &&
41445
+ isTransientLockFileDenial(error, lockPath);
40679
41446
  if (error instanceof errors_FsSafeError && error.code === "already-exists") {
40680
41447
  throw Object.assign(new Error("sidecar lock exists"), { code: "EEXIST" });
40681
41448
  }
@@ -40712,7 +41479,7 @@ async function acquireSidecarLock(options, context) {
40712
41479
  }
40713
41480
  await handle.writeFile(raw, "utf8");
40714
41481
  }
40715
- const snapshot = { raw, payload, stat: await handle.stat(), ownershipToken };
41482
+ const snapshot = { raw, payload, stat: external_node_fs_.fstatSync(handle.fd), ownershipToken };
40716
41483
  if (snapshot.stat.nlink === 0) {
40717
41484
  await handle.close();
40718
41485
  handle = null;
@@ -40728,6 +41495,7 @@ async function acquireSidecarLock(options, context) {
40728
41495
  acquiredAt: Date.now(),
40729
41496
  metadata: options.metadata ?? {},
40730
41497
  lockRoot: options.lockRoot,
41498
+ retainOnExit: options.retainOnExit,
40731
41499
  parsePayload: options.parsePayload,
40732
41500
  };
40733
41501
  context.held.set(normalizedTargetPath, createdHeld);
@@ -40765,7 +41533,7 @@ async function acquireSidecarLock(options, context) {
40765
41533
  if (handle) {
40766
41534
  const failedSnapshot = createdSnapshot ?? { payload: null };
40767
41535
  try {
40768
- failedSnapshot.stat = await handle.stat();
41536
+ failedSnapshot.stat = external_node_fs_.fstatSync(handle.fd);
40769
41537
  }
40770
41538
  catch {
40771
41539
  // Best-effort cleanup of a failed exclusive create.
@@ -40938,9 +41706,15 @@ function createHeldSidecarLockHandle(params) {
40938
41706
 
40939
41707
 
40940
41708
 
41709
+
40941
41710
  const GLOBAL_STATE_KEY = Symbol.for("fsSafe.sidecarLockManagers");
40942
41711
  const GLOBAL_CLEANUP_KEY = Symbol.for("fsSafe.sidecarLockCleanupRegistered");
40943
41712
  const GLOBAL_CLEANUP_HANDLER_KEY = Symbol.for("fsSafe.sidecarLockCleanupHandler");
41713
+ const GLOBAL_BEFORE_EXIT_KEY = Symbol.for("fsSafe.sidecarLockBeforeExitCleanup");
41714
+ // Set by copies whose exit handlers honor retainOnExit. When an older package
41715
+ // copy registered the handlers first, this marker stays absent and retained
41716
+ // acquisitions must fail closed rather than silently lose the guarantee.
41717
+ const GLOBAL_RETAIN_AWARE_KEY = Symbol.for("fsSafe.sidecarLockRetainAwareCleanup");
40944
41718
  function getGlobalManagers() {
40945
41719
  const globalWithState = globalThis;
40946
41720
  if (!globalWithState[GLOBAL_STATE_KEY]) {
@@ -41013,7 +41787,8 @@ function snapshotMatchesSync(lockPath, observed) {
41013
41787
  }
41014
41788
  }
41015
41789
  function releaseAllReclaimGuardsSync(state) {
41016
- for (const reclaimGuardPath of state.reclaimGuards) {
41790
+ // Exit cleanup also visits managers created by older copies and never reopened here.
41791
+ for (const reclaimGuardPath of state.reclaimGuards ?? []) {
41017
41792
  try {
41018
41793
  external_node_fs_.rmdirSync(reclaimGuardPath);
41019
41794
  state.reclaimGuards.delete(reclaimGuardPath);
@@ -41023,11 +41798,12 @@ function releaseAllReclaimGuardsSync(state) {
41023
41798
  }
41024
41799
  }
41025
41800
  }
41026
- function releaseAllLocksSync(state) {
41801
+ function releaseAllLocksSync(state, options) {
41027
41802
  for (const [normalizedTargetPath, held] of state.held) {
41028
41803
  void held.handle.close().catch(() => undefined);
41029
41804
  try {
41030
- if (!held.lockRoot && snapshotMatchesSync(held.lockPath, held.snapshot)) {
41805
+ const retained = options?.preserveRetained === true && held.retainOnExit;
41806
+ if (!retained && !held.lockRoot && snapshotMatchesSync(held.lockPath, held.snapshot)) {
41031
41807
  external_node_fs_.rmSync(held.lockPath, { force: true });
41032
41808
  }
41033
41809
  }
@@ -41043,14 +41819,43 @@ function ensureGlobalExitCleanupRegistered() {
41043
41819
  if (globalWithCleanup[GLOBAL_CLEANUP_KEY])
41044
41820
  return;
41045
41821
  globalWithCleanup[GLOBAL_CLEANUP_KEY] = true;
41822
+ globalWithCleanup[GLOBAL_RETAIN_AWARE_KEY] = true;
41046
41823
  const cleanup = () => {
41047
41824
  for (const state of getGlobalManagers().values()) {
41048
- releaseAllLocksSync(state);
41825
+ releaseAllLocksSync(state, { preserveRetained: true });
41049
41826
  }
41050
41827
  };
41051
41828
  globalWithCleanup[GLOBAL_CLEANUP_HANDLER_KEY] = cleanup;
41052
41829
  process.on("exit", cleanup);
41053
41830
  }
41831
+ /** True when a retain-unaware package copy registered the process-exit handlers first. */
41832
+ function exitCleanupCannotRetain() {
41833
+ const globalWithCleanup = globalThis;
41834
+ return globalWithCleanup[GLOBAL_CLEANUP_KEY] === true && globalWithCleanup[GLOBAL_RETAIN_AWARE_KEY] !== true;
41835
+ }
41836
+ function ensureGlobalBeforeExitCleanupRegistered() {
41837
+ const globalWithCleanup = globalThis;
41838
+ if (globalWithCleanup[GLOBAL_BEFORE_EXIT_KEY]) {
41839
+ return globalWithCleanup[GLOBAL_BEFORE_EXIT_KEY];
41840
+ }
41841
+ // Independent of the exit registration, which an older package copy may own.
41842
+ const lifecycle = { armed: false };
41843
+ globalWithCleanup[GLOBAL_BEFORE_EXIT_KEY] = lifecycle;
41844
+ process.on("beforeExit", () => {
41845
+ if (!lifecycle.armed)
41846
+ return;
41847
+ // Cleanup itself schedules I/O; retry only after another acquisition.
41848
+ lifecycle.armed = false;
41849
+ for (const state of getGlobalManagers().values()) {
41850
+ for (const [normalizedTargetPath, held] of Array.from(state.held.entries())) {
41851
+ if (held.lockRoot && !held.retainOnExit) {
41852
+ void releaseHeldLock(state, normalizedTargetPath, held, { force: true }).catch(() => undefined);
41853
+ }
41854
+ }
41855
+ }
41856
+ });
41857
+ return lifecycle;
41858
+ }
41054
41859
  async function releaseHeldLock(state, normalizedTargetPath, held, options = {}) {
41055
41860
  const current = state.held.get(normalizedTargetPath);
41056
41861
  if (current !== held) {
@@ -41092,6 +41897,7 @@ async function releaseHeldLock(state, normalizedTargetPath, held, options = {})
41092
41897
  }
41093
41898
  }
41094
41899
  function handleForHeldLock(state, normalizedTargetPath, held) {
41900
+ ensureGlobalBeforeExitCleanupRegistered().armed = true;
41095
41901
  return createHeldSidecarLockHandle({
41096
41902
  normalizedTargetPath,
41097
41903
  held,
@@ -41104,8 +41910,12 @@ function createSidecarLockManager(key) {
41104
41910
  state.cleanupRegistered = true;
41105
41911
  state.reclaimCleanupRegistered = true;
41106
41912
  ensureGlobalExitCleanupRegistered();
41913
+ ensureGlobalBeforeExitCleanupRegistered().armed = true;
41107
41914
  }
41108
41915
  async function acquire(options) {
41916
+ if (options.retainOnExit === true && exitCleanupCannotRetain()) {
41917
+ throw new errors_FsSafeError("helper-unavailable", "retainOnExit requires this process's exit handlers to be retain-aware; an older package copy registered them first");
41918
+ }
41109
41919
  return await acquireSidecarLock(options, {
41110
41920
  held: state.held,
41111
41921
  reclaimGuards: state.reclaimGuards,
@@ -41175,6 +41985,8 @@ async function withSidecarLock(targetPath, options, fn) {
41175
41985
 
41176
41986
 
41177
41987
 
41988
+
41989
+
41178
41990
  function pinned_write_byteLength(input, encoding) {
41179
41991
  return typeof input === "string"
41180
41992
  ? Buffer.byteLength(input, encoding ?? "utf8")
@@ -41194,16 +42006,6 @@ function assertWithinMaxBytes(bytes, maxBytes) {
41194
42006
  throw new errors_FsSafeError("too-large", `file exceeds limit of ${maxBytes} bytes (got at least ${bytes})`);
41195
42007
  }
41196
42008
  }
41197
- async function syncFileBestEffort(handle) {
41198
- try {
41199
- await handle.sync();
41200
- }
41201
- catch (error) {
41202
- if (error?.code !== "EPERM") {
41203
- throw error;
41204
- }
41205
- }
41206
- }
41207
42009
  async function writeStreamToHandle(stream, handle, maxBytes) {
41208
42010
  let bytes = 0;
41209
42011
  for await (const chunk of stream) {
@@ -41245,7 +42047,7 @@ async function runPinnedWriteWithRenamePolicy(params) {
41245
42047
  const relativeTargetPath = writeParams.relativeParentPath
41246
42048
  ? `${writeParams.relativeParentPath}/${writeParams.basename}`
41247
42049
  : writeParams.basename;
41248
- const lockPath = external_node_path_.join(writeParams.rootPath, `.fs-safe-write-${sha256Hex(relativeTargetPath)}.lock`);
42050
+ const lockPath = external_node_path_.join(writeParams.rootPath, `.fs-safe-write-${file_identity_sha256Hex(relativeTargetPath)}.lock`);
41249
42051
  return await withSidecarLock(writeParams.rootPath, {
41250
42052
  managerKey: `fs-safe.write:${targetPath}`,
41251
42053
  lockPath,
@@ -41259,6 +42061,11 @@ async function runPinnedWriteWithRenamePolicy(params) {
41259
42061
  }));
41260
42062
  }
41261
42063
  async function runPinnedWriteFallback(params) {
42064
+ const exactRoot = typeof params.rootIdentity?.dev === "bigint" && typeof params.rootIdentity.ino === "bigint"
42065
+ ? { dev: params.rootIdentity.dev, ino: params.rootIdentity.ino } : undefined;
42066
+ if (exactRoot)
42067
+ await inspectDirectoryIdentity(params.rootPath, exactRoot);
42068
+ const guardOptions = { bigint: exactRoot !== undefined };
41262
42069
  let parentPath = params.relativeParentPath
41263
42070
  ? external_node_path_.join(params.rootPath, ...params.relativeParentPath.split("/"))
41264
42071
  : params.rootPath;
@@ -41274,8 +42081,8 @@ async function runPinnedWriteFallback(params) {
41274
42081
  });
41275
42082
  }
41276
42083
  const parentGuard = params.mkdir
41277
- ? await directory_guard_createAsyncDirectoryGuard(parentPath)
41278
- : await directory_guard_createNearestExistingDirectoryGuard(params.rootPath, parentPath);
42084
+ ? await directory_guard_createAsyncDirectoryGuard(parentPath, guardOptions)
42085
+ : await directory_guard_createNearestExistingDirectoryGuard(params.rootPath, parentPath, guardOptions);
41279
42086
  const targetPath = external_node_path_.join(parentPath, params.basename);
41280
42087
  if (params.overwrite === false) {
41281
42088
  const handle = await withAsyncDirectoryGuards([parentGuard], async () => await promises_.open(targetPath, external_node_fs_.constants.O_WRONLY | external_node_fs_.constants.O_CREAT | external_node_fs_.constants.O_EXCL, params.mode), {
@@ -41286,9 +42093,10 @@ async function runPinnedWriteFallback(params) {
41286
42093
  },
41287
42094
  });
41288
42095
  let created = true;
42096
+ let createdIdentity;
41289
42097
  try {
41290
- const verificationIdentity = await handle.stat({ bigint: true });
41291
- await handle.chmod(params.mode);
42098
+ const verificationIdentity = external_node_fs_.fstatSync(handle.fd, { bigint: true });
42099
+ createdIdentity = verificationIdentity;
41292
42100
  if (params.input.kind === "buffer") {
41293
42101
  assertWithinMaxBytes(pinned_write_byteLength(params.input.data, params.input.encoding), params.maxBytes);
41294
42102
  if (typeof params.input.data === "string") {
@@ -41301,18 +42109,26 @@ async function runPinnedWriteFallback(params) {
41301
42109
  else {
41302
42110
  await writeStreamToHandle(params.input.stream, handle, params.maxBytes);
41303
42111
  }
41304
- await syncFileBestEffort(handle);
41305
- const stat = await handle.stat();
41306
- await syncDirectoryBestEffort(parentPath);
42112
+ // Content writes may clear set-ID bits; finalize them through the owned fd.
42113
+ await handle.chmod(params.mode);
42114
+ if (params.sync !== false)
42115
+ await syncFileBestEffort(handle);
42116
+ const stat = external_node_fs_.fstatSync(handle.fd);
42117
+ if (params.sync !== false)
42118
+ await syncDirectoryBestEffort(parentPath);
41307
42119
  // Publication is complete. A failed outer check must not remove its target.
41308
42120
  created = false;
41309
42121
  await params.verifyPublished?.(handle.fd, verificationIdentity, parentGuard);
41310
42122
  return { dev: stat.dev, ino: stat.ino };
41311
42123
  }
41312
42124
  finally {
41313
- await handle.close().catch(() => undefined);
41314
- if (created) {
41315
- await promises_.rm(targetPath, { force: true }).catch(() => undefined);
42125
+ try {
42126
+ if (created) {
42127
+ await cleanupPinnedFilePath({ pathname: targetPath, handle, identity: createdIdentity, parentGuard });
42128
+ }
42129
+ }
42130
+ finally {
42131
+ await handle.close().catch(() => undefined);
41316
42132
  }
41317
42133
  }
41318
42134
  }
@@ -41326,12 +42142,13 @@ async function runPinnedWriteFallback(params) {
41326
42142
  : 0);
41327
42143
  let handle;
41328
42144
  let tempStat;
42145
+ let tempIdentity;
41329
42146
  let readHandle;
41330
42147
  let renamed = false;
41331
42148
  try {
41332
42149
  handle = await promises_.open(tempPath, tempFlags, params.mode);
41333
- let verificationIdentity = await handle.stat({ bigint: true });
41334
- await handle.chmod(params.mode);
42150
+ let verificationIdentity = external_node_fs_.fstatSync(handle.fd, { bigint: true });
42151
+ tempIdentity = verificationIdentity;
41335
42152
  if (params.input.kind === "buffer") {
41336
42153
  assertWithinMaxBytes(pinned_write_byteLength(params.input.data, params.input.encoding), params.maxBytes);
41337
42154
  if (typeof params.input.data === "string") {
@@ -41344,20 +42161,23 @@ async function runPinnedWriteFallback(params) {
41344
42161
  else {
41345
42162
  await writeStreamToHandle(params.input.stream, handle, params.maxBytes);
41346
42163
  }
41347
- tempStat = await handle.stat();
41348
- const tempPathStat = await promises_.lstat(tempPath);
42164
+ tempStat = external_node_fs_.fstatSync(handle.fd);
42165
+ const tempPathStat = external_node_fs_.lstatSync(tempPath);
41349
42166
  if (tempPathStat.isSymbolicLink() || !file_identity_sameFileIdentity(tempPathStat, tempStat)) {
41350
42167
  throw new errors_FsSafeError("path-mismatch", "fallback temp path changed during write");
41351
42168
  }
41352
42169
  const expectedTempStat = tempStat;
41353
- await syncFileBestEffort(handle);
42170
+ await handle.chmod(params.mode);
42171
+ if (params.sync !== false)
42172
+ await syncFileBestEffort(handle);
41354
42173
  let verifiedIdentity = expectedTempStat;
41355
42174
  await withAsyncDirectoryGuards([parentGuard], async () => {
41356
42175
  await promises_.rename(tempPath, targetPath);
41357
42176
  renamed = true;
41358
42177
  await getFsSafeTestHooks()?.afterPinnedWriteFallbackRename?.(targetPath);
41359
- await syncDirectoryBestEffort(parentPath);
41360
- const targetStat = await promises_.lstat(targetPath);
42178
+ if (params.sync !== false)
42179
+ await syncDirectoryBestEffort(parentPath);
42180
+ const targetStat = external_node_fs_.lstatSync(targetPath);
41361
42181
  if (targetStat.isSymbolicLink()) {
41362
42182
  throw new errors_FsSafeError("path-mismatch", "fallback target changed during write");
41363
42183
  }
@@ -41372,10 +42192,10 @@ async function runPinnedWriteFallback(params) {
41372
42192
  if (params.input.kind !== "buffer") {
41373
42193
  throw new errors_FsSafeError("path-mismatch", "fallback target changed during write");
41374
42194
  }
41375
- const expectedHash = sha256Hex(params.input.data, params.input.encoding);
42195
+ const expectedHash = file_identity_sha256Hex(params.input.data, params.input.encoding);
41376
42196
  readHandle = await promises_.open(targetPath, read_open_flags_resolveReadOpenFlags());
41377
- const readHandleStat = await readHandle.stat({ bigint: true });
41378
- const actualHash = sha256Hex(await readHandle.readFile());
42197
+ const readHandleStat = external_node_fs_.fstatSync(readHandle.fd, { bigint: true });
42198
+ const actualHash = file_identity_sha256Hex(await readHandle.readFile());
41379
42199
  if (actualHash !== expectedHash) {
41380
42200
  throw new errors_FsSafeError("path-mismatch", "fallback target changed during write");
41381
42201
  }
@@ -41389,10 +42209,14 @@ async function runPinnedWriteFallback(params) {
41389
42209
  return { dev: verifiedIdentity.dev, ino: verifiedIdentity.ino };
41390
42210
  }
41391
42211
  finally {
41392
- await readHandle?.close().catch(() => undefined);
41393
- await handle?.close().catch(() => undefined);
41394
- if (!renamed) {
41395
- await promises_.rm(tempPath, { force: true }).catch(() => undefined);
42212
+ try {
42213
+ if (!renamed && handle) {
42214
+ await cleanupPinnedFilePath({ pathname: tempPath, handle, identity: tempIdentity, parentGuard });
42215
+ }
42216
+ }
42217
+ finally {
42218
+ await readHandle?.close().catch(() => undefined);
42219
+ await handle?.close().catch(() => undefined);
41396
42220
  }
41397
42221
  }
41398
42222
  }
@@ -41404,7 +42228,7 @@ async function runPinnedWriteFallback(params) {
41404
42228
 
41405
42229
  const PATH_ALIAS_POLICIES = ROOT_PATH_ALIAS_POLICIES;
41406
42230
  async function assertNoPathAliasEscape(params) {
41407
- const resolved = await resolveRootPath({
42231
+ const resolved = await root_path_resolveRootPath({
41408
42232
  absolutePath: params.absolutePath,
41409
42233
  rootPath: params.rootPath,
41410
42234
  boundaryLabel: params.boundaryLabel,
@@ -41427,7 +42251,7 @@ async function assertNoHardlinkedFinalPath(params) {
41427
42251
  }
41428
42252
  let stat;
41429
42253
  try {
41430
- stat = await promises_.stat(params.filePath);
42254
+ stat = external_node_fs_.statSync(params.filePath);
41431
42255
  }
41432
42256
  catch (err) {
41433
42257
  if (path_isNotFoundPathError(err)) {
@@ -41446,9 +42270,6 @@ async function assertNoHardlinkedFinalPath(params) {
41446
42270
  // EXTERNAL MODULE: external "node:url"
41447
42271
  var external_node_url_ = __webpack_require__(3136);
41448
42272
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/string-coerce.js
41449
- function readStringValue(value) {
41450
- return typeof value === "string" ? value : undefined;
41451
- }
41452
42273
  function normalizeNullableString(value) {
41453
42274
  if (typeof value !== "string") {
41454
42275
  return null;
@@ -41459,65 +42280,12 @@ function normalizeNullableString(value) {
41459
42280
  function normalizeOptionalString(value) {
41460
42281
  return normalizeNullableString(value) ?? undefined;
41461
42282
  }
41462
- function normalizeStringifiedOptionalString(value) {
41463
- if (typeof value === "string") {
41464
- return normalizeOptionalString(value);
41465
- }
41466
- if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
41467
- return normalizeOptionalString(String(value));
41468
- }
41469
- return undefined;
41470
- }
41471
42283
  function normalizeOptionalLowercaseString(value) {
41472
42284
  return normalizeOptionalString(value)?.toLowerCase();
41473
42285
  }
41474
42286
  function normalizeLowercaseStringOrEmpty(value) {
41475
42287
  return normalizeOptionalLowercaseString(value) ?? "";
41476
42288
  }
41477
- function normalizeFastMode(raw) {
41478
- if (typeof raw === "boolean") {
41479
- return raw;
41480
- }
41481
- if (!raw) {
41482
- return undefined;
41483
- }
41484
- const key = normalizeLowercaseStringOrEmpty(raw);
41485
- if (["off", "false", "no", "0", "disable", "disabled", "normal"].includes(key)) {
41486
- return false;
41487
- }
41488
- if (["on", "true", "yes", "1", "enable", "enabled", "fast"].includes(key)) {
41489
- return true;
41490
- }
41491
- return undefined;
41492
- }
41493
- function lowercasePreservingWhitespace(value) {
41494
- return value.toLowerCase();
41495
- }
41496
- function localeLowercasePreservingWhitespace(value) {
41497
- return value.toLocaleLowerCase();
41498
- }
41499
- function resolvePrimaryStringValue(value) {
41500
- if (typeof value === "string") {
41501
- return normalizeOptionalString(value);
41502
- }
41503
- if (!value || typeof value !== "object") {
41504
- return undefined;
41505
- }
41506
- return normalizeOptionalString(value.primary);
41507
- }
41508
- function normalizeOptionalThreadValue(value) {
41509
- if (typeof value === "number") {
41510
- return Number.isFinite(value) ? Math.trunc(value) : undefined;
41511
- }
41512
- return normalizeOptionalString(value);
41513
- }
41514
- function normalizeOptionalStringifiedId(value) {
41515
- const normalized = normalizeOptionalThreadValue(value);
41516
- return normalized == null ? undefined : String(normalized);
41517
- }
41518
- function hasNonEmptyString(value) {
41519
- return normalizeOptionalString(value) !== undefined;
41520
- }
41521
42289
 
41522
42290
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/local-file-access.js
41523
42291
 
@@ -41709,8 +42477,11 @@ function normalizeWindowsDeviceBaseName(filePath) {
41709
42477
  const normalized = trimTrailingWindowsSeparators(filePath.replace(/\//g, "\\"));
41710
42478
  const lastSegment = normalized.split("\\").filter(Boolean).at(-1) ?? normalized;
41711
42479
  const withoutStream = lastSegment.split(":")[0] ?? lastSegment;
41712
- const withoutTrailingIgnoredChars = trimTrailingWindowsIgnoredChars(withoutStream);
41713
- return (withoutTrailingIgnoredChars.split(".")[0] ?? withoutTrailingIgnoredChars).toUpperCase();
42480
+ const stem = withoutStream.split(".")[0] ?? withoutStream;
42481
+ return trimTrailingWindowsIgnoredChars(stem).toUpperCase();
42482
+ }
42483
+ function isWindowsReservedDeviceName(name) {
42484
+ return name.length > 0 && WINDOWS_RESERVED_DEVICE_NAMES.has(normalizeWindowsDeviceBaseName(name));
41714
42485
  }
41715
42486
  function matchWindowsDeviceReadPath(filePath) {
41716
42487
  const normalized = filePath.replace(/\//g, "\\");
@@ -41764,6 +42535,42 @@ async function read_opened_file_readOpenedFileSafely(params) {
41764
42535
  };
41765
42536
  }
41766
42537
 
42538
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/write-open-flags.js
42539
+
42540
+
42541
+ function resolveNonblockingWriteFlag(constants = external_node_fs_.constants) {
42542
+ return process.platform !== "win32" && typeof constants.O_NONBLOCK === "number"
42543
+ ? constants.O_NONBLOCK
42544
+ : 0;
42545
+ }
42546
+ function isNonblockingWriteEnxio(error, flags) {
42547
+ return hasNodeErrorCode(error, "ENXIO") &&
42548
+ (flags & (external_node_fs_.constants.O_WRONLY | external_node_fs_.constants.O_RDWR)) === external_node_fs_.constants.O_WRONLY &&
42549
+ (flags & resolveNonblockingWriteFlag()) !== 0;
42550
+ }
42551
+ // A no-reader FIFO rejects a nonblocking write-only open before fstat is possible.
42552
+ // Reclassify only a confirmed non-regular path; inconclusive races keep the errno.
42553
+ async function isNonRegularWriteOpenError(error, filePath, flags) {
42554
+ if (!isNonblockingWriteEnxio(error, flags))
42555
+ return false;
42556
+ try {
42557
+ return !external_node_fs_.lstatSync(filePath).isFile();
42558
+ }
42559
+ catch {
42560
+ return false;
42561
+ }
42562
+ }
42563
+ function isNonRegularWriteOpenErrorSync(error, filePath, flags) {
42564
+ if (!isNonblockingWriteEnxio(error, flags))
42565
+ return false;
42566
+ try {
42567
+ return !fsSync.lstatSync(filePath).isFile();
42568
+ }
42569
+ catch {
42570
+ return false;
42571
+ }
42572
+ }
42573
+
41767
42574
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/home-dir.js
41768
42575
 
41769
42576
 
@@ -41782,10 +42589,6 @@ function resolveEffectiveHomeDir(env = process.env, homedir = external_node_os_.
41782
42589
  const raw = resolveRawHomeDir(env, homedir);
41783
42590
  return raw ? external_node_path_.resolve(raw) : undefined;
41784
42591
  }
41785
- function resolveOsHomeDir(env = process.env, homedir = os.homedir) {
41786
- const raw = resolveRawOsHomeDir(env, homedir);
41787
- return raw ? path.resolve(raw) : undefined;
41788
- }
41789
42592
  function resolveRawHomeDir(env, homedir) {
41790
42593
  const explicitHome = normalize(env.OPENCLAW_HOME);
41791
42594
  if (!explicitHome) {
@@ -41826,9 +42629,6 @@ function normalizeSafe(homedir) {
41826
42629
  function resolveRequiredHomeDir(env = process.env, homedir = os.homedir) {
41827
42630
  return resolveEffectiveHomeDir(env, homedir) ?? path.resolve(process.cwd());
41828
42631
  }
41829
- function resolveRequiredOsHomeDir(env = process.env, homedir = os.homedir) {
41830
- return resolveOsHomeDir(env, homedir) ?? path.resolve(process.cwd());
41831
- }
41832
42632
  function expandHomePrefix(input, opts) {
41833
42633
  const segments = external_node_path_.normalize(input).split(external_node_path_.sep);
41834
42634
  if (segments[0] !== "~") {
@@ -41856,27 +42656,6 @@ function resolveHomeRelativePath(input, opts) {
41856
42656
  });
41857
42657
  return path.resolve(expanded);
41858
42658
  }
41859
- function resolveUserPath(input, optsOrEnv, homedir) {
41860
- const opts = optsOrEnv && ("env" in optsOrEnv || "homedir" in optsOrEnv)
41861
- ? optsOrEnv
41862
- : { env: optsOrEnv, homedir };
41863
- return resolveHomeRelativePath(input, opts);
41864
- }
41865
- function resolveOsHomeRelativePath(input, opts) {
41866
- if (!input) {
41867
- return input;
41868
- }
41869
- const segments = path.normalize(input).split(path.sep);
41870
- if (segments[0] !== "~") {
41871
- return path.resolve(input);
41872
- }
41873
- const expanded = expandHomePrefix(input, {
41874
- home: resolveRequiredOsHomeDir(opts?.env ?? process.env, opts?.homedir ?? os.homedir),
41875
- env: opts?.env,
41876
- homedir: opts?.homedir,
41877
- });
41878
- return path.resolve(expanded);
41879
- }
41880
42659
 
41881
42660
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/root-context.js
41882
42661
 
@@ -41889,6 +42668,7 @@ function resolveOsHomeRelativePath(input, opts) {
41889
42668
 
41890
42669
 
41891
42670
 
42671
+
41892
42672
  const ensureTrailingSep = (value) => value.endsWith(external_node_path_.sep) ? value : value + external_node_path_.sep;
41893
42673
  function assertValidRootRelativePath(relativePath) {
41894
42674
  path_assertNoNulPathInput(relativePath, "relative path contains a NUL byte");
@@ -41905,7 +42685,7 @@ async function expandRelativePathWithHome(relativePath) {
41905
42685
  if (cachedHomePath?.raw !== rawHome) {
41906
42686
  let realHome = rawHome;
41907
42687
  try {
41908
- realHome = await promises_.realpath(rawHome);
42688
+ realHome = external_node_fs_.realpathSync.native(rawHome);
41909
42689
  }
41910
42690
  catch {
41911
42691
  // If the home dir cannot be canonicalized, keep lexical expansion behavior.
@@ -41919,8 +42699,8 @@ async function resolveRootContext(rootDir) {
41919
42699
  let rootReal;
41920
42700
  let rootIdentity;
41921
42701
  try {
41922
- rootReal = await promises_.realpath(rootDir);
41923
- const rootStat = await promises_.stat(rootReal);
42702
+ rootReal = external_node_fs_.realpathSync.native(rootDir);
42703
+ const rootStat = external_node_fs_.statSync(rootReal);
41924
42704
  if (!rootStat.isDirectory()) {
41925
42705
  throw new errors_FsSafeError("invalid-path", "root dir is not a directory");
41926
42706
  }
@@ -41942,10 +42722,28 @@ async function resolveRootContext(rootDir) {
41942
42722
  rootWithSep: ensureTrailingSep(rootReal),
41943
42723
  };
41944
42724
  }
42725
+ function rootRelativeReadPath(root, filePath) {
42726
+ const absoluteInput = external_node_path_.isAbsolute(filePath);
42727
+ const candidatePath = absoluteInput
42728
+ ? external_node_path_.resolve(filePath)
42729
+ : external_node_path_.resolve(root.rootDir, filePath);
42730
+ let relativeBase = root.rootDir;
42731
+ if (absoluteInput &&
42732
+ !path_isPathInside(root.rootDir, candidatePath) &&
42733
+ path_isPathInside(root.rootReal, candidatePath)) {
42734
+ // A Root created through an alias has two valid in-root absolute spellings.
42735
+ relativeBase = root.rootReal;
42736
+ }
42737
+ return external_node_path_.relative(relativeBase, candidatePath);
42738
+ }
41945
42739
  async function assertRootIdentityCurrent(root) {
41946
42740
  let current;
41947
42741
  try {
41948
- current = await promises_.lstat(root.rootReal);
42742
+ if (typeof root.rootIdentity.dev === "bigint" && typeof root.rootIdentity.ino === "bigint") {
42743
+ await inspectDirectoryIdentity(root.rootReal, { dev: root.rootIdentity.dev, ino: root.rootIdentity.ino });
42744
+ return;
42745
+ }
42746
+ current = external_node_fs_.lstatSync(root.rootReal);
41949
42747
  }
41950
42748
  catch (error) {
41951
42749
  throw new errors_FsSafeError("path-mismatch", "root path changed during operation", {
@@ -41973,7 +42771,7 @@ async function resolvePathInRoot(root, relativePath, options) {
41973
42771
  ? expanded
41974
42772
  : `${root.rootWithSep}${expanded}`;
41975
42773
  try {
41976
- await resolveRootPath({
42774
+ await root_path_resolveRootPath({
41977
42775
  absolutePath: rawAbsolutePath,
41978
42776
  rootPath: root.rootReal,
41979
42777
  rootCanonicalPath: root.rootReal,
@@ -42051,17 +42849,19 @@ async function* walkRoot(root, relativePath, options) {
42051
42849
  const maxEntries = validateBudget("maxEntries", options.maxEntries);
42052
42850
  const visitedDirectories = new Set();
42053
42851
  let examined = 0;
42852
+ let truncated = false;
42054
42853
  const onLimit = (atPath) => {
42055
42854
  if ((options.limitBehavior ?? "truncate") === "throw") {
42056
42855
  throw new errors_FsSafeError("too-large", `root walk budget exceeded at ${atPath || "."}`);
42057
42856
  }
42857
+ truncated = true;
42058
42858
  return limitEntry(atPath);
42059
42859
  };
42060
42860
  async function* visit(directory, depth) {
42061
42861
  options.signal?.throwIfAborted();
42062
42862
  let entries;
42063
42863
  try {
42064
- const resolvedDirectory = await resolveRootPath({
42864
+ const resolvedDirectory = await root_path_resolveRootPath({
42065
42865
  absolutePath: external_node_path_.resolve(root.rootReal, directory),
42066
42866
  rootPath: root.rootReal,
42067
42867
  rootCanonicalPath: root.rootReal,
@@ -42105,7 +42905,7 @@ async function* walkRoot(root, relativePath, options) {
42105
42905
  if (options.symlinkPolicy === "skip") {
42106
42906
  continue;
42107
42907
  }
42108
- const resolved = await resolveRootPath({
42908
+ const resolved = await root_path_resolveRootPath({
42109
42909
  absolutePath: external_node_path_.resolve(root.rootReal, child),
42110
42910
  rootPath: root.rootReal,
42111
42911
  rootCanonicalPath: root.rootReal,
@@ -42136,6 +42936,8 @@ async function* walkRoot(root, relativePath, options) {
42136
42936
  return;
42137
42937
  }
42138
42938
  yield* visit(child, depth + 1);
42939
+ if (truncated)
42940
+ return;
42139
42941
  }
42140
42942
  }
42141
42943
  yield* visit(relativePath, 0);
@@ -42153,7 +42955,7 @@ function pathStillMatchesReceipt(entry) {
42153
42955
  try {
42154
42956
  const current = external_node_fs_.lstatSync(entry.path, { bigint: true });
42155
42957
  return (!entry.singleLinkFile || (current.isFile() && current.nlink === 1n)) &&
42156
- sameFileIdentityForCleanup(current, entry.identity);
42958
+ file_identity_sameFileIdentityForCleanup(current, entry.identity);
42157
42959
  }
42158
42960
  catch (error) {
42159
42961
  return !entry.singleLinkFile && error.code === "ENOENT";
@@ -42184,7 +42986,7 @@ function cleanupRegisteredTempPathsSync() {
42184
42986
  }
42185
42987
  tempCleanupEntries.clear();
42186
42988
  }
42187
- function registerTempPathForExit(tempPath, options) {
42989
+ function temp_cleanup_registerTempPathForExit(tempPath, options) {
42188
42990
  if (!cleanupRegistered) {
42189
42991
  cleanupRegistered = true;
42190
42992
  process.once("exit", cleanupRegisteredTempPathsSync);
@@ -42288,21 +43090,27 @@ async function verifyAtomicWriteResult(params) {
42288
43090
  throw new errors_FsSafeError("path-mismatch", "descriptor changed during write");
42289
43091
  }
42290
43092
  assertFile(stat);
43093
+ if (process.platform !== "win32" && params.expectedMode !== undefined) {
43094
+ const actualMode = Number(stat.mode & 4095n);
43095
+ if (actualMode !== params.expectedMode) {
43096
+ throw new Error(`Private secret file ${params.targetPath} has insecure permissions ${actualMode.toString(8)}.`);
43097
+ }
43098
+ }
42291
43099
  return stat;
42292
43100
  };
42293
43101
  try {
42294
43102
  // This descriptor remains owned by the writer, even when final mode forbids opens.
42295
43103
  const stat = assertDescriptor();
42296
- assertPath(await promises_.lstat(params.targetPath, { bigint: true }));
42297
- const realPath = await resolveOpenedFileRealPathForFd(params.fd, stat, params.targetPath);
42298
- assertPath(await promises_.stat(realPath, { bigint: true }));
43104
+ assertPath(external_node_fs_.lstatSync(params.targetPath, { bigint: true }));
43105
+ const { realPath } = await resolveOpenedFileRealPathForFd(params.fd, stat, params.targetPath);
43106
+ assertPath(external_node_fs_.statSync(realPath, { bigint: true }));
42299
43107
  if (!path_isPathInside(params.root.rootWithSep, realPath)) {
42300
43108
  throw outsideWorkspaceError();
42301
43109
  }
42302
- await assertAsyncDirectoryGuard(params.parentGuard);
43110
+ await directory_guard_assertAsyncDirectoryGuard(params.parentGuard);
42303
43111
  await assertRootIdentityCurrent(params.root);
42304
43112
  // Recheck after canonical resolution and directory checks, including late links.
42305
- assertPath(await promises_.lstat(params.targetPath, { bigint: true }));
43113
+ assertPath(external_node_fs_.lstatSync(params.targetPath, { bigint: true }));
42306
43114
  assertDescriptor();
42307
43115
  if (needsPathOpen) {
42308
43116
  // A retained fd cannot prove that an opaque Windows pathname still names it.
@@ -42320,15 +43128,15 @@ async function verifyAtomicWriteResult(params) {
42320
43128
  });
42321
43129
  try {
42322
43130
  const reopenedStat = assertDescriptor(opened.fd);
42323
- assertPath(await promises_.lstat(params.targetPath, { bigint: true }));
42324
- const reopenedPath = await resolveOpenedFileRealPathForFd(opened.fd, reopenedStat, params.targetPath);
42325
- assertPath(await promises_.stat(reopenedPath, { bigint: true }));
43131
+ assertPath(external_node_fs_.lstatSync(params.targetPath, { bigint: true }));
43132
+ const { realPath: reopenedPath } = await resolveOpenedFileRealPathForFd(opened.fd, reopenedStat, params.targetPath);
43133
+ assertPath(external_node_fs_.statSync(reopenedPath, { bigint: true }));
42326
43134
  if (!path_isPathInside(params.root.rootWithSep, reopenedPath)) {
42327
43135
  throw outsideWorkspaceError();
42328
43136
  }
42329
- await assertAsyncDirectoryGuard(params.parentGuard);
43137
+ await directory_guard_assertAsyncDirectoryGuard(params.parentGuard);
42330
43138
  await assertRootIdentityCurrent(params.root);
42331
- assertPath(await promises_.lstat(params.targetPath, { bigint: true }));
43139
+ assertPath(external_node_fs_.lstatSync(params.targetPath, { bigint: true }));
42332
43140
  assertDescriptor(opened.fd);
42333
43141
  }
42334
43142
  finally {
@@ -42343,6 +43151,74 @@ async function verifyAtomicWriteResult(params) {
42343
43151
  }
42344
43152
  }
42345
43153
 
43154
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/root-write-mode.js
43155
+
43156
+
43157
+
43158
+
43159
+
43160
+
43161
+
43162
+
43163
+ // The caller has already resolved and guarded this write target.
43164
+ async function inheritWriteTargetMode(params) {
43165
+ try {
43166
+ const existing = await strict_file_identity_inspectFileIdentity(() => external_node_fs_.lstatSync(params.targetPath, { bigint: true }));
43167
+ if (existing.isSymbolicLink())
43168
+ throw new errors_FsSafeError("path-alias", "path alias escape blocked");
43169
+ if (!existing.isFile())
43170
+ throw new errors_FsSafeError("not-file", "not a file");
43171
+ if (existing.nlink > 1n)
43172
+ throw hardlinkedPathNotAllowedError();
43173
+ if (!path_isPathInside(params.rootWithSep, params.targetPath))
43174
+ throw outsideWorkspaceError();
43175
+ // Preserve read-open admission of the pre-existing destination. access(2)
43176
+ // is not equivalent: it ignores ACLs on Windows and capabilities on Linux.
43177
+ const handle = await promises_.open(params.targetPath, read_open_flags_resolveReadOpenFlags());
43178
+ try {
43179
+ // Bind admission to the inode whose metadata is inherited.
43180
+ if (!file_identity_sameFileIdentity(external_node_fs_.fstatSync(handle.fd, { bigint: true }), existing)) {
43181
+ throw new errors_FsSafeError("path-mismatch", "write target changed during mode inheritance");
43182
+ }
43183
+ }
43184
+ finally {
43185
+ await handle.close().catch(() => undefined);
43186
+ }
43187
+ try {
43188
+ // A parent can change after guarded resolution. Do not inherit metadata
43189
+ // from an outside inode, even if the parent is restored before publication.
43190
+ const realPath = external_node_fs_.realpathSync.native(params.targetPath);
43191
+ if (!path_isPathInside(params.rootWithSep, realPath))
43192
+ throw outsideWorkspaceError();
43193
+ await strict_file_identity_inspectFileIdentity(async () => {
43194
+ const current = external_node_fs_.statSync(realPath, { bigint: true });
43195
+ if (!current.isFile())
43196
+ throw new errors_FsSafeError("not-file", "not a file");
43197
+ if (current.nlink > 1n)
43198
+ throw hardlinkedPathNotAllowedError();
43199
+ return current;
43200
+ }, existing);
43201
+ }
43202
+ catch (error) {
43203
+ if (path_isNotFoundPathError(error)) {
43204
+ throw new errors_FsSafeError("path-mismatch", "write target changed during mode inheritance", { cause: error });
43205
+ }
43206
+ throw error;
43207
+ }
43208
+ return params.requestedMode ?? Number(existing.mode & 511n);
43209
+ }
43210
+ catch (error) {
43211
+ if (!path_isNotFoundPathError(error))
43212
+ throw error;
43213
+ return params.requestedMode ?? 0o600;
43214
+ }
43215
+ }
43216
+
43217
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/copy-publication.js
43218
+ // Internal composition hook; the descriptor is borrowed until the callback returns.
43219
+ // Kept off RootCopyOptions and all public package exports.
43220
+ const onCopyPublication = Symbol("onCopyPublication");
43221
+
42346
43222
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/root-impl.js
42347
43223
 
42348
43224
 
@@ -42372,6 +43248,9 @@ async function verifyAtomicWriteResult(params) {
42372
43248
 
42373
43249
 
42374
43250
 
43251
+
43252
+
43253
+
42375
43254
 
42376
43255
 
42377
43256
 
@@ -42384,12 +43263,14 @@ function logWarn(message) {
42384
43263
  const SUPPORTS_NOFOLLOW = process.platform !== "win32" && "O_NOFOLLOW" in external_node_fs_.constants;
42385
43264
  const OPEN_READ_FLAGS = read_open_flags_resolveReadOpenFlags();
42386
43265
  const OPEN_READ_FOLLOW_FLAGS = read_open_flags_resolveReadOpenFlags({ followSymlinks: true });
42387
- const OPEN_WRITE_EXISTING_FLAGS = external_node_fs_.constants.O_WRONLY | (SUPPORTS_NOFOLLOW ? external_node_fs_.constants.O_NOFOLLOW : 0);
43266
+ const OPEN_WRITE_EXISTING_FLAGS = external_node_fs_.constants.O_WRONLY | (SUPPORTS_NOFOLLOW ? external_node_fs_.constants.O_NOFOLLOW : 0) |
43267
+ resolveNonblockingWriteFlag();
42388
43268
  const OPEN_WRITE_CREATE_FLAGS = external_node_fs_.constants.O_WRONLY |
42389
43269
  external_node_fs_.constants.O_CREAT |
42390
43270
  external_node_fs_.constants.O_EXCL |
42391
43271
  (SUPPORTS_NOFOLLOW ? external_node_fs_.constants.O_NOFOLLOW : 0);
42392
- const OPEN_APPEND_EXISTING_FLAGS = external_node_fs_.constants.O_RDWR | external_node_fs_.constants.O_APPEND | (SUPPORTS_NOFOLLOW ? external_node_fs_.constants.O_NOFOLLOW : 0);
43272
+ const OPEN_APPEND_EXISTING_FLAGS = external_node_fs_.constants.O_RDWR | external_node_fs_.constants.O_APPEND | (SUPPORTS_NOFOLLOW ? external_node_fs_.constants.O_NOFOLLOW : 0) |
43273
+ resolveNonblockingWriteFlag();
42393
43274
  const OPEN_APPEND_CREATE_FLAGS = external_node_fs_.constants.O_RDWR |
42394
43275
  external_node_fs_.constants.O_APPEND |
42395
43276
  external_node_fs_.constants.O_CREAT |
@@ -42428,8 +43309,8 @@ async function openVerifiedLocalFile(filePath, options) {
42428
43309
  // Reject directories before opening so we never surface EISDIR to callers (e.g. tool
42429
43310
  // results that get sent to messaging channels). See openclaw/openclaw#31186.
42430
43311
  try {
42431
- preOpenStat = await inspectFileIdentity(async () => {
42432
- const stat = await promises_.lstat(filePath, { bigint: true });
43312
+ preOpenStat = await strict_file_identity_inspectFileIdentity(async () => {
43313
+ const stat = external_node_fs_.lstatSync(filePath, { bigint: true });
42433
43314
  observedBeforeOpen = true;
42434
43315
  if (stat.isSymbolicLink() && options?.symlinks !== "follow-within-root") {
42435
43316
  throw new errors_FsSafeError("symlink", "symlink not allowed");
@@ -42469,13 +43350,13 @@ async function openVerifiedLocalFile(filePath, options) {
42469
43350
  }
42470
43351
  try {
42471
43352
  await fsSafeTestHooks?.afterOpen?.(filePath, handle);
42472
- const stat = await handle.stat();
43353
+ const stat = external_node_fs_.fstatSync(handle.fd);
42473
43354
  if (!stat.isFile()) {
42474
43355
  throw new errors_FsSafeError("not-file", "not a file");
42475
43356
  }
42476
43357
  // Keep numeric Stats for the public receipt, never for identity verification.
42477
43358
  let openedIdentity;
42478
- const identity = await inspectFileIdentity(async () => (openedIdentity = await handle.stat({ bigint: true })), preOpenStat && !preOpenStat.isSymbolicLink() ? preOpenStat : undefined).catch(async (error) => {
43359
+ const identity = await strict_file_identity_inspectFileIdentity(async () => (openedIdentity = external_node_fs_.fstatSync(handle.fd, { bigint: true })), preOpenStat && !preOpenStat.isSymbolicLink() ? preOpenStat : undefined).catch(async (error) => {
42479
43360
  if ([0, 1].includes(stat.nlink)) {
42480
43361
  await recordPreOpenFileChange(error, handle, filePath, preOpenStat, openedIdentity);
42481
43362
  }
@@ -42486,7 +43367,7 @@ async function openVerifiedLocalFile(filePath, options) {
42486
43367
  }
42487
43368
  const inspectPathIdentity = async (inspect) => {
42488
43369
  try {
42489
- return await inspectFileIdentity(inspect, identity);
43370
+ return await strict_file_identity_inspectFileIdentity(inspect, identity);
42490
43371
  }
42491
43372
  catch (error) {
42492
43373
  const failure = path_isNotFoundPathError(error) ? openedPathResolutionError(fileNotFoundError()) : error;
@@ -42498,23 +43379,28 @@ async function openVerifiedLocalFile(filePath, options) {
42498
43379
  };
42499
43380
  await inspectPathIdentity(async () => {
42500
43381
  const pathStat = options?.symlinks === "follow-within-root"
42501
- ? await promises_.stat(filePath, { bigint: true })
42502
- : await promises_.lstat(filePath, { bigint: true });
43382
+ ? external_node_fs_.statSync(filePath, { bigint: true })
43383
+ : external_node_fs_.lstatSync(filePath, { bigint: true });
42503
43384
  if (pathStat.isSymbolicLink() && options?.symlinks !== "follow-within-root") {
42504
43385
  throw new errors_FsSafeError("symlink", "symlink not allowed");
42505
43386
  }
42506
43387
  return pathStat;
42507
43388
  });
42508
43389
  await fsSafeTestHooks?.afterOpenedPathIdentityCheck?.(filePath, handle);
42509
- const realPath = await resolveOpenedFileRealPathForFd(handle.fd, identity, filePath)
43390
+ const resolved = await resolveOpenedFileRealPathForFd(handle.fd, identity, filePath)
42510
43391
  .catch(async (error) => {
42511
43392
  if (stat.nlink <= 1 && (!preOpenStat || preOpenStat.nlink <= 1n)) {
42512
43393
  await recordOpenedFileFailure(error, handle, filePath, identity);
42513
43394
  }
42514
43395
  throw error;
42515
43396
  });
43397
+ const { realPath } = resolved;
43398
+ let resolvedStat = resolved.stat;
42516
43399
  await inspectPathIdentity(async () => {
42517
- const realStat = await promises_.stat(realPath, { bigint: true });
43400
+ // Reuse the post-realpath observation; unknown Windows identities still
43401
+ // get a fresh observation on inspectFileIdentity's retry.
43402
+ const realStat = resolvedStat ?? external_node_fs_.statSync(realPath, { bigint: true });
43403
+ resolvedStat = undefined;
42518
43404
  if (options?.hardlinks === "reject" && realStat.nlink > 1n) {
42519
43405
  throw hardlinkedPathNotAllowedError();
42520
43406
  }
@@ -42612,6 +43498,7 @@ class RootHandle {
42612
43498
  mkdir: this.defaults.mkdir,
42613
43499
  mode: this.defaults.mode,
42614
43500
  ...this.mutationOptions(options),
43501
+ durable: options.durable ?? this.defaults.durable ?? true,
42615
43502
  });
42616
43503
  }
42617
43504
  async remove(relativePath, options = {}) {
@@ -42644,6 +43531,7 @@ class RootHandle {
42644
43531
  mode: this.defaults.mode,
42645
43532
  renameIdentity: this.defaults.renameIdentity,
42646
43533
  ...this.mutationOptions(options),
43534
+ durable: options.durable ?? this.defaults.durable ?? true,
42647
43535
  });
42648
43536
  }
42649
43537
  async create(relativePath, data, options = {}) {
@@ -42654,6 +43542,7 @@ class RootHandle {
42654
43542
  mkdir: this.defaults.mkdir,
42655
43543
  mode: this.defaults.mode,
42656
43544
  ...this.mutationOptions(options),
43545
+ durable: options.durable ?? this.defaults.durable ?? true,
42657
43546
  overwrite: false,
42658
43547
  });
42659
43548
  }
@@ -42677,6 +43566,8 @@ class RootHandle {
42677
43566
  mkdir: this.defaults.mkdir,
42678
43567
  mode: this.defaults.mode,
42679
43568
  ...copyOptions,
43569
+ durable: options.durable ?? this.defaults.durable ?? true,
43570
+ verifyPublished: options[onCopyPublication],
42680
43571
  });
42681
43572
  }
42682
43573
  async exists(relativePath) {
@@ -42727,7 +43618,6 @@ function readDefaults(defaults) {
42727
43618
  return {
42728
43619
  hardlinks: defaults.hardlinks,
42729
43620
  maxBytes: byte_budget_normalizeMaxBytes(defaults.maxBytes, { defaultValue: DEFAULT_ROOT_MAX_BYTES }),
42730
- nonBlockingRead: defaults.nonBlockingRead,
42731
43621
  symlinks: defaults.symlinks,
42732
43622
  };
42733
43623
  }
@@ -42736,8 +43626,6 @@ function mergeReadOptions(defaults, options) {
42736
43626
  if (options.hardlinks !== undefined)
42737
43627
  merged.hardlinks = options.hardlinks;
42738
43628
  merged.maxBytes = byte_budget_normalizeMaxBytes(options.maxBytes, { defaultValue: merged.maxBytes });
42739
- if (options.nonBlockingRead !== undefined)
42740
- merged.nonBlockingRead = options.nonBlockingRead;
42741
43629
  if (options.symlinks !== undefined)
42742
43630
  merged.symlinks = options.symlinks;
42743
43631
  return merged;
@@ -42753,7 +43641,6 @@ async function openFileInRoot(root, params) {
42753
43641
  rejectSymlinks: params.symlinks !== "follow-within-root",
42754
43642
  });
42755
43643
  const { opened } = await openVerifiedLocalFile(resolved, {
42756
- nonBlockingRead: params.nonBlockingRead,
42757
43644
  symlinks: params.symlinks,
42758
43645
  });
42759
43646
  if (params.hardlinks !== "allow" && opened.stat.nlink > 1) {
@@ -42776,16 +43663,11 @@ async function readFileInRoot(root, params) {
42776
43663
  }
42777
43664
  }
42778
43665
  async function readPathInRoot(root, params) {
42779
- const rootDir = root.rootDir;
42780
- const candidatePath = external_node_path_.isAbsolute(params.filePath)
42781
- ? external_node_path_.resolve(params.filePath)
42782
- : external_node_path_.resolve(rootDir, params.filePath);
42783
- const relativePath = external_node_path_.relative(rootDir, candidatePath);
43666
+ const relativePath = rootRelativeReadPath(root, params.filePath);
42784
43667
  return await readFileInRoot(root, {
42785
43668
  relativePath,
42786
43669
  hardlinks: params.hardlinks,
42787
43670
  maxBytes: params.maxBytes,
42788
- nonBlockingRead: params.nonBlockingRead,
42789
43671
  symlinks: params.symlinks,
42790
43672
  });
42791
43673
  }
@@ -42832,7 +43714,7 @@ async function writeTempFileForAtomicReplace(params) {
42832
43714
  }
42833
43715
  return {
42834
43716
  handle: tempHandle,
42835
- identity: await tempHandle.stat({ bigint: true }),
43717
+ identity: external_node_fs_.fstatSync(tempHandle.fd, { bigint: true }),
42836
43718
  };
42837
43719
  }
42838
43720
  catch (error) {
@@ -42871,7 +43753,7 @@ async function openWritableFileInRoot(root, params) {
42871
43753
  ? resolved
42872
43754
  : await prepareRootWriteTarget(rootReal, resolved);
42873
43755
  try {
42874
- const resolvedRealPath = await promises_.realpath(ioPath);
43756
+ const resolvedRealPath = external_node_fs_.realpathSync.native(ioPath);
42875
43757
  if (!path_isPathInside(rootWithSep, resolvedRealPath)) {
42876
43758
  throw outsideWorkspaceError();
42877
43759
  }
@@ -42895,6 +43777,9 @@ async function openWritableFileInRoot(root, params) {
42895
43777
  handle = await promises_.open(ioPath, existingFlags, mode);
42896
43778
  }
42897
43779
  catch (err) {
43780
+ if (await isNonRegularWriteOpenError(err, ioPath, existingFlags)) {
43781
+ throw new errors_FsSafeError("not-file", "path is not a regular file under root");
43782
+ }
42898
43783
  if (!path_isNotFoundPathError(err)) {
42899
43784
  throw err;
42900
43785
  }
@@ -42917,7 +43802,7 @@ async function openWritableFileInRoot(root, params) {
42917
43802
  let realPathForCleanup = null;
42918
43803
  let createdIdentity = null;
42919
43804
  try {
42920
- const stat = await handle.stat();
43805
+ const stat = external_node_fs_.fstatSync(handle.fd);
42921
43806
  if (createdForWrite) {
42922
43807
  createdIdentity = stat;
42923
43808
  }
@@ -42928,7 +43813,7 @@ async function openWritableFileInRoot(root, params) {
42928
43813
  throw hardlinkedPathNotAllowedError();
42929
43814
  }
42930
43815
  try {
42931
- const lstat = await promises_.lstat(ioPath);
43816
+ const lstat = external_node_fs_.lstatSync(ioPath);
42932
43817
  if (lstat.isSymbolicLink() || !lstat.isFile()) {
42933
43818
  throw new errors_FsSafeError(lstat.isSymbolicLink() ? "symlink" : "not-file", "path is not a regular file under root");
42934
43819
  }
@@ -42943,7 +43828,7 @@ async function openWritableFileInRoot(root, params) {
42943
43828
  }
42944
43829
  const realPath = await resolveOpenedFileRealPathForHandle(handle, ioPath);
42945
43830
  realPathForCleanup = realPath;
42946
- const realStat = await promises_.stat(realPath);
43831
+ const realStat = external_node_fs_.statSync(realPath);
42947
43832
  if (!file_identity_sameFileIdentity(stat, realStat)) {
42948
43833
  throw new errors_FsSafeError("path-mismatch", "path mismatch");
42949
43834
  }
@@ -43006,8 +43891,9 @@ async function appendFileInRoot(root, params) {
43006
43891
  const payload = prefix.length > 0 ? Buffer.concat([Buffer.from(prefix, "utf8"), params.data]) : params.data;
43007
43892
  await target.handle.appendFile(payload);
43008
43893
  }
43009
- await target.handle.sync();
43010
- if (target.createdForWrite) {
43894
+ if (params.durable !== false)
43895
+ await target.handle.sync();
43896
+ if (params.durable !== false && target.createdForWrite) {
43011
43897
  await syncDirectoryBestEffort(external_node_path_.dirname(target.realPath));
43012
43898
  }
43013
43899
  }
@@ -43063,6 +43949,7 @@ async function commitPinnedWriteInRoot(root, pinned, params) {
43063
43949
  renameIdentity: params.renameIdentity,
43064
43950
  mkdir: params.mkdir !== false,
43065
43951
  mode: params.mode ?? pinned.mode,
43952
+ sync: params.durable !== false,
43066
43953
  overwrite: params.overwrite,
43067
43954
  input: { kind: "buffer", data: params.data, encoding: params.encoding },
43068
43955
  rootIdentity: root.rootIdentity,
@@ -43124,6 +44011,8 @@ async function copyFileInRoot(root, params) {
43124
44011
  mode: pinned.mode,
43125
44012
  overwrite: true,
43126
44013
  maxBytes: params.maxBytes,
44014
+ sync: params.durable !== false,
44015
+ verifyPublished: params.verifyPublished,
43127
44016
  input: { kind: "stream", stream: source.handle.createReadStream() },
43128
44017
  rootIdentity: root.rootIdentity,
43129
44018
  });
@@ -43146,12 +44035,12 @@ async function copyFileInRoot(root, params) {
43146
44035
  }
43147
44036
  }
43148
44037
  async function assertCopySourceCurrent(source, identity) {
43149
- await inspectFileIdentity(() => source.handle.stat({ bigint: true }), identity);
44038
+ await strict_file_identity_inspectFileIdentity(() => external_node_fs_.fstatSync(source.handle.fd, { bigint: true }), identity);
43150
44039
  await assertCopySourcePathCurrent(source, identity);
43151
44040
  }
43152
44041
  async function assertCopySourcePathCurrent(source, identity) {
43153
- await inspectFileIdentity(async () => {
43154
- const current = await promises_.lstat(source.realPath, { bigint: true });
44042
+ await strict_file_identity_inspectFileIdentity(async () => {
44043
+ const current = external_node_fs_.lstatSync(source.realPath, { bigint: true });
43155
44044
  if (current.isSymbolicLink() || !current.isFile()) {
43156
44045
  throw new errors_FsSafeError("path-mismatch", "copy source path changed");
43157
44046
  }
@@ -43160,8 +44049,8 @@ async function assertCopySourcePathCurrent(source, identity) {
43160
44049
  }
43161
44050
  async function removePathIfIdentityUnchanged(targetPath, identity) {
43162
44051
  const parentGuard = await directory_guard_createAsyncDirectoryGuard(external_node_path_.dirname(targetPath));
43163
- const current = await promises_.lstat(targetPath);
43164
- if (current.isSymbolicLink() || !sameFileIdentityForCleanup(current, identity)) {
44052
+ const current = external_node_fs_.lstatSync(targetPath);
44053
+ if (current.isSymbolicLink() || !file_identity_sameFileIdentityForCleanup(current, identity)) {
43165
44054
  return;
43166
44055
  }
43167
44056
  await withAsyncDirectoryGuards([parentGuard], async () => {
@@ -43190,7 +44079,7 @@ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode,
43190
44079
  // and alias checks, but never open a competing owner's record just to reject it.
43191
44080
  if (!overwrite) {
43192
44081
  try {
43193
- const existing = await promises_.stat(resolved);
44082
+ const existing = external_node_fs_.statSync(resolved);
43194
44083
  if (!existing.isFile())
43195
44084
  throw new errors_FsSafeError("not-file", "not a file");
43196
44085
  if (existing.nlink > 1)
@@ -43202,31 +44091,9 @@ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode,
43202
44091
  throw error;
43203
44092
  }
43204
44093
  }
43205
- let mode = requestedMode ?? 0o600;
43206
- try {
43207
- if (overwrite) {
43208
- const opened = await openFileInRoot(root, {
43209
- relativePath,
43210
- hardlinks: "reject",
43211
- nonBlockingRead: true,
43212
- symlinks: "follow-within-root",
43213
- });
43214
- try {
43215
- mode = requestedMode ?? (opened.stat.mode & 0o777);
43216
- if (!path_isPathInside(rootWithSep, opened.realPath)) {
43217
- throw outsideWorkspaceError();
43218
- }
43219
- }
43220
- finally {
43221
- await opened.handle.close().catch(() => { });
43222
- }
43223
- }
43224
- }
43225
- catch (err) {
43226
- if (!(err instanceof errors_FsSafeError) || err.code !== "not-found") {
43227
- throw err;
43228
- }
43229
- }
44094
+ const mode = overwrite
44095
+ ? await inheritWriteTargetMode({ targetPath: resolved, rootWithSep, requestedMode })
44096
+ : requestedMode ?? 0o600;
43230
44097
  return {
43231
44098
  rootReal,
43232
44099
  targetPath: resolved,
@@ -43276,7 +44143,7 @@ async function resolvePinnedRootPathInRoot(root, params) {
43276
44143
  let resolved;
43277
44144
  try {
43278
44145
  const expandedPath = await expandRelativePathWithHome(params.relativePath);
43279
- resolved = await resolveRootPath({
44146
+ resolved = await root_path_resolveRootPath({
43280
44147
  absolutePath: external_node_path_.isAbsolute(expandedPath)
43281
44148
  ? expandedPath
43282
44149
  : `${ensureTrailingSep(rootReal)}${expandedPath}`,
@@ -43300,7 +44167,7 @@ async function prepareRemoveGuard(targetPath) {
43300
44167
  try {
43301
44168
  const guard = await directory_guard_createAsyncDirectoryGuard(external_node_path_.dirname(targetPath));
43302
44169
  await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("remove", targetPath);
43303
- await assertAsyncDirectoryGuard(guard);
44170
+ await directory_guard_assertAsyncDirectoryGuard(guard);
43304
44171
  return guard;
43305
44172
  }
43306
44173
  catch (error) {
@@ -43310,12 +44177,12 @@ async function prepareRemoveGuard(targetPath) {
43310
44177
  async function removePathFallback(resolved) {
43311
44178
  const guard = await prepareRemoveGuard(resolved.resolved);
43312
44179
  try {
43313
- await ((await promises_.lstat(resolved.resolved)).isDirectory() ? promises_.rmdir(resolved.resolved) : promises_.rm(resolved.resolved));
44180
+ await (external_node_fs_.lstatSync(resolved.resolved).isDirectory() ? promises_.rmdir(resolved.resolved) : promises_.rm(resolved.resolved));
43314
44181
  }
43315
44182
  catch (error) {
43316
44183
  throw normalizeRemovePathError(error);
43317
44184
  }
43318
- await assertAsyncDirectoryGuard(guard).catch(() => undefined);
44185
+ await directory_guard_assertAsyncDirectoryGuard(guard).catch(() => undefined);
43319
44186
  }
43320
44187
  async function mkdirPathFallback(resolved) {
43321
44188
  await mkdirPathComponentsWithGuards({
@@ -43326,7 +44193,7 @@ async function mkdirPathFallback(resolved) {
43326
44193
  async function statPathFallback(root, relativePath) {
43327
44194
  const resolved = await resolvePinnedPathInRoot(root, { relativePath, allowRoot: true });
43328
44195
  try {
43329
- const stat = pathStatFromStats(await promises_.lstat(resolved.resolved));
44196
+ const stat = pathStatFromStats(external_node_fs_.lstatSync(resolved.resolved));
43330
44197
  await assertRootIdentityCurrent(root);
43331
44198
  return stat;
43332
44199
  }
@@ -43350,7 +44217,7 @@ async function listPathFallback(root, relativePath, withFileTypes) {
43350
44217
  for (const name of sortedNames) {
43351
44218
  entries.push({
43352
44219
  name,
43353
- ...pathStatFromStats(await promises_.lstat(external_node_path_.join(resolved.resolved, name))),
44220
+ ...pathStatFromStats(external_node_fs_.lstatSync(external_node_path_.join(resolved.resolved, name))),
43354
44221
  });
43355
44222
  }
43356
44223
  await assertRootIdentityCurrent(root);
@@ -43399,7 +44266,11 @@ async function movePathFallback(root, params) {
43399
44266
  relativePath: params.toRelative,
43400
44267
  policy: PATH_ALIAS_POLICIES.unlinkTarget,
43401
44268
  });
43402
- const targetStat = await promises_.lstat(resolvedTarget.resolved).catch(() => undefined);
44269
+ let targetStat;
44270
+ try {
44271
+ targetStat = external_node_fs_.lstatSync(resolvedTarget.resolved);
44272
+ }
44273
+ catch { /* Advisory lookup. */ }
43403
44274
  return !(process.platform !== "win32" &&
43404
44275
  params.overwrite &&
43405
44276
  targetStat?.isSymbolicLink() === true);
@@ -43407,7 +44278,7 @@ async function movePathFallback(root, params) {
43407
44278
  });
43408
44279
  let sourceStat;
43409
44280
  try {
43410
- sourceStat = await promises_.lstat(source.resolved);
44281
+ sourceStat = external_node_fs_.lstatSync(source.resolved);
43411
44282
  }
43412
44283
  catch (error) {
43413
44284
  if (path_isNotFoundPathError(error)) {
@@ -43426,7 +44297,7 @@ async function movePathFallback(root, params) {
43426
44297
  }
43427
44298
  if (!params.overwrite) {
43428
44299
  try {
43429
- await promises_.lstat(target.resolved);
44300
+ external_node_fs_.lstatSync(target.resolved);
43430
44301
  throw new errors_FsSafeError("already-exists", "destination exists");
43431
44302
  }
43432
44303
  catch (error) {
@@ -43441,8 +44312,8 @@ async function movePathFallback(root, params) {
43441
44312
  const sourceParentGuard = await directory_guard_createAsyncDirectoryGuard(external_node_path_.dirname(source.resolved));
43442
44313
  const targetParentGuard = await directory_guard_createNearestExistingDirectoryGuard(target.rootReal, external_node_path_.dirname(target.resolved));
43443
44314
  await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("move", target.resolved);
43444
- await assertAsyncDirectoryGuard(sourceParentGuard);
43445
- await assertAsyncDirectoryGuard(targetParentGuard);
44315
+ await directory_guard_assertAsyncDirectoryGuard(sourceParentGuard);
44316
+ await directory_guard_assertAsyncDirectoryGuard(targetParentGuard);
43446
44317
  try {
43447
44318
  await promises_.rename(source.resolved, target.resolved);
43448
44319
  }
@@ -43457,7 +44328,7 @@ async function movePathFallback(root, params) {
43457
44328
  }
43458
44329
  throw error;
43459
44330
  }
43460
- await assertAsyncDirectoryGuard(targetParentGuard).catch(() => undefined);
44331
+ await directory_guard_assertAsyncDirectoryGuard(targetParentGuard).catch(() => undefined);
43461
44332
  }
43462
44333
  async function writeFileFallback(root, params) {
43463
44334
  if (params.overwrite === false) {
@@ -43467,7 +44338,8 @@ async function writeFileFallback(root, params) {
43467
44338
  const target = await openWritableFileInRoot(root, {
43468
44339
  relativePath: params.relativePath,
43469
44340
  mkdir: params.mkdir,
43470
- mode: params.mode,
44341
+ // Private, writable placeholder: Windows cannot rename over a read-only file.
44342
+ mode: 0o600,
43471
44343
  denyMutations: params.denyMutations,
43472
44344
  truncateExisting: false,
43473
44345
  });
@@ -43480,12 +44352,12 @@ async function writeFileFallback(root, params) {
43480
44352
  let writtenHandle;
43481
44353
  try {
43482
44354
  tempPath = buildAtomicWriteTempPath(destinationPath);
43483
- unregisterTempPath = registerTempPathForExit(tempPath);
44355
+ unregisterTempPath = temp_cleanup_registerTempPathForExit(tempPath);
43484
44356
  const written = await writeTempFileForAtomicReplace({
43485
44357
  tempPath,
43486
44358
  data: params.data,
43487
44359
  encoding: params.encoding,
43488
- mode,
44360
+ mode: 0o600,
43489
44361
  });
43490
44362
  writtenHandle = written.handle;
43491
44363
  unregisterTempPath.setIdentity(written.identity);
@@ -43496,6 +44368,14 @@ async function writeFileFallback(root, params) {
43496
44368
  });
43497
44369
  unregisterTempPath();
43498
44370
  unregisterTempPath = null;
44371
+ // Final mode via the retained handle after publication, as the native writer does.
44372
+ try {
44373
+ await written.handle.chmod(mode);
44374
+ }
44375
+ catch (error) {
44376
+ await removePathIfIdentityUnchanged(destinationPath, written.identity).catch(() => { });
44377
+ throw error;
44378
+ }
43499
44379
  try {
43500
44380
  await verifyAtomicWriteResult({
43501
44381
  root,
@@ -43533,11 +44413,11 @@ async function writeMissingFileFallback(root, params) {
43533
44413
  let verifyingPublication = false;
43534
44414
  try {
43535
44415
  const { handle, writtenStat } = await withAsyncDirectoryGuards([parentGuard], async () => {
43536
- const handle = await promises_.open(targetPath, OPEN_WRITE_CREATE_FLAGS, params.mode ?? 0o600);
44416
+ const handle = await promises_.open(targetPath, OPEN_WRITE_CREATE_FLAGS, params.mode ?? 0o600).catch((error) => recordExclusiveCreateFailure(error, targetPath));
43537
44417
  created = true;
43538
44418
  try {
43539
- createdIdentity = await handle.stat();
43540
- const writtenStat = await handle.stat({ bigint: true });
44419
+ createdIdentity = external_node_fs_.fstatSync(handle.fd);
44420
+ const writtenStat = external_node_fs_.fstatSync(handle.fd, { bigint: true });
43541
44421
  if (typeof params.data === "string") {
43542
44422
  await handle.writeFile(params.data, params.encoding ?? "utf8");
43543
44423
  }
@@ -92069,4 +92949,4 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
92069
92949
  // module factories are used so entry inlining is disabled
92070
92950
  // startup
92071
92951
  // Load entry module and return exports
92072
- var __webpack_exports__ = __webpack_require__(3829);
92952
+ var __webpack_exports__ = __webpack_require__(6732);