@lousy-agents/mcp 5.14.9 → 5.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/116.js CHANGED
@@ -2,9 +2,6 @@ export const __rspack_esm_id = 116;
2
2
  export const __rspack_esm_ids = [116];
3
3
  export const __webpack_modules__ = {
4
4
  8711(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
5
- __webpack_require__.d(__webpack_exports__, {
6
- prompt: () => (prompt)
7
- });
8
5
  /* import */ var node_util__rspack_import_0 = __webpack_require__(7975);
9
6
  /* import */ var node_process__rspack_import_1 = __webpack_require__(1708);
10
7
  /* import */ var node_readline__rspack_import_2 = __webpack_require__(481);
@@ -290,6 +287,10 @@ async function prompt(message, opts = {}) {
290
287
 
291
288
 
292
289
 
290
+ __webpack_require__.d(__webpack_exports__, {
291
+ prompt: () => (prompt)
292
+ });
293
+
293
294
 
294
295
  },
295
296
 
package/dist/316.js CHANGED
@@ -4,9 +4,6 @@ export const __webpack_modules__ = {
4
4
  5375(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
5
5
  var zlib__rspack_import_11_namespace_cache;
6
6
  __webpack_require__.r(__webpack_exports__);
7
- __webpack_require__.d(__webpack_exports__, {
8
- t: () => (ce)
9
- });
10
7
  /* import */ var _rolldown_runtime_mjs__rspack_import_14 = __webpack_require__(421);
11
8
  /* import */ var node_fs__rspack_import_0 = __webpack_require__(3024);
12
9
  /* import */ var node_fs_promises__rspack_import_1 = __webpack_require__(1455);
@@ -2954,6 +2951,10 @@ var Da = (e) => {
2954
2951
  };
2955
2952
 
2956
2953
 
2954
+ __webpack_require__.d(__webpack_exports__, {
2955
+ t: () => (ce)
2956
+ });
2957
+
2957
2958
 
2958
2959
  },
2959
2960
 
package/dist/475.js CHANGED
@@ -1729,10 +1729,10 @@ class FSWatcher extends external_node_events_.EventEmitter {
1729
1729
  const options = { type: EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 };
1730
1730
  let stream = readdirp(root, options);
1731
1731
  this._streams.add(stream);
1732
- stream.once(STR_CLOSE, () => {
1732
+ stream.once((/* inlined export .STR_CLOSE */"close"), () => {
1733
1733
  stream = undefined;
1734
1734
  });
1735
- stream.once(STR_END, () => {
1735
+ stream.once((/* inlined export .STR_END */"end"), () => {
1736
1736
  if (stream) {
1737
1737
  this._streams.delete(stream);
1738
1738
  stream = undefined;
package/dist/653.js CHANGED
@@ -3,13 +3,6 @@ export const __rspack_esm_ids = [653];
3
3
  export const __webpack_modules__ = {
4
4
  292(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
5
5
  __webpack_require__.r(__webpack_exports__);
6
- __webpack_require__.d(__webpack_exports__, {
7
- a: () => (y),
8
- i: () => (S),
9
- n: () => (ne),
10
- r: () => (C),
11
- t: () => (oe)
12
- });
13
6
  /* import */ var _rolldown_runtime_mjs__rspack_import_8 = __webpack_require__(421);
14
7
  /* import */ var node_module__rspack_import_0 = __webpack_require__(8995);
15
8
  /* import */ var node_fs__rspack_import_1 = __webpack_require__(3024);
@@ -689,12 +682,18 @@ async function fe(e = {}) {
689
682
  }
690
683
 
691
684
 
685
+ __webpack_require__.d(__webpack_exports__, {
686
+ t: () => (oe)
687
+ }, {
688
+ a: y,
689
+ i: S,
690
+ n: ne,
691
+ r: C
692
+ });
693
+
692
694
 
693
695
  },
694
696
  421(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
695
- __webpack_require__.d(__webpack_exports__, {
696
- t: () => (__exportAll)
697
- });
698
697
  /* import */ var node_module__rspack_import_0 = __webpack_require__(8995);
699
698
 
700
699
  //#region \0rolldown/runtime.js
@@ -711,6 +710,10 @@ var __exportAll = (all, no_symbols) => {
711
710
  //#endregion
712
711
 
713
712
 
713
+ __webpack_require__.d(__webpack_exports__, {
714
+ t: () => (__exportAll)
715
+ });
716
+
714
717
 
715
718
  },
716
719
  8900(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
@@ -6559,7 +6559,7 @@ function escapeJsonPtr(str) {
6559
6559
 
6560
6560
 
6561
6561
  },
6562
- 3523(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
6562
+ 2229(__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);
@@ -26726,6 +26726,9 @@ function path_isPathInside(root, target) {
26726
26726
  const firstSegment = relative.split(external_node_path_.posix.sep)[0];
26727
26727
  return relative === "" || (firstSegment !== ".." && !external_node_path_.isAbsolute(relative));
26728
26728
  }
26729
+ function isPathRelativeEscape(relativePath) {
26730
+ return relativePath === ".." || relativePath.startsWith(`..${external_node_path_.sep}`) || external_node_path_.isAbsolute(relativePath);
26731
+ }
26729
26732
  function resolveSafeBaseDir(rootDir) {
26730
26733
  const resolved = path.resolve(rootDir);
26731
26734
  return resolved.endsWith(path.sep) ? resolved : `${resolved}${path.sep}`;
@@ -26874,17 +26877,17 @@ function directory_guard_createNearestExistingSyncDirectoryGuard(rootReal, targe
26874
26877
 
26875
26878
 
26876
26879
 
26880
+
26877
26881
  function isSameOrChildPath(candidate, parent) {
26878
- return candidate === parent || candidate.startsWith(`${parent}${external_node_path_.sep}`);
26879
- }
26880
- function isPathEscape(relativePath) {
26881
- return relativePath === ".." || relativePath.startsWith(`..${external_node_path_.sep}`) || external_node_path_.isAbsolute(relativePath);
26882
+ const parentPrefix = parent.endsWith(external_node_path_.sep) ? parent : `${parent}${external_node_path_.sep}`;
26883
+ return candidate === parent || candidate.startsWith(parentPrefix);
26882
26884
  }
26883
26885
  async function mkdirPathComponentsWithGuards(params) {
26884
26886
  const root = external_node_path_.resolve(params.rootReal);
26887
+ const rootCanonical = external_node_path_.resolve(await promises_.realpath(root));
26885
26888
  const target = external_node_path_.resolve(params.targetPath);
26886
26889
  const relative = external_node_path_.relative(root, target);
26887
- if (isPathEscape(relative)) {
26890
+ if (isPathRelativeEscape(relative)) {
26888
26891
  throw new errors_FsSafeError("outside-workspace", "directory is outside workspace root");
26889
26892
  }
26890
26893
  let current = root;
@@ -26907,7 +26910,7 @@ async function mkdirPathComponentsWithGuards(params) {
26907
26910
  }
26908
26911
  // Node's recursive mkdir follows symlinks in missing components. Build one
26909
26912
  // segment at a time and realpath-check each segment before descending.
26910
- if (!isSameOrChildPath(external_node_path_.resolve(await promises_.realpath(next)), root)) {
26913
+ if (!isSameOrChildPath(external_node_path_.resolve(await promises_.realpath(next)), rootCanonical)) {
26911
26914
  throw new errors_FsSafeError("outside-workspace", "directory escaped workspace root");
26912
26915
  }
26913
26916
  await directory_guard_createAsyncDirectoryGuard(next);
@@ -26994,6 +26997,191 @@ function guardedRmSync(params) {
26994
26997
  }), { verifyAfter: params.verifyAfter });
26995
26998
  }
26996
26999
 
27000
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/deny-mutations.js
27001
+
27002
+
27003
+
27004
+
27005
+ async function pathExists(filePath) {
27006
+ try {
27007
+ await promises_.lstat(filePath);
27008
+ return true;
27009
+ }
27010
+ catch (err) {
27011
+ if (!path_isNotFoundPathError(err)) {
27012
+ throw err;
27013
+ }
27014
+ return false;
27015
+ }
27016
+ }
27017
+ async function resolvePathViaExistingAncestor(targetPath) {
27018
+ const normalized = external_node_path_.resolve(targetPath);
27019
+ let cursor = normalized;
27020
+ const missingSuffix = [];
27021
+ while (external_node_path_.dirname(cursor) !== cursor && !(await pathExists(cursor))) {
27022
+ missingSuffix.unshift(external_node_path_.basename(cursor));
27023
+ cursor = external_node_path_.dirname(cursor);
27024
+ }
27025
+ if (!(await pathExists(cursor))) {
27026
+ return normalized;
27027
+ }
27028
+ try {
27029
+ const resolvedAncestor = external_node_path_.resolve(await promises_.realpath(cursor));
27030
+ return missingSuffix.length === 0
27031
+ ? resolvedAncestor
27032
+ : external_node_path_.resolve(resolvedAncestor, ...missingSuffix);
27033
+ }
27034
+ catch {
27035
+ return normalized;
27036
+ }
27037
+ }
27038
+ async function comparablePaths(rawPath) {
27039
+ path_assertNoNulPathInput(rawPath, "path contains a NUL byte");
27040
+ const resolved = external_node_path_.resolve(rawPath);
27041
+ return new Set([resolved, await resolvePathViaExistingAncestor(resolved)]);
27042
+ }
27043
+ function isSamePath(left, right) {
27044
+ return path_isPathInside(left, right) && path_isPathInside(right, left);
27045
+ }
27046
+ function hasPolicyEntries(policy) {
27047
+ return Boolean(policy?.paths?.length || policy?.prefixes?.length);
27048
+ }
27049
+ function policyPathEntries(entries) {
27050
+ const paths = [];
27051
+ for (const entry of entries ?? []) {
27052
+ if (entry.length === 0) {
27053
+ throw new errors_FsSafeError("invalid-path", "deny mutation paths must be non-empty");
27054
+ }
27055
+ path_assertNoNulPathInput(entry, "deny mutation path contains a NUL byte");
27056
+ if (!external_node_path_.isAbsolute(entry)) {
27057
+ throw new errors_FsSafeError("invalid-path", "deny mutation paths must be absolute");
27058
+ }
27059
+ paths.push(entry);
27060
+ }
27061
+ return paths;
27062
+ }
27063
+ async function assertMutationNotDenied(filePath, policy, options = {}) {
27064
+ if (!hasPolicyEntries(policy)) {
27065
+ return;
27066
+ }
27067
+ const targetPaths = await comparablePaths(filePath);
27068
+ for (const deniedPath of policyPathEntries(policy.paths)) {
27069
+ const deniedPaths = await comparablePaths(deniedPath);
27070
+ for (const target of targetPaths) {
27071
+ for (const denied of deniedPaths) {
27072
+ if (isSamePath(denied, target) ||
27073
+ (options.protectAncestors === true && path_isPathInside(target, denied))) {
27074
+ throw new errors_FsSafeError("denied-path", "path is denied by denyMutations policy");
27075
+ }
27076
+ }
27077
+ }
27078
+ }
27079
+ for (const deniedPrefix of policyPathEntries(policy.prefixes)) {
27080
+ const deniedPaths = await comparablePaths(deniedPrefix);
27081
+ for (const target of targetPaths) {
27082
+ for (const denied of deniedPaths) {
27083
+ if (path_isPathInside(denied, target) ||
27084
+ (options.protectAncestors === true && path_isPathInside(target, denied))) {
27085
+ throw new errors_FsSafeError("denied-path", "path is denied by denyMutations policy");
27086
+ }
27087
+ }
27088
+ }
27089
+ }
27090
+ }
27091
+ function mergeDenyMutationPolicies(defaultPolicy, callPolicy) {
27092
+ if (!defaultPolicy) {
27093
+ return callPolicy;
27094
+ }
27095
+ if (!callPolicy) {
27096
+ return defaultPolicy;
27097
+ }
27098
+ return {
27099
+ paths: [...(defaultPolicy.paths ?? []), ...(callPolicy.paths ?? [])],
27100
+ prefixes: [...(defaultPolicy.prefixes ?? []), ...(callPolicy.prefixes ?? [])],
27101
+ };
27102
+ }
27103
+
27104
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/opened-realpath.js
27105
+
27106
+
27107
+
27108
+
27109
+
27110
+ async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
27111
+ const handleStat = await handle.stat();
27112
+ const fdCandidates = process.platform === "linux"
27113
+ ? [`/proc/self/fd/${handle.fd}`, `/dev/fd/${handle.fd}`]
27114
+ : process.platform === "win32"
27115
+ ? []
27116
+ : [`/dev/fd/${handle.fd}`];
27117
+ for (const fdPath of fdCandidates) {
27118
+ try {
27119
+ const fdRealPath = await promises_.realpath(fdPath);
27120
+ const fdRealStat = await promises_.stat(fdRealPath);
27121
+ if (file_identity_sameFileIdentity(handleStat, fdRealStat)) {
27122
+ return fdRealPath;
27123
+ }
27124
+ }
27125
+ catch {
27126
+ // try next fd path
27127
+ }
27128
+ }
27129
+ try {
27130
+ const ioRealPath = await promises_.realpath(ioPath);
27131
+ const ioRealStat = await promises_.stat(ioRealPath);
27132
+ if (file_identity_sameFileIdentity(handleStat, ioRealStat)) {
27133
+ return ioRealPath;
27134
+ }
27135
+ }
27136
+ catch (err) {
27137
+ if (!path_isNotFoundPathError(err)) {
27138
+ throw err;
27139
+ }
27140
+ }
27141
+ const parentResolved = await resolveOpenedFileRealPathFromParent(handleStat, ioPath);
27142
+ if (parentResolved) {
27143
+ return parentResolved;
27144
+ }
27145
+ throw new errors_FsSafeError("path-mismatch", "unable to resolve opened file path");
27146
+ }
27147
+ async function resolveOpenedFileRealPathFromParent(handleStat, ioPath) {
27148
+ let parentReal;
27149
+ try {
27150
+ parentReal = await promises_.realpath(external_node_path_.dirname(ioPath));
27151
+ }
27152
+ catch (err) {
27153
+ if (path_isNotFoundPathError(err)) {
27154
+ return null;
27155
+ }
27156
+ throw err;
27157
+ }
27158
+ let entries;
27159
+ try {
27160
+ entries = await promises_.readdir(parentReal);
27161
+ }
27162
+ catch (err) {
27163
+ if (path_isNotFoundPathError(err)) {
27164
+ return null;
27165
+ }
27166
+ throw err;
27167
+ }
27168
+ for (const entry of entries.toSorted()) {
27169
+ const candidatePath = external_node_path_.join(parentReal, entry);
27170
+ try {
27171
+ const candidateStat = await promises_.lstat(candidatePath);
27172
+ if (candidateStat.isFile() && file_identity_sameFileIdentity(handleStat, candidateStat)) {
27173
+ return await promises_.realpath(candidatePath);
27174
+ }
27175
+ }
27176
+ catch (err) {
27177
+ if (!path_isNotFoundPathError(err)) {
27178
+ throw err;
27179
+ }
27180
+ }
27181
+ }
27182
+ return null;
27183
+ }
27184
+
26997
27185
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/pinned-python-config.js
26998
27186
  let overrideConfig = {};
26999
27187
  function parseMode(value) {
@@ -27042,26 +27230,20 @@ var external_node_child_process_ = __webpack_require__(1421);
27042
27230
 
27043
27231
 
27044
27232
  const PINNED_PYTHON_WORKER_SOURCE = String.raw `
27045
- import base64
27046
- import errno
27047
- import json
27048
- import os
27049
- import secrets
27050
- import stat
27051
- import sys
27052
-
27233
+ import base64, errno, json, os, secrets, stat, sys
27053
27234
  DIR_FLAGS = os.O_RDONLY
27054
27235
  if hasattr(os, "O_DIRECTORY"):
27055
27236
  DIR_FLAGS |= os.O_DIRECTORY
27056
27237
  if hasattr(os, "O_NOFOLLOW"):
27057
27238
  DIR_FLAGS |= os.O_NOFOLLOW
27058
27239
  READ_FLAGS = os.O_RDONLY
27240
+ if hasattr(os, "O_NONBLOCK"):
27241
+ READ_FLAGS |= os.O_NONBLOCK
27059
27242
  if hasattr(os, "O_NOFOLLOW"):
27060
27243
  READ_FLAGS |= os.O_NOFOLLOW
27061
27244
  WRITE_FLAGS = os.O_WRONLY | os.O_CREAT | os.O_EXCL
27062
27245
  if hasattr(os, "O_NOFOLLOW"):
27063
27246
  WRITE_FLAGS |= os.O_NOFOLLOW
27064
-
27065
27247
  def split_relative(value):
27066
27248
  if value in ("", "."):
27067
27249
  return []
@@ -27074,10 +27256,8 @@ def split_relative(value):
27074
27256
  if part == "..":
27075
27257
  raise OSError(errno.EPERM, "path traversal is not allowed")
27076
27258
  return parts
27077
-
27078
27259
  def open_dir(path_value, dir_fd=None):
27079
27260
  return os.open(path_value, DIR_FLAGS, dir_fd=dir_fd)
27080
-
27081
27261
  def walk_dir(root_fd, segments, mkdir_enabled=False):
27082
27262
  current_fd = os.dup(root_fd)
27083
27263
  try:
@@ -27095,14 +27275,12 @@ def walk_dir(root_fd, segments, mkdir_enabled=False):
27095
27275
  except Exception:
27096
27276
  os.close(current_fd)
27097
27277
  raise
27098
-
27099
27278
  def parent_and_basename(root_fd, relative):
27100
27279
  segments = split_relative(relative)
27101
27280
  if not segments:
27102
27281
  raise OSError(errno.EPERM, "operation requires a non-root path")
27103
27282
  parent_fd = walk_dir(root_fd, segments[:-1])
27104
27283
  return parent_fd, segments[-1]
27105
-
27106
27284
  def encode_stat(st):
27107
27285
  mode = st.st_mode
27108
27286
  return {
@@ -27118,14 +27296,12 @@ def encode_stat(st):
27118
27296
  "size": st.st_size,
27119
27297
  "uid": st.st_uid,
27120
27298
  }
27121
-
27122
27299
  def reject_unsafe_endpoint(st):
27123
27300
  mode = st.st_mode
27124
27301
  if stat.S_ISLNK(mode):
27125
27302
  raise OSError(errno.ELOOP, "symlink endpoint is not allowed")
27126
27303
  if stat.S_ISREG(mode) and st.st_nlink > 1:
27127
27304
  raise OSError(errno.EPERM, "hardlinked file endpoint is not allowed")
27128
-
27129
27305
  def copy_bytes(source_fd, dest_fd):
27130
27306
  while True:
27131
27307
  chunk = os.read(source_fd, 65536)
@@ -27137,7 +27313,6 @@ def copy_bytes(source_fd, dest_fd):
27137
27313
  if written <= 0:
27138
27314
  raise OSError(errno.EIO, "short write")
27139
27315
  view = view[written:]
27140
-
27141
27316
  def write_all(fd, data):
27142
27317
  view = memoryview(data)
27143
27318
  while view:
@@ -27145,11 +27320,9 @@ def write_all(fd, data):
27145
27320
  if written <= 0:
27146
27321
  raise OSError(errno.EIO, "short write")
27147
27322
  view = view[written:]
27148
-
27149
27323
  def link_unsupported(exc):
27150
27324
  unsupported = (errno.EPERM, errno.EOPNOTSUPP, getattr(errno, "ENOTSUP", errno.EOPNOTSUPP))
27151
27325
  return getattr(exc, "errno", None) in unsupported
27152
-
27153
27326
  def link_no_replace(name, new_name, source_fd, target_fd):
27154
27327
  linked = False
27155
27328
  try:
@@ -27164,11 +27337,9 @@ def link_no_replace(name, new_name, source_fd, target_fd):
27164
27337
  os.fsync(source_fd)
27165
27338
  if source_fd != target_fd:
27166
27339
  os.fsync(target_fd)
27167
-
27168
27340
  def copy_file_no_replace(source_parent_fd, source_name, target_parent_fd, basename, mode, expected=None, unlink_source=False):
27169
27341
  source_fd = os.open(source_name, READ_FLAGS, dir_fd=source_parent_fd)
27170
- dest_fd = None
27171
- success = False
27342
+ dest_fd = None; success = False; dest_stat = None
27172
27343
  try:
27173
27344
  if expected is not None:
27174
27345
  source_stat = os.fstat(source_fd)
@@ -27177,6 +27348,7 @@ def copy_file_no_replace(source_parent_fd, source_name, target_parent_fd, basena
27177
27348
  dest_fd = os.open(basename, WRITE_FLAGS, mode, dir_fd=target_parent_fd)
27178
27349
  copy_bytes(source_fd, dest_fd)
27179
27350
  os.fsync(dest_fd)
27351
+ dest_stat = os.fstat(dest_fd)
27180
27352
  success = True
27181
27353
  finally:
27182
27354
  os.close(source_fd)
@@ -27192,19 +27364,40 @@ def copy_file_no_replace(source_parent_fd, source_name, target_parent_fd, basena
27192
27364
  try: os.unlink(basename, dir_fd=target_parent_fd)
27193
27365
  except FileNotFoundError: pass
27194
27366
  raise
27195
-
27196
- def commit_temp_file(parent_fd, temp_name, basename, overwrite, mode):
27367
+ return dest_stat
27368
+ def same_identity(left, right):
27369
+ return left.st_dev == right.st_dev and left.st_ino == right.st_ino
27370
+ def verify_temp_name(parent_fd, temp_name, expected_stat):
27371
+ current_stat = os.lstat(temp_name, dir_fd=parent_fd)
27372
+ if stat.S_ISLNK(current_stat.st_mode) or not same_identity(current_stat, expected_stat):
27373
+ raise RuntimeError("fs-safe-temp-mismatch")
27374
+ def verify_committed_temp(parent_fd, basename, expected_stat):
27375
+ final_stat = os.lstat(basename, dir_fd=parent_fd)
27376
+ if not stat.S_ISLNK(final_stat.st_mode) and same_identity(final_stat, expected_stat):
27377
+ return final_stat
27378
+ try: os.unlink(basename, dir_fd=parent_fd)
27379
+ except FileNotFoundError: pass
27380
+ raise RuntimeError("fs-safe-temp-mismatch")
27381
+ def commit_temp_file(parent_fd, temp_name, basename, overwrite, mode, expected_stat):
27382
+ verify_temp_name(parent_fd, temp_name, expected_stat)
27197
27383
  if overwrite:
27198
27384
  os.replace(temp_name, basename, src_dir_fd=parent_fd, dst_dir_fd=parent_fd)
27385
+ return verify_committed_temp(parent_fd, basename, expected_stat)
27199
27386
  else:
27200
27387
  try:
27201
27388
  os.link(temp_name, basename, src_dir_fd=parent_fd, dst_dir_fd=parent_fd, follow_symlinks=False)
27389
+ final_stat = verify_committed_temp(parent_fd, basename, expected_stat)
27202
27390
  os.unlink(temp_name, dir_fd=parent_fd)
27391
+ return final_stat
27203
27392
  except OSError as exc:
27204
27393
  if not link_unsupported(exc):
27205
27394
  raise
27206
- copy_file_no_replace(parent_fd, temp_name, parent_fd, basename, mode, unlink_source=True)
27207
-
27395
+ return copy_file_no_replace(parent_fd, temp_name, parent_fd, basename, mode, expected_stat, True)
27396
+ def assert_expected_root(root_fd, payload):
27397
+ if "rootDev" in payload or "rootIno" in payload:
27398
+ root_stat = os.fstat(root_fd)
27399
+ if root_stat.st_dev != int(payload["rootDev"]) or root_stat.st_ino != int(payload["rootIno"]):
27400
+ raise RuntimeError("fs-safe-root-mismatch")
27208
27401
  def stat_path(root_fd, payload):
27209
27402
  relative = payload.get("relativePath", "")
27210
27403
  segments = split_relative(relative)
@@ -27218,7 +27411,6 @@ def stat_path(root_fd, payload):
27218
27411
  return encode_stat(st)
27219
27412
  finally:
27220
27413
  os.close(parent_fd)
27221
-
27222
27414
  def readdir_path(root_fd, payload):
27223
27415
  dir_fd = walk_dir(root_fd, split_relative(payload.get("relativePath", "")))
27224
27416
  try:
@@ -27234,12 +27426,9 @@ def readdir_path(root_fd, payload):
27234
27426
  return entries
27235
27427
  finally:
27236
27428
  os.close(dir_fd)
27237
-
27238
27429
  def mkdirp_path(root_fd, payload):
27239
27430
  dir_fd = walk_dir(root_fd, split_relative(payload.get("relativePath", "")), mkdir_enabled=True)
27240
- os.close(dir_fd)
27241
- return None
27242
-
27431
+ os.close(dir_fd); return None
27243
27432
  def remove_tree(parent_fd, basename):
27244
27433
  st = os.lstat(basename, dir_fd=parent_fd)
27245
27434
  if stat.S_ISDIR(st.st_mode) and not stat.S_ISLNK(st.st_mode):
@@ -27252,7 +27441,6 @@ def remove_tree(parent_fd, basename):
27252
27441
  os.rmdir(basename, dir_fd=parent_fd)
27253
27442
  else:
27254
27443
  os.unlink(basename, dir_fd=parent_fd)
27255
-
27256
27444
  def remove_path(root_fd, payload):
27257
27445
  parent_fd, basename = parent_and_basename(root_fd, payload.get("relativePath", ""))
27258
27446
  try:
@@ -27335,14 +27523,15 @@ def write_path(root_fd, payload):
27335
27523
  except FileNotFoundError:
27336
27524
  pass
27337
27525
  temp_name, temp_fd = create_temp_file(parent_fd, basename, mode)
27526
+ os.fchmod(temp_fd, mode)
27338
27527
  write_all(temp_fd, data)
27339
27528
  os.fsync(temp_fd)
27529
+ temp_stat = os.fstat(temp_fd)
27340
27530
  os.close(temp_fd)
27341
27531
  temp_fd = None
27342
- commit_temp_file(parent_fd, temp_name, basename, overwrite, mode)
27532
+ result_stat = commit_temp_file(parent_fd, temp_name, basename, overwrite, mode, temp_stat)
27343
27533
  temp_name = None
27344
27534
  os.fsync(parent_fd)
27345
- result_stat = os.stat(basename, dir_fd=parent_fd, follow_symlinks=False)
27346
27535
  return {"dev": result_stat.st_dev, "ino": result_stat.st_ino}
27347
27536
  finally:
27348
27537
  if temp_fd is not None:
@@ -27373,6 +27562,7 @@ def copy_path(root_fd, payload):
27373
27562
  raise RuntimeError("fs-safe-too-large:%d:%d" % (max_bytes, source_stat.st_size))
27374
27563
  parent_fd = walk_dir(root_fd, split_relative(payload.get("relativeParentPath", "")), bool(payload.get("mkdir", True)))
27375
27564
  temp_name, temp_fd = create_temp_file(parent_fd, basename, mode)
27565
+ os.fchmod(temp_fd, mode)
27376
27566
  written_bytes = 0
27377
27567
  while True:
27378
27568
  chunk = os.read(source_fd, 65536)
@@ -27388,12 +27578,12 @@ def copy_path(root_fd, payload):
27388
27578
  raise OSError(errno.EIO, "short write")
27389
27579
  view = view[written:]
27390
27580
  os.fsync(temp_fd)
27581
+ temp_stat = os.fstat(temp_fd)
27391
27582
  os.close(temp_fd)
27392
27583
  temp_fd = None
27393
- commit_temp_file(parent_fd, temp_name, basename, overwrite, mode)
27584
+ result_stat = commit_temp_file(parent_fd, temp_name, basename, overwrite, mode, temp_stat)
27394
27585
  temp_name = None
27395
27586
  os.fsync(parent_fd)
27396
- result_stat = os.stat(basename, dir_fd=parent_fd, follow_symlinks=False)
27397
27587
  return {"dev": result_stat.st_dev, "ino": result_stat.st_ino}
27398
27588
  finally:
27399
27589
  os.close(source_fd)
@@ -27410,6 +27600,7 @@ def copy_path(root_fd, payload):
27410
27600
  def run_operation(operation, root_path, payload):
27411
27601
  root_fd = open_dir(root_path)
27412
27602
  try:
27603
+ assert_expected_root(root_fd, payload)
27413
27604
  if operation == "stat":
27414
27605
  return stat_path(root_fd, payload)
27415
27606
  if operation == "readdir":
@@ -27514,6 +27705,12 @@ function mapWorkerError(response) {
27514
27705
  if (message.includes("fs-safe-source-mismatch")) {
27515
27706
  return new errors_FsSafeError("path-mismatch", "source path changed during copy");
27516
27707
  }
27708
+ if (message.includes("fs-safe-temp-mismatch")) {
27709
+ return new errors_FsSafeError("path-mismatch", "temp path changed during write");
27710
+ }
27711
+ if (message.includes("fs-safe-root-mismatch")) {
27712
+ return new errors_FsSafeError("path-mismatch", "root path changed during operation");
27713
+ }
27517
27714
  if (message.includes("fs-safe-directory-noreplace-unsupported")) {
27518
27715
  return new errors_FsSafeError("invalid-path", "directory moves require overwrite: true");
27519
27716
  }
@@ -27694,9 +27891,7 @@ function validatePinnedOperationPayload(payload) {
27694
27891
  }
27695
27892
  }
27696
27893
  function isPinnedHelperUnavailable(error) {
27697
- return error instanceof Error &&
27698
- "code" in error &&
27699
- error.code === "helper-unavailable";
27894
+ return error instanceof Error && "code" in error && error.code === "helper-unavailable";
27700
27895
  }
27701
27896
  function validatePinnedRelativePath(relativePath) {
27702
27897
  if (relativePath.length === 0 || relativePath === ".") {
@@ -27794,29 +27989,21 @@ function assertWithinMaxBytes(bytes, maxBytes) {
27794
27989
  throw new errors_FsSafeError("too-large", `file exceeds limit of ${maxBytes} bytes (got at least ${bytes})`);
27795
27990
  }
27796
27991
  }
27797
- function pinned_write_createMaxBytesTransform(maxBytes) {
27798
- if (maxBytes === undefined) {
27799
- return undefined;
27800
- }
27992
+ async function writeStreamToHandle(stream, handle, maxBytes) {
27801
27993
  let bytes = 0;
27802
- return new external_node_stream_.Transform({
27803
- transform(chunk, _encoding, callback) {
27804
- bytes += chunk.byteLength;
27805
- if (bytes > maxBytes) {
27806
- callback(new errors_FsSafeError("too-large", `file exceeds limit of ${maxBytes} bytes (got at least ${bytes})`));
27807
- return;
27994
+ for await (const chunk of stream) {
27995
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
27996
+ bytes += buffer.byteLength;
27997
+ assertWithinMaxBytes(bytes, maxBytes);
27998
+ let offset = 0;
27999
+ while (offset < buffer.byteLength) {
28000
+ const { bytesWritten } = await handle.write(buffer, offset, buffer.byteLength - offset);
28001
+ if (bytesWritten <= 0) {
28002
+ throw new errors_FsSafeError("helper-failed", "fallback stream write made no progress");
27808
28003
  }
27809
- callback(null, chunk);
27810
- },
27811
- });
27812
- }
27813
- async function pipelineWithMaxBytes(stream, destination, maxBytes) {
27814
- const limiter = pinned_write_createMaxBytesTransform(maxBytes);
27815
- if (limiter) {
27816
- await (0,external_node_stream_promises_.pipeline)(stream, limiter, destination);
27817
- return;
28004
+ offset += bytesWritten;
28005
+ }
27818
28006
  }
27819
- await (0,external_node_stream_promises_.pipeline)(stream, destination);
27820
28007
  }
27821
28008
  async function inputToBase64(input, maxBytes) {
27822
28009
  if (input.kind === "buffer") {
@@ -27862,6 +28049,7 @@ async function runPinnedWriteHelper(params) {
27862
28049
  mode: params.mode || 0o600,
27863
28050
  overwrite: params.overwrite !== false,
27864
28051
  relativeParentPath: params.relativeParentPath,
28052
+ ...(params.rootIdentity ? { rootDev: params.rootIdentity.dev, rootIno: params.rootIdentity.ino } : {}),
27865
28053
  };
27866
28054
  try {
27867
28055
  return await runPinnedPythonOperation({
@@ -27892,6 +28080,7 @@ async function runPinnedCopyHelper(params) {
27892
28080
  mode: params.mode || 0o600,
27893
28081
  overwrite: params.overwrite !== false,
27894
28082
  relativeParentPath: params.relativeParentPath,
28083
+ ...(params.rootIdentity ? { rootDev: params.rootIdentity.dev, rootIno: params.rootIdentity.ino } : {}),
27895
28084
  sourceDev: params.sourceIdentity.dev,
27896
28085
  sourceIno: params.sourceIdentity.ino,
27897
28086
  sourcePath: params.sourcePath,
@@ -27902,12 +28091,12 @@ async function runPinnedWriteFallback(params) {
27902
28091
  const parentPath = params.relativeParentPath
27903
28092
  ? external_node_path_.join(params.rootPath, ...params.relativeParentPath.split("/"))
27904
28093
  : params.rootPath;
27905
- const parentGuard = await directory_guard_createNearestExistingDirectoryGuard(params.rootPath, parentPath);
27906
28094
  if (params.mkdir) {
27907
- await withAsyncDirectoryGuards([parentGuard], async () => {
27908
- await promises_.mkdir(parentPath, { recursive: true });
27909
- });
28095
+ await mkdirPathComponentsWithGuards({ rootReal: params.rootPath, targetPath: parentPath });
27910
28096
  }
28097
+ const parentGuard = params.mkdir
28098
+ ? await directory_guard_createAsyncDirectoryGuard(parentPath)
28099
+ : await directory_guard_createNearestExistingDirectoryGuard(params.rootPath, parentPath);
27911
28100
  const targetPath = external_node_path_.join(parentPath, params.basename);
27912
28101
  if (params.overwrite === false) {
27913
28102
  let 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), {
@@ -27929,7 +28118,7 @@ async function runPinnedWriteFallback(params) {
27929
28118
  }
27930
28119
  }
27931
28120
  else {
27932
- await pipelineWithMaxBytes(params.input.stream, handle.createWriteStream(), params.maxBytes);
28121
+ await writeStreamToHandle(params.input.stream, handle, params.maxBytes);
27933
28122
  }
27934
28123
  const stat = await handle.stat();
27935
28124
  created = false;
@@ -27950,7 +28139,9 @@ async function runPinnedWriteFallback(params) {
27950
28139
  ? external_node_fs_.constants.O_NOFOLLOW
27951
28140
  : 0);
27952
28141
  let handle;
27953
- let handleClosedByStream = false;
28142
+ let tempStat;
28143
+ let targetStat;
28144
+ let renamed = false;
27954
28145
  try {
27955
28146
  handle = await promises_.open(tempPath, tempFlags, params.mode);
27956
28147
  if (params.input.kind === "buffer") {
@@ -27963,29 +28154,36 @@ async function runPinnedWriteFallback(params) {
27963
28154
  }
27964
28155
  }
27965
28156
  else {
27966
- const writable = handle.createWriteStream();
27967
- writable.once("close", () => {
27968
- handleClosedByStream = true;
27969
- });
27970
- await pipelineWithMaxBytes(params.input.stream, writable, params.maxBytes);
28157
+ await writeStreamToHandle(params.input.stream, handle, params.maxBytes);
27971
28158
  }
27972
- if (!handleClosedByStream) {
27973
- await handle.close().catch(() => undefined);
27974
- handle = undefined;
28159
+ tempStat = await handle.stat();
28160
+ const tempPathStat = await promises_.lstat(tempPath);
28161
+ if (tempPathStat.isSymbolicLink() || !file_identity_sameFileIdentity(tempPathStat, tempStat)) {
28162
+ throw new errors_FsSafeError("path-mismatch", "fallback temp path changed during write");
27975
28163
  }
28164
+ const expectedTempStat = tempStat;
28165
+ await handle.close().catch(() => undefined);
28166
+ handle = undefined;
27976
28167
  await withAsyncDirectoryGuards([parentGuard], async () => {
27977
28168
  await promises_.rename(tempPath, targetPath);
28169
+ renamed = true;
28170
+ targetStat = await promises_.lstat(targetPath);
28171
+ if (targetStat.isSymbolicLink() || !file_identity_sameFileIdentity(targetStat, expectedTempStat)) {
28172
+ throw new errors_FsSafeError("path-mismatch", "fallback target changed during write");
28173
+ }
27978
28174
  });
27979
28175
  }
27980
28176
  catch (error) {
27981
- if (handle && !handleClosedByStream) {
27982
- await handle.close().catch(() => undefined);
28177
+ await handle?.close().catch(() => undefined);
28178
+ if (!renamed) {
28179
+ await promises_.rm(tempPath, { force: true }).catch(() => undefined);
27983
28180
  }
27984
- await promises_.rm(tempPath, { force: true }).catch(() => undefined);
27985
28181
  throw error;
27986
28182
  }
27987
- const stat = await promises_.stat(targetPath);
27988
- return { dev: stat.dev, ino: stat.ino };
28183
+ if (!targetStat) {
28184
+ throw new errors_FsSafeError("path-mismatch", "fallback target was not verified");
28185
+ }
28186
+ return { dev: targetStat.dev, ino: targetStat.ino };
27989
28187
  }
27990
28188
 
27991
28189
  // EXTERNAL MODULE: external "node:os"
@@ -28011,7 +28209,7 @@ async function resolveRootPath(params) {
28011
28209
  const absolutePath = external_node_path_.resolve(params.absolutePath);
28012
28210
  const rootCanonicalPath = params.rootCanonicalPath
28013
28211
  ? external_node_path_.resolve(params.rootCanonicalPath)
28014
- : await resolvePathViaExistingAncestor(rootPath);
28212
+ : await root_path_resolvePathViaExistingAncestor(rootPath);
28015
28213
  const context = createBoundaryResolutionContext({
28016
28214
  resolveParams: params,
28017
28215
  rootPath,
@@ -28380,7 +28578,7 @@ async function resolveOutsideLexicalCanonicalPathAsync(params) {
28380
28578
  if (path_isPathInside(params.rootPath, params.absolutePath)) {
28381
28579
  return undefined;
28382
28580
  }
28383
- return await resolvePathViaExistingAncestor(params.absolutePath);
28581
+ return await root_path_resolvePathViaExistingAncestor(params.absolutePath);
28384
28582
  }
28385
28583
  function resolveOutsideLexicalCanonicalPathSync(params) {
28386
28584
  if (isPathInside(params.rootPath, params.absolutePath)) {
@@ -28427,11 +28625,11 @@ function buildResolvedRootPath(params) {
28427
28625
  kind: params.kind.kind,
28428
28626
  };
28429
28627
  }
28430
- async function resolvePathViaExistingAncestor(targetPath) {
28628
+ async function root_path_resolvePathViaExistingAncestor(targetPath) {
28431
28629
  const normalized = external_node_path_.resolve(targetPath);
28432
28630
  let cursor = normalized;
28433
28631
  const missingSuffix = [];
28434
- while (!isFilesystemRoot(cursor) && !(await pathExists(cursor))) {
28632
+ while (!isFilesystemRoot(cursor) && !(await root_path_pathExists(cursor))) {
28435
28633
  missingSuffix.unshift(external_node_path_.basename(cursor));
28436
28634
  const parent = external_node_path_.dirname(cursor);
28437
28635
  if (parent === cursor) {
@@ -28439,7 +28637,7 @@ async function resolvePathViaExistingAncestor(targetPath) {
28439
28637
  }
28440
28638
  cursor = parent;
28441
28639
  }
28442
- if (!(await pathExists(cursor))) {
28640
+ if (!(await root_path_pathExists(cursor))) {
28443
28641
  return normalized;
28444
28642
  }
28445
28643
  try {
@@ -28524,7 +28722,7 @@ function relativeInsideRoot(rootPath, targetPath) {
28524
28722
  if (!relative || relative === ".") {
28525
28723
  return "";
28526
28724
  }
28527
- if (relative.startsWith("..") || external_node_path_.isAbsolute(relative)) {
28725
+ if (isPathRelativeEscape(relative)) {
28528
28726
  return "";
28529
28727
  }
28530
28728
  return relative;
@@ -28551,7 +28749,7 @@ function shortPath(value) {
28551
28749
  function isFilesystemRoot(candidate) {
28552
28750
  return external_node_path_.parse(candidate).root === candidate;
28553
28751
  }
28554
- async function pathExists(targetPath) {
28752
+ async function root_path_pathExists(targetPath) {
28555
28753
  try {
28556
28754
  await promises_.lstat(targetPath);
28557
28755
  return true;
@@ -28573,7 +28771,7 @@ async function resolveSymlinkHopPath(symlinkPath) {
28573
28771
  }
28574
28772
  const linkTarget = await promises_.readlink(symlinkPath);
28575
28773
  const linkAbsolute = external_node_path_.resolve(external_node_path_.dirname(symlinkPath), linkTarget);
28576
- return resolvePathViaExistingAncestor(linkAbsolute);
28774
+ return root_path_resolvePathViaExistingAncestor(linkAbsolute);
28577
28775
  }
28578
28776
  }
28579
28777
  function resolveSymlinkHopPathSync(symlinkPath) {
@@ -28642,6 +28840,23 @@ function path_policy_shortPath(value) {
28642
28840
  return value;
28643
28841
  }
28644
28842
 
28843
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/read-opened-file.js
28844
+
28845
+ async function read_opened_file_readOpenedFileSafely(params) {
28846
+ if (params.maxBytes !== undefined && params.opened.stat.size > params.maxBytes) {
28847
+ throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${params.opened.stat.size})`);
28848
+ }
28849
+ const buffer = await params.opened.handle.readFile();
28850
+ if (params.maxBytes !== undefined && buffer.byteLength > params.maxBytes) {
28851
+ throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${buffer.byteLength})`);
28852
+ }
28853
+ return {
28854
+ buffer,
28855
+ realPath: params.opened.realPath,
28856
+ stat: params.opened.stat,
28857
+ };
28858
+ }
28859
+
28645
28860
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/path-stat.js
28646
28861
  function pathStatFromStats(stat) {
28647
28862
  return {
@@ -28969,6 +29184,10 @@ async function serializePathWrite(key, run) {
28969
29184
 
28970
29185
 
28971
29186
 
29187
+
29188
+
29189
+
29190
+
28972
29191
 
28973
29192
 
28974
29193
 
@@ -29167,6 +29386,7 @@ class RootHandle {
29167
29386
  mkdir: this.defaults.mkdir,
29168
29387
  mode: this.defaults.mode,
29169
29388
  ...options,
29389
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
29170
29390
  append: writeMode === "append",
29171
29391
  truncateExisting: writeMode === "replace",
29172
29392
  });
@@ -29178,18 +29398,29 @@ class RootHandle {
29178
29398
  mkdir: this.defaults.mkdir,
29179
29399
  mode: this.defaults.mode,
29180
29400
  ...options,
29401
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
29181
29402
  });
29182
29403
  }
29183
- async remove(relativePath) {
29404
+ async remove(relativePath, options = {}) {
29184
29405
  assertValidRootRelativePath(relativePath);
29185
- await removePathInRoot(this.context, relativePath);
29406
+ await removePathInRoot(this.context, {
29407
+ relativePath,
29408
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
29409
+ });
29186
29410
  }
29187
- async mkdir(relativePath) {
29411
+ async mkdir(relativePath, options = {}) {
29188
29412
  assertValidRootRelativePath(relativePath);
29189
- await mkdirPathInRoot(this.context, { relativePath });
29413
+ await mkdirPathInRoot(this.context, {
29414
+ relativePath,
29415
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
29416
+ });
29190
29417
  }
29191
- async ensureRoot() {
29192
- await mkdirPathInRoot(this.context, { relativePath: "", allowRoot: true });
29418
+ async ensureRoot(options = {}) {
29419
+ await mkdirPathInRoot(this.context, {
29420
+ relativePath: "",
29421
+ allowRoot: true,
29422
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
29423
+ });
29193
29424
  }
29194
29425
  async write(relativePath, data, options = {}) {
29195
29426
  await writeFileInRoot(this.context, {
@@ -29198,6 +29429,7 @@ class RootHandle {
29198
29429
  mkdir: this.defaults.mkdir,
29199
29430
  mode: this.defaults.mode,
29200
29431
  ...options,
29432
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
29201
29433
  });
29202
29434
  }
29203
29435
  async create(relativePath, data, options = {}) {
@@ -29207,6 +29439,7 @@ class RootHandle {
29207
29439
  mkdir: this.defaults.mkdir,
29208
29440
  mode: this.defaults.mode,
29209
29441
  ...options,
29442
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
29210
29443
  overwrite: false,
29211
29444
  });
29212
29445
  }
@@ -29229,6 +29462,7 @@ class RootHandle {
29229
29462
  mkdir: this.defaults.mkdir,
29230
29463
  mode: this.defaults.mode,
29231
29464
  ...options,
29465
+ denyMutations: mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations),
29232
29466
  });
29233
29467
  }
29234
29468
  async exists(relativePath) {
@@ -29272,6 +29506,12 @@ class RootHandle {
29272
29506
  async move(fromRelative, toRelative, options = {}) {
29273
29507
  assertValidRootRelativePath(fromRelative);
29274
29508
  assertValidRootRelativePath(toRelative);
29509
+ const denyMutations = mergeDenyMutationPolicies(this.defaults.denyMutations, options.denyMutations);
29510
+ await assertMoveMutationAllowed(this.context, {
29511
+ fromRelative,
29512
+ toRelative,
29513
+ denyMutations,
29514
+ });
29275
29515
  try {
29276
29516
  await runPinnedHelper("rename", this.rootReal, {
29277
29517
  from: fromRelative,
@@ -29283,6 +29523,7 @@ class RootHandle {
29283
29523
  if (canFallbackFromPythonError(error)) {
29284
29524
  await movePathFallback(this.context, {
29285
29525
  fromRelative,
29526
+ denyMutations,
29286
29527
  overwrite: options.overwrite ?? false,
29287
29528
  toRelative,
29288
29529
  });
@@ -29331,7 +29572,7 @@ async function openFileInRoot(root, params) {
29331
29572
  async function readFileInRoot(root, params) {
29332
29573
  const opened = await openFileInRoot(root, params);
29333
29574
  try {
29334
- return await readOpenedFileSafely({ opened, maxBytes: params.maxBytes });
29575
+ return await read_opened_file_readOpenedFileSafely({ opened, maxBytes: params.maxBytes });
29335
29576
  }
29336
29577
  finally {
29337
29578
  await opened.handle.close().catch(() => { });
@@ -29364,20 +29605,6 @@ async function openLocalFileSafely(params) {
29364
29605
  assertNoNulPathInput(params.filePath, "file path contains a NUL byte");
29365
29606
  return await openVerifiedLocalFile(params.filePath);
29366
29607
  }
29367
- async function readOpenedFileSafely(params) {
29368
- if (params.maxBytes !== undefined && params.opened.stat.size > params.maxBytes) {
29369
- throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${params.opened.stat.size})`);
29370
- }
29371
- const buffer = await params.opened.handle.readFile();
29372
- if (params.maxBytes !== undefined && buffer.byteLength > params.maxBytes) {
29373
- throw new errors_FsSafeError("too-large", `file exceeds limit of ${params.maxBytes} bytes (got ${buffer.byteLength})`);
29374
- }
29375
- return {
29376
- buffer,
29377
- realPath: params.opened.realPath,
29378
- stat: params.opened.stat,
29379
- };
29380
- }
29381
29608
  function emitWriteBoundaryWarning(reason) {
29382
29609
  logWarn(`security: fs-safe write boundary warning (${reason})`);
29383
29610
  }
@@ -29418,82 +29645,9 @@ async function verifyAtomicWriteResult(params) {
29418
29645
  await opened.handle.close().catch(() => { });
29419
29646
  }
29420
29647
  }
29421
- async function resolveOpenedFileRealPathForHandle(handle, ioPath) {
29422
- const handleStat = await handle.stat();
29423
- const fdCandidates = process.platform === "linux"
29424
- ? [`/proc/self/fd/${handle.fd}`, `/dev/fd/${handle.fd}`]
29425
- : process.platform === "win32"
29426
- ? []
29427
- : [`/dev/fd/${handle.fd}`];
29428
- for (const fdPath of fdCandidates) {
29429
- try {
29430
- const fdRealPath = await promises_.realpath(fdPath);
29431
- const fdRealStat = await promises_.stat(fdRealPath);
29432
- if (file_identity_sameFileIdentity(handleStat, fdRealStat)) {
29433
- return fdRealPath;
29434
- }
29435
- }
29436
- catch {
29437
- // try next fd path
29438
- }
29439
- }
29440
- try {
29441
- const ioRealPath = await promises_.realpath(ioPath);
29442
- const ioRealStat = await promises_.stat(ioRealPath);
29443
- if (file_identity_sameFileIdentity(handleStat, ioRealStat)) {
29444
- return ioRealPath;
29445
- }
29446
- }
29447
- catch (err) {
29448
- if (!path_isNotFoundPathError(err)) {
29449
- throw err;
29450
- }
29451
- }
29452
- const parentResolved = await resolveOpenedFileRealPathFromParent(handleStat, ioPath);
29453
- if (parentResolved) {
29454
- return parentResolved;
29455
- }
29456
- throw new errors_FsSafeError("path-mismatch", "unable to resolve opened file path");
29457
- }
29458
- async function resolveOpenedFileRealPathFromParent(handleStat, ioPath) {
29459
- let parentReal;
29460
- try {
29461
- parentReal = await promises_.realpath(external_node_path_.dirname(ioPath));
29462
- }
29463
- catch (err) {
29464
- if (path_isNotFoundPathError(err)) {
29465
- return null;
29466
- }
29467
- throw err;
29468
- }
29469
- let entries;
29470
- try {
29471
- entries = await promises_.readdir(parentReal);
29472
- }
29473
- catch (err) {
29474
- if (path_isNotFoundPathError(err)) {
29475
- return null;
29476
- }
29477
- throw err;
29478
- }
29479
- for (const entry of entries.toSorted()) {
29480
- const candidatePath = external_node_path_.join(parentReal, entry);
29481
- try {
29482
- const candidateStat = await promises_.lstat(candidatePath);
29483
- if (candidateStat.isFile() && file_identity_sameFileIdentity(handleStat, candidateStat)) {
29484
- return await promises_.realpath(candidatePath);
29485
- }
29486
- }
29487
- catch (err) {
29488
- if (!path_isNotFoundPathError(err)) {
29489
- throw err;
29490
- }
29491
- }
29492
- }
29493
- return null;
29494
- }
29495
29648
  async function openWritableFileInRoot(root, params) {
29496
29649
  const { rootReal, rootWithSep, resolved } = await resolvePathInRoot(root, params.relativePath);
29650
+ await assertMutationNotDenied(resolved, params.denyMutations);
29497
29651
  try {
29498
29652
  await assertNoPathAliasEscape({
29499
29653
  absolutePath: resolved,
@@ -29620,6 +29774,7 @@ async function appendFileInRoot(root, params) {
29620
29774
  relativePath: params.relativePath,
29621
29775
  mkdir: params.mkdir,
29622
29776
  mode: params.mode,
29777
+ denyMutations: params.denyMutations,
29623
29778
  truncateExisting: false,
29624
29779
  append: true,
29625
29780
  });
@@ -29647,8 +29802,8 @@ async function appendFileInRoot(root, params) {
29647
29802
  await target.handle.close().catch(() => { });
29648
29803
  }
29649
29804
  }
29650
- async function removePathInRoot(root, relativePath) {
29651
- const resolved = await resolvePinnedRemovePathInRoot(root, relativePath);
29805
+ async function removePathInRoot(root, params) {
29806
+ const resolved = await resolvePinnedRemovePathInRoot(root, params.relativePath, params.denyMutations);
29652
29807
  if (process.platform === "win32") {
29653
29808
  await removePathFallback(resolved);
29654
29809
  return;
@@ -29696,7 +29851,7 @@ async function writeFileInRoot(root, params) {
29696
29851
  });
29697
29852
  return;
29698
29853
  }
29699
- const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode);
29854
+ const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
29700
29855
  await serializePathWrite(pinned.targetPath, async () => {
29701
29856
  let identity;
29702
29857
  try {
@@ -29752,7 +29907,7 @@ async function copyFileInRoot(root, params) {
29752
29907
  });
29753
29908
  return;
29754
29909
  }
29755
- const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode);
29910
+ const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
29756
29911
  await serializePathWrite(pinned.targetPath, async () => {
29757
29912
  let identity;
29758
29913
  try {
@@ -29796,8 +29951,9 @@ async function copyFileInRoot(root, params) {
29796
29951
  await source.handle.close().catch(() => { });
29797
29952
  }
29798
29953
  }
29799
- async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode) {
29954
+ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode, denyMutations) {
29800
29955
  const { rootReal, rootWithSep, resolved } = await resolvePathInRoot(root, relativePath);
29956
+ await assertMutationNotDenied(resolved, denyMutations);
29801
29957
  try {
29802
29958
  await assertNoPathAliasEscape({
29803
29959
  absolutePath: resolved,
@@ -29854,12 +30010,16 @@ async function resolvePinnedWriteTargetInRoot(root, relativePath, requestedMode)
29854
30010
  async function resolvePinnedPathInRoot(root, params) {
29855
30011
  return await resolvePinnedOperationPathInRoot(root, {
29856
30012
  allowRoot: params.allowRoot,
30013
+ denyMutations: params.denyMutations,
30014
+ protectDenyMutationAncestors: false,
29857
30015
  relativePath: params.relativePath,
29858
30016
  policy: PATH_ALIAS_POLICIES.strict,
29859
30017
  });
29860
30018
  }
29861
- async function resolvePinnedRemovePathInRoot(root, relativePath) {
30019
+ async function resolvePinnedRemovePathInRoot(root, relativePath, denyMutations) {
29862
30020
  return await resolvePinnedOperationPathInRoot(root, {
30021
+ denyMutations,
30022
+ protectDenyMutationAncestors: true,
29863
30023
  relativePath,
29864
30024
  policy: PATH_ALIAS_POLICIES.unlinkTarget,
29865
30025
  });
@@ -29871,6 +30031,7 @@ async function resolvePinnedOperationPathInRoot(root, params) {
29871
30031
  });
29872
30032
  const relativeResolved = external_node_path_.relative(resolved.rootReal, resolved.canonicalPath);
29873
30033
  if ((relativeResolved === "" || relativeResolved === ".") && params.allowRoot === true) {
30034
+ await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations);
29874
30035
  return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix: "" };
29875
30036
  }
29876
30037
  const firstSegment = relativeResolved.split(external_node_path_.sep)[0];
@@ -29884,6 +30045,9 @@ async function resolvePinnedOperationPathInRoot(root, params) {
29884
30045
  if (!path_isPathInside(resolved.rootWithSep, resolved.canonicalPath)) {
29885
30046
  throw new errors_FsSafeError("outside-workspace", "file is outside workspace root");
29886
30047
  }
30048
+ await assertMutationNotDenied(resolved.canonicalPath, params.denyMutations, {
30049
+ protectAncestors: params.protectDenyMutationAncestors,
30050
+ });
29887
30051
  return { rootReal: resolved.rootReal, resolved: resolved.canonicalPath, relativePosix };
29888
30052
  }
29889
30053
  async function resolvePinnedRootPathInRoot(root, params) {
@@ -29961,13 +30125,21 @@ async function listPathFallback(root, relativePath, withFileTypes) {
29961
30125
  throw error;
29962
30126
  }
29963
30127
  }
30128
+ async function assertMoveMutationAllowed(root, params) {
30129
+ const source = await resolvePathInRoot(root, params.fromRelative);
30130
+ await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
30131
+ const target = await resolvePathInRoot(root, params.toRelative);
30132
+ await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
30133
+ }
29964
30134
  async function movePathFallback(root, params) {
29965
30135
  const source = await resolvePathInRoot(root, params.fromRelative);
30136
+ await assertMutationNotDenied(source.resolved, params.denyMutations, { protectAncestors: true });
29966
30137
  await resolvePinnedRootPathInRoot(root, {
29967
30138
  relativePath: params.fromRelative,
29968
30139
  policy: PATH_ALIAS_POLICIES.strict,
29969
30140
  });
29970
30141
  const target = await resolvePathInRoot(root, params.toRelative);
30142
+ await assertMutationNotDenied(target.resolved, params.denyMutations, { protectAncestors: true });
29971
30143
  await resolvePinnedRootPathInRoot(root, {
29972
30144
  relativePath: params.toRelative,
29973
30145
  policy: PATH_ALIAS_POLICIES.unlinkTarget,
@@ -30051,6 +30223,7 @@ async function writeFileFallback(root, params) {
30051
30223
  relativePath: params.relativePath,
30052
30224
  mkdir: params.mkdir,
30053
30225
  mode: params.mode,
30226
+ denyMutations: params.denyMutations,
30054
30227
  truncateExisting: false,
30055
30228
  });
30056
30229
  const destinationPath = target.realPath;
@@ -30096,6 +30269,7 @@ async function writeFileFallback(root, params) {
30096
30269
  }
30097
30270
  async function writeMissingFileFallback(root, params) {
30098
30271
  const { rootReal, resolved } = await resolvePathInRoot(root, params.relativePath);
30272
+ await assertMutationNotDenied(resolved, params.denyMutations);
30099
30273
  try {
30100
30274
  await assertNoPathAliasEscape({
30101
30275
  absolutePath: resolved,
@@ -30169,6 +30343,7 @@ async function copyFileFallback(root, params, source) {
30169
30343
  relativePath: params.relativePath,
30170
30344
  mkdir: params.mkdir,
30171
30345
  mode: params.mode,
30346
+ denyMutations: params.denyMutations,
30172
30347
  truncateExisting: false,
30173
30348
  });
30174
30349
  const destinationPath = target.realPath;
@@ -30328,7 +30503,7 @@ async function file_system_utils_pathExistsWithinRoot(targetDir, relativePath) {
30328
30503
  * (symlink, traversal, or size-limit violation). These errors carry a
30329
30504
  * FsSafeError as their `cause` and should be re-thrown rather than
30330
30505
  * silently swallowed by per-file error handlers.
30331
- */ function isFsSafeViolation(error) {
30506
+ */ function file_system_utils_isFsSafeViolation(error) {
30332
30507
  return error instanceof Error && error.cause instanceof errors_FsSafeError;
30333
30508
  }
30334
30509
  async function file_system_utils_statWithinRoot(targetDir, relativePath) {
@@ -36126,6 +36301,7 @@ const PackageJsonSchema = schemas_object({
36126
36301
  */
36127
36302
 
36128
36303
 
36304
+
36129
36305
  /** Maximum skill file size: 1 MB */ const MAX_SKILL_FILE_BYTES = 1_048_576;
36130
36306
  /**
36131
36307
  * Skill directory locations to search for SKILL.md files.
@@ -36134,6 +36310,33 @@ const PackageJsonSchema = schemas_object({
36134
36310
  (0,external_node_path_.join)(".claude", "skills"),
36135
36311
  (0,external_node_path_.join)(".agents", "skills")
36136
36312
  ];
36313
+ /** Maximum lock file size: 256 KB */ const MAX_LOCK_FILE_BYTES = 262_144;
36314
+ /** Relative path to the skills lock file. */ const SKILLS_LOCK_PATH = "skills-lock.json";
36315
+ /** Zod schema for skills-lock.json structure */ const SkillsLockSchema = schemas_object({
36316
+ skills: record(schemas_string(), unknown()).optional()
36317
+ });
36318
+ /**
36319
+ * Reads the skills-lock.json file and returns the set of locked skill names.
36320
+ * Returns an empty set if the file does not exist or cannot be parsed.
36321
+ */ async function readLockedSkillNames(targetDir) {
36322
+ try {
36323
+ const exists = await pathExistsWithinRoot(targetDir, SKILLS_LOCK_PATH);
36324
+ if (!exists) {
36325
+ return new Set();
36326
+ }
36327
+ const content = await readTextWithinRoot(targetDir, SKILLS_LOCK_PATH, MAX_LOCK_FILE_BYTES);
36328
+ const result = SkillsLockSchema.safeParse(JSON.parse(content));
36329
+ if (result.success && Object.hasOwn(result.data, "skills") && result.data.skills != null) {
36330
+ return new Set(Object.keys(result.data.skills));
36331
+ }
36332
+ return new Set();
36333
+ } catch (error) {
36334
+ if (isFsSafeViolation(error)) {
36335
+ throw error;
36336
+ }
36337
+ return new Set();
36338
+ }
36339
+ }
36137
36340
  /**
36138
36341
  * File system implementation of the skill lint gateway.
36139
36342
  */ class FileSystemSkillLintGateway {
@@ -36143,7 +36346,11 @@ const PackageJsonSchema = schemas_object({
36143
36346
  const discovered = await this.discoverSkillsInDir(targetDir, relativeDir);
36144
36347
  skills.push(...discovered);
36145
36348
  }
36146
- return skills;
36349
+ const lockedNames = await readLockedSkillNames(targetDir);
36350
+ if (lockedNames.size === 0) {
36351
+ return skills;
36352
+ }
36353
+ return skills.filter((skill)=>!lockedNames.has(skill.skillName));
36147
36354
  }
36148
36355
  async discoverSkillsInDir(targetDir, skillsDir) {
36149
36356
  try {
@@ -36226,7 +36433,7 @@ const MAX_WORKFLOW_FILE_BYTES = 1_048_576;
36226
36433
  const tools = this.extractToolsFromWorkflow(workflow, file.name);
36227
36434
  allTools.push(...tools);
36228
36435
  } catch (error) {
36229
- if (isFsSafeViolation(error)) {
36436
+ if (file_system_utils_isFsSafeViolation(error)) {
36230
36437
  throw error;
36231
36438
  }
36232
36439
  }
@@ -36583,7 +36790,7 @@ class FileSystemWorkflowGateway {
36583
36790
  const candidates = extractSetupStepsFromWorkflow(workflow, config.setupActionPatterns);
36584
36791
  allCandidates.push(...candidates);
36585
36792
  } catch (error) {
36586
- if (isFsSafeViolation(error)) {
36793
+ if (file_system_utils_isFsSafeViolation(error)) {
36587
36794
  throw error;
36588
36795
  }
36589
36796
  // Skip workflow files with YAML parse errors or transient I/O failures
@@ -50937,7 +51144,7 @@ function formatHeadingAsSetext(node, state) {
50937
51144
  node.type === 'break'
50938
51145
  ) {
50939
51146
  literalWithBreak = true
50940
- return EXIT
51147
+ return (/* inlined export .EXIT */false)
50941
51148
  }
50942
51149
  })
50943
51150
 
@@ -67955,10 +68162,11 @@ exports.visitAsync = visitAsync;
67955
68162
 
67956
68163
  },
67957
68164
  5492(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
68165
+ const t=Symbol.for(`__confbox_fmt__`),n=/^(\s+)/,r=/(\s+)$/;function i(e,t={}){return{sample:t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),whiteSpace:t.preserveWhitespace===!1?void 0:{start:n.exec(e)?.[0]||``,end:r.exec(e)?.[0]||``}}}function a(e,n,r){!n||typeof n!=`object`||Object.defineProperty(n,t,{enumerable:!1,configurable:!0,writable:!0,value:i(e,r)})}function o(n,r){if(!n||typeof n!=`object`||!(t in n))return{indent:r?.indent??2,whitespace:{start:``,end:``}};let i=n[t];return{indent:r?.indent||e(i.sample||``).indent,whitespace:i.whiteSpace||{start:``,end:``}}}
67958
68166
  __webpack_require__.d(__webpack_exports__, {
67959
68167
  n: () => (a)
67960
68168
  });
67961
- const t=Symbol.for(`__confbox_fmt__`),n=/^(\s+)/,r=/(\s+)$/;function i(e,t={}){return{sample:t.indent===void 0&&t.preserveIndentation!==!1&&e.slice(0,t?.sampleSize||1024),whiteSpace:t.preserveWhitespace===!1?void 0:{start:n.exec(e)?.[0]||``,end:r.exec(e)?.[0]||``}}}function a(e,n,r){!n||typeof n!=`object`||Object.defineProperty(n,t,{enumerable:!1,configurable:!0,writable:!0,value:i(e,r)})}function o(n,r){if(!n||typeof n!=`object`||!(t in n))return{indent:r?.indent??2,whitespace:{start:``,end:``}};let i=n[t];return{indent:r?.indent||e(i.sample||``).indent,whitespace:i.whiteSpace||{start:``,end:``}}}
68169
+
67962
68170
 
67963
68171
  },
67964
68172
  5975(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
@@ -67985,11 +68193,11 @@ function jsonc_r(n,r){let i=jsonc_parser_m(n,r?.errors,r);return (0,_format.n)(n
67985
68193
 
67986
68194
  },
67987
68195
  3770(module) {
67988
- module.exports = JSON.parse('{"$id":"https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#","description":"Meta-schema for $data reference (JSON AnySchema extension proposal)","type":"object","required":["$data"],"properties":{"$data":{"type":"string","anyOf":[{"format":"relative-json-pointer"},{"format":"json-pointer"}]}},"additionalProperties":false}')
68196
+ module.exports = /*#__PURE__*/JSON.parse('{"$id":"https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#","description":"Meta-schema for $data reference (JSON AnySchema extension proposal)","type":"object","required":["$data"],"properties":{"$data":{"type":"string","anyOf":[{"format":"relative-json-pointer"},{"format":"json-pointer"}]}},"additionalProperties":false}')
67989
68197
 
67990
68198
  },
67991
68199
  3928(module) {
67992
- module.exports = JSON.parse('{"$schema":"http://json-schema.org/draft-07/schema#","$id":"http://json-schema.org/draft-07/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"$comment":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":true,"readOnly":{"type":"boolean","default":false},"examples":{"type":"array","items":true},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":true},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"propertyNames":{"format":"regex"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":true,"enum":{"type":"array","items":true,"minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"contentMediaType":{"type":"string"},"contentEncoding":{"type":"string"},"if":{"$ref":"#"},"then":{"$ref":"#"},"else":{"$ref":"#"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":true}')
68200
+ module.exports = /*#__PURE__*/JSON.parse('{"$schema":"http://json-schema.org/draft-07/schema#","$id":"http://json-schema.org/draft-07/schema#","title":"Core schema meta-schema","definitions":{"schemaArray":{"type":"array","minItems":1,"items":{"$ref":"#"}},"nonNegativeInteger":{"type":"integer","minimum":0},"nonNegativeIntegerDefault0":{"allOf":[{"$ref":"#/definitions/nonNegativeInteger"},{"default":0}]},"simpleTypes":{"enum":["array","boolean","integer","null","number","object","string"]},"stringArray":{"type":"array","items":{"type":"string"},"uniqueItems":true,"default":[]}},"type":["object","boolean"],"properties":{"$id":{"type":"string","format":"uri-reference"},"$schema":{"type":"string","format":"uri"},"$ref":{"type":"string","format":"uri-reference"},"$comment":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"default":true,"readOnly":{"type":"boolean","default":false},"examples":{"type":"array","items":true},"multipleOf":{"type":"number","exclusiveMinimum":0},"maximum":{"type":"number"},"exclusiveMaximum":{"type":"number"},"minimum":{"type":"number"},"exclusiveMinimum":{"type":"number"},"maxLength":{"$ref":"#/definitions/nonNegativeInteger"},"minLength":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"pattern":{"type":"string","format":"regex"},"additionalItems":{"$ref":"#"},"items":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/schemaArray"}],"default":true},"maxItems":{"$ref":"#/definitions/nonNegativeInteger"},"minItems":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"uniqueItems":{"type":"boolean","default":false},"contains":{"$ref":"#"},"maxProperties":{"$ref":"#/definitions/nonNegativeInteger"},"minProperties":{"$ref":"#/definitions/nonNegativeIntegerDefault0"},"required":{"$ref":"#/definitions/stringArray"},"additionalProperties":{"$ref":"#"},"definitions":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"properties":{"type":"object","additionalProperties":{"$ref":"#"},"default":{}},"patternProperties":{"type":"object","additionalProperties":{"$ref":"#"},"propertyNames":{"format":"regex"},"default":{}},"dependencies":{"type":"object","additionalProperties":{"anyOf":[{"$ref":"#"},{"$ref":"#/definitions/stringArray"}]}},"propertyNames":{"$ref":"#"},"const":true,"enum":{"type":"array","items":true,"minItems":1,"uniqueItems":true},"type":{"anyOf":[{"$ref":"#/definitions/simpleTypes"},{"type":"array","items":{"$ref":"#/definitions/simpleTypes"},"minItems":1,"uniqueItems":true}]},"format":{"type":"string"},"contentMediaType":{"type":"string"},"contentEncoding":{"type":"string"},"if":{"$ref":"#"},"then":{"$ref":"#"},"else":{"$ref":"#"},"allOf":{"$ref":"#/definitions/schemaArray"},"anyOf":{"$ref":"#/definitions/schemaArray"},"oneOf":{"$ref":"#/definitions/schemaArray"},"not":{"$ref":"#"}},"default":true}')
67993
68201
 
67994
68202
  },
67995
68203
 
@@ -68051,12 +68259,16 @@ __webpack_require__.t = function(value, mode) {
68051
68259
  })();
68052
68260
  // webpack/runtime/define_property_getters
68053
68261
  (() => {
68054
- __webpack_require__.d = (exports, definition) => {
68055
- for(var key in definition) {
68056
- if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
68057
- Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
68058
- }
68059
- }
68262
+ __webpack_require__.d = (exports, getters, values) => {
68263
+ var define = (defs, kind) => {
68264
+ for(var key in defs) {
68265
+ if(__webpack_require__.o(defs, key) && !__webpack_require__.o(exports, key)) {
68266
+ Object.defineProperty(exports, key, { enumerable: true, [kind]: defs[key] });
68267
+ }
68268
+ }
68269
+ };
68270
+ define(getters, "get");
68271
+ define(values, "value");
68060
68272
  };
68061
68273
  })();
68062
68274
  // webpack/runtime/ensure_chunk
@@ -68158,4 +68370,4 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
68158
68370
  // module factories are used so entry inlining is disabled
68159
68371
  // startup
68160
68372
  // Load entry module and return exports
68161
- var __webpack_exports__ = __webpack_require__(3523);
68373
+ var __webpack_exports__ = __webpack_require__(2229);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lousy-agents/mcp",
3
- "version": "5.14.9",
3
+ "version": "5.15.0",
4
4
  "description": "MCP server for lousy-agents - provides AI coding assistant tools via the Model Context Protocol",
5
5
  "type": "module",
6
6
  "repository": {