@lousy-agents/mcp 5.23.3 → 5.23.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/mcp-server.js +122 -44
  2. package/package.json +1 -1
@@ -30286,6 +30286,15 @@ function assertWindowsAclRemediationAllowed() {
30286
30286
 
30287
30287
  const runtimePlatform = process.versions.bun ? (0,external_node_os_.platform)() : undefined;
30288
30288
  const bunPosix = runtimePlatform === "darwin" || runtimePlatform === "linux" ? runtimePlatform : undefined;
30289
+ function nativeResult(input, result) {
30290
+ if (result.path !== undefined)
30291
+ return result.path;
30292
+ const errno = -(result.errno);
30293
+ const code = (0,external_node_util_.getSystemErrorName)(errno);
30294
+ throw Object.assign(new Error(`${code}: realpath '${input}'`), {
30295
+ code, errno, syscall: "realpath", path: input,
30296
+ });
30297
+ }
30289
30298
  function realpath_resolve(input, native) {
30290
30299
  if (native && process.platform === "win32") {
30291
30300
  try {
@@ -30332,14 +30341,7 @@ function realpath_resolve(input, native) {
30332
30341
  const binding = native_getNativeBinding();
30333
30342
  if (binding?.canonicalizePath) {
30334
30343
  // Ordinary resolution normalizes both the input and each expanded symlink.
30335
- const result = binding.canonicalizePath(input, !native);
30336
- if (result.path !== undefined)
30337
- return result.path;
30338
- const errno = -(result.errno);
30339
- const code = (0,external_node_util_.getSystemErrorName)(errno);
30340
- throw Object.assign(new Error(`${code}: realpath '${input}'`), {
30341
- code, errno, syscall: "realpath", path: input,
30342
- });
30344
+ return nativeResult(input, binding.canonicalizePath(input, !native));
30343
30345
  }
30344
30346
  if (getFsSafeNativeConfig().mode === "require") {
30345
30347
  throw new errors_FsSafeError("helper-unavailable", "native fs-safe canonicalization is unavailable");
@@ -30352,10 +30354,19 @@ function realpath_resolve(input, native) {
30352
30354
  const realpath_realpathSync = Object.assign((input) => realpath_resolve(input, false), {
30353
30355
  native: (input) => realpath_resolve(input, true),
30354
30356
  });
30355
- /** Async on Node; retain runtime-specific native canonicalization guarantees. */
30357
+ /** POSIX async canonicalization retains Bun's native path and record-lock semantics. */
30356
30358
  async function realpath_realpathNative(input) {
30357
- if (bunPosix)
30358
- return realpath_realpathSync.native(input);
30359
+ if (bunPosix) {
30360
+ if (input.includes("\0")) {
30361
+ throw Object.assign(new TypeError("realpath input must not contain null bytes"), { code: "ERR_INVALID_ARG_VALUE" });
30362
+ }
30363
+ const binding = native_getNativeBinding();
30364
+ if (binding?.canonicalizePathAsync)
30365
+ return nativeResult(input, await binding.canonicalizePathAsync(input, false));
30366
+ if (binding?.canonicalizePath || getFsSafeNativeConfig().mode === "require") {
30367
+ throw new errors_FsSafeError("helper-unavailable", "native fs-safe canonicalization is unavailable");
30368
+ }
30369
+ }
30359
30370
  try {
30360
30371
  return await promises_.realpath(input);
30361
30372
  }
@@ -30462,6 +30473,7 @@ function assertStatObservationSync(inspect, expected, initial, platform = proces
30462
30473
 
30463
30474
 
30464
30475
 
30476
+
30465
30477
  // Numeric metadata is retained for existing internal consumers; rounded IDs
30466
30478
  // must never become authority for a later comparison.
30467
30479
  const exactGuardIdentities = new WeakMap();
@@ -30569,7 +30581,15 @@ async function createNearestExistingDirectoryGuard(rootReal, targetPath, options
30569
30581
  }
30570
30582
  // Recovery receipts must retain every identity bit, including on Windows.
30571
30583
  async function directory_guard_inspectDirectoryIdentity(dir, expected) {
30572
- return directory_guard_inspectDirectoryIdentitySync(dir, expected);
30584
+ if (process.platform === "win32")
30585
+ return directory_guard_inspectDirectoryIdentitySync(dir, expected);
30586
+ const operationPath = directoryOperationPath(dir);
30587
+ return strict_file_identity_inspectFileIdentity(async () => {
30588
+ const stat = await promises_.lstat(operationPath, { bigint: true });
30589
+ if (stat.isSymbolicLink() || !stat.isDirectory())
30590
+ throw root_errors_directoryComponentNotDirectoryError();
30591
+ return stat;
30592
+ }, expected);
30573
30593
  }
30574
30594
  function directoryOperationPath(dir) {
30575
30595
  windows_path_alias_assertNoWindowsPathAlias(dir, "filesystem");
@@ -33217,7 +33237,7 @@ async function readBoundedAsync(maxBytes, readChunk, options = {}) {
33217
33237
  let total = 0;
33218
33238
  const { observeRegularFileSize, createLimitError } = options;
33219
33239
  const allocate = options.unpooled ? Buffer.allocUnsafeSlow : undefined;
33220
- const size = options.initialSize ?? observeRegularFileSize?.();
33240
+ const size = options.initialSize ?? await observeRegularFileSize?.();
33221
33241
  let buffer = size === undefined ? createScratchBuffer(maxBytes, allocate) : createInitialBuffer(maxBytes, size, allocate);
33222
33242
  if (size !== undefined) {
33223
33243
  const bytesRead = await readChunk(buffer, buffer.length);
@@ -33225,7 +33245,7 @@ async function readBoundedAsync(maxBytes, readChunk, options = {}) {
33225
33245
  return finishReadBuffer(buffer, 0, allocate);
33226
33246
  // Short reads can occur before EOF. Only use the size shortcut on this
33227
33247
  // initial read; virtual files can report zero or stale sizes thereafter.
33228
- const currentSize = bytesRead < buffer.length ? observeRegularFileSize?.() : undefined;
33248
+ const currentSize = bytesRead < buffer.length ? await observeRegularFileSize?.() : undefined;
33229
33249
  total = addReadBytes(total, bytesRead, maxBytes, createLimitError);
33230
33250
  if (currentSize !== undefined && currentSize > 0 && bytesRead >= currentSize)
33231
33251
  return finishReadBuffer(buffer, total, allocate);
@@ -33256,12 +33276,12 @@ function readFileHandleBoundedWithSize(handle, maxBytes, initialSize) {
33256
33276
  return (await handle.read(scratch, 0, length, null)).bytesRead;
33257
33277
  }, {
33258
33278
  initialSize,
33259
- observeRegularFileSize: fd === undefined ? undefined : () => regularFileSize(fd),
33279
+ observeRegularFileSize: fd === undefined ? undefined : () => regularFileSizeAsync(fd),
33260
33280
  });
33261
33281
  }
33262
33282
  function regularFileSize(fd) {
33263
33283
  try {
33264
- const stat = external_node_fs_.fstatSync(fd);
33284
+ const stat = fs.fstatSync(fd);
33265
33285
  return stat.isFile() && Number.isSafeInteger(stat.size) && stat.size >= 0
33266
33286
  ? stat.size : undefined;
33267
33287
  }
@@ -33270,6 +33290,17 @@ function regularFileSize(fd) {
33270
33290
  return undefined;
33271
33291
  }
33272
33292
  }
33293
+ async function regularFileSizeAsync(fd) {
33294
+ try {
33295
+ const stat = await new Promise((resolve, reject) => {
33296
+ external_node_fs_.fstat(fd, (error, value) => error ? reject(error) : resolve(value));
33297
+ });
33298
+ return stat.isFile() && Number.isSafeInteger(stat.size) && stat.size >= 0 ? stat.size : undefined;
33299
+ }
33300
+ catch {
33301
+ return undefined;
33302
+ }
33303
+ }
33273
33304
  function readDescriptorChunk(fd, scratch, length) {
33274
33305
  return new Promise((resolve, reject) => {
33275
33306
  fs.read(fd, scratch, 0, length, null, (error, bytesRead) => {
@@ -33286,7 +33317,7 @@ async function readFileDescriptorBounded(fd, maxBytes) {
33286
33317
  normalizeMaxBytes(maxBytes);
33287
33318
  return await readBoundedAsync(maxBytes, async (scratch, length) => {
33288
33319
  return await readDescriptorChunk(fd, scratch, length);
33289
- }, { observeRegularFileSize: () => regularFileSize(fd) });
33320
+ }, { observeRegularFileSize: () => regularFileSizeAsync(fd) });
33290
33321
  }
33291
33322
  function readBoundedSync(maxBytes, readChunk, options = {}) {
33292
33323
  byte_budget_normalizeMaxBytes(maxBytes);
@@ -37699,7 +37730,8 @@ function* traverseRootPath(params, { mode = "native", observation: observationOu
37699
37730
  windows_path_alias_assertNoWindowsPathAlias(rootPath);
37700
37731
  windows_path_alias_assertNoWindowsPathAlias(absolutePath);
37701
37732
  windows_path_alias_assertNoWindowsPathAlias(rootCanonicalPath);
37702
- observeRoot?.(rootCanonicalPath);
37733
+ if (observeRoot)
37734
+ yield* wait(observeRoot(rootCanonicalPath));
37703
37735
  const context = createLexicalTraversalContext(yield* prepareRootTraversal(input, rootPath, rootCanonicalPath, absolutePath, rawAbsolutePath, synchronous));
37704
37736
  const { state } = context;
37705
37737
  const observation = createLexicalTraversalObservation(context, observationOutput?.request);
@@ -37890,6 +37922,8 @@ function assertInsideBoundary(params) {
37890
37922
 
37891
37923
 
37892
37924
 
37925
+
37926
+
37893
37927
  const root_context_ensureTrailingSep = (value) => value.endsWith(external_node_path_.sep) ? value : value + external_node_path_.sep;
37894
37928
  function assertValidRootRelativePath(relativePath) {
37895
37929
  path_assertNoNulPathInput(relativePath, "relative path contains a NUL byte");
@@ -37913,21 +37947,24 @@ async function expandRelativePathWithHome(relativePath) {
37913
37947
  }
37914
37948
  const rawHome = process.env.HOME || process.env.USERPROFILE || external_node_os_.homedir();
37915
37949
  windows_path_alias_assertNoWindowsPathAlias(rawHome, "filesystem", "home path uses a Windows filesystem namespace alias");
37916
- if (cachedHomePath?.raw !== rawHome) {
37950
+ let home = cachedHomePath?.raw === rawHome ? cachedHomePath.real : undefined;
37951
+ if (home === undefined) {
37917
37952
  let realHome = rawHome;
37918
37953
  try {
37919
- realHome = realpath_realpathSync.native(windows_path_alias_pathForWindowsFilesystem(rawHome));
37954
+ const homePath = windows_path_alias_pathForWindowsFilesystem(rawHome);
37955
+ realHome = process.platform === "win32" ? realpath_realpathSync.native(homePath) : await realpath_realpathNative(homePath);
37920
37956
  }
37921
37957
  catch {
37922
37958
  // If the home dir cannot be canonicalized, keep lexical expansion behavior.
37923
37959
  }
37924
37960
  cachedHomePath = { raw: rawHome, real: realHome };
37961
+ home = realHome;
37925
37962
  }
37926
37963
  if (homeOnly) {
37927
- windows_path_alias_assertNoWindowsPathAlias(cachedHomePath.real, "filesystem", "home path uses a Windows filesystem namespace alias");
37928
- return cachedHomePath.real;
37964
+ windows_path_alias_assertNoWindowsPathAlias(home, "filesystem", "home path uses a Windows filesystem namespace alias");
37965
+ return home;
37929
37966
  }
37930
- const expanded = `${root_context_ensureTrailingSep(cachedHomePath.real)}${relativePath.slice(2)}`;
37967
+ const expanded = `${root_context_ensureTrailingSep(home)}${relativePath.slice(2)}`;
37931
37968
  windows_path_alias_assertNoWindowsPathAlias(expanded, "filesystem", "expanded path uses a Windows filesystem namespace alias");
37932
37969
  return expanded;
37933
37970
  }
@@ -37940,14 +37977,17 @@ async function resolveRootContext(rootDir) {
37940
37977
  let rootStat;
37941
37978
  let rootIdentity;
37942
37979
  try {
37943
- rootReal = realpath_realpathSync.native(windows_path_alias_pathForWindowsFilesystem(rootDir));
37980
+ const rootPath = windows_path_alias_pathForWindowsFilesystem(absolutePathWithRawSegments(rootDir));
37981
+ rootReal = process.platform === "win32" ? realpath_realpathSync.native(rootPath) : await realpath_realpathNative(rootPath);
37944
37982
  windows_path_alias_assertNoWindowsPathAlias(rootReal, "filesystem", "canonical root path uses a Windows filesystem namespace alias");
37945
- rootStat = await strict_file_identity_inspectFileIdentity(() => {
37946
- const stat = external_node_fs_.statSync(rootReal, { bigint: true });
37983
+ const inspect = (stat) => {
37947
37984
  if (!stat.isDirectory())
37948
37985
  throw new errors_FsSafeError("invalid-path", "root dir is not a directory");
37949
37986
  return stat;
37950
- });
37987
+ };
37988
+ rootStat = await strict_file_identity_inspectFileIdentity(() => process.platform === "win32"
37989
+ ? inspect(external_node_fs_.statSync(rootReal, { bigint: true }))
37990
+ : promises_.stat(rootReal, { bigint: true }).then(inspect));
37951
37991
  rootIdentity = { dev: rootStat.dev, ino: rootStat.ino };
37952
37992
  }
37953
37993
  catch (err) {
@@ -38007,7 +38047,15 @@ function root_context_assertRootIdentityCurrentSync(root, observe) {
38007
38047
  }
38008
38048
  }
38009
38049
  async function assertRootIdentityCurrent(root, observe) {
38010
- root_context_assertRootIdentityCurrentSync(root, observe);
38050
+ if (process.platform === "win32")
38051
+ return root_context_assertRootIdentityCurrentSync(root, observe);
38052
+ try {
38053
+ const stat = await directory_guard_inspectDirectoryIdentity(root.rootReal, { dev: root.rootIdentity.dev, ino: root.rootIdentity.ino });
38054
+ observe?.(stat);
38055
+ }
38056
+ catch (error) {
38057
+ throw rootPathChangedError(error instanceof Error ? error : undefined);
38058
+ }
38011
38059
  }
38012
38060
  /**
38013
38061
  * Observe the current Root with an exact, operation-local receipt.
@@ -45143,7 +45191,8 @@ async function recordPreOpenFileChange(error, handle, filePath, before, opened)
45143
45191
  return;
45144
45192
  try {
45145
45193
  await strict_file_identity_inspectFileIdentity(async () => before);
45146
- const current = await strict_file_identity_inspectFileIdentity(() => external_node_fs_.fstatSync(handle.fd, { bigint: true }), opened);
45194
+ const current = await strict_file_identity_inspectFileIdentity(() => process.platform === "win32"
45195
+ ? external_node_fs_.fstatSync(handle.fd, { bigint: true }) : handle.stat({ bigint: true }), opened);
45147
45196
  if (current.isFile() && [0n, 1n].includes(current.nlink) &&
45148
45197
  (before.dev !== current.dev || before.ino !== current.ino)) {
45149
45198
  // A stale pathname sample is not proof that its former inode was unlinked.
@@ -45159,7 +45208,8 @@ async function recordOpenedFileFailure(error, handle, filePath, identity) {
45159
45208
  !identity.isFile() || identity.nlink > 1n)
45160
45209
  return;
45161
45210
  try {
45162
- const current = await strict_file_identity_inspectFileIdentity(() => external_node_fs_.fstatSync(handle.fd, { bigint: true }), identity);
45211
+ const current = await strict_file_identity_inspectFileIdentity(() => process.platform === "win32"
45212
+ ? external_node_fs_.fstatSync(handle.fd, { bigint: true }) : handle.stat({ bigint: true }), identity);
45163
45213
  if (current.isFile() && current.nlink === 0n)
45164
45214
  recordFileObservationFailure(error, `unlinked:${filePath}`);
45165
45215
  }
@@ -45191,8 +45241,7 @@ async function openLocalFileDescriptor(filePath, options) {
45191
45241
  // Reject directories before opening so we never surface EISDIR to callers (e.g. tool
45192
45242
  // results that get sent to messaging channels). See openclaw/openclaw#31186.
45193
45243
  try {
45194
- preOpenStat = strict_file_identity_inspectFileIdentitySync(() => {
45195
- const stat = external_node_fs_.lstatSync(filePath, { bigint: true });
45244
+ const inspect = (stat) => {
45196
45245
  observedBeforeOpen = true;
45197
45246
  if (stat.isSymbolicLink() && options?.symlinks !== "follow-within-root") {
45198
45247
  throw new errors_FsSafeError("symlink", "symlink not allowed");
@@ -45201,7 +45250,10 @@ async function openLocalFileDescriptor(filePath, options) {
45201
45250
  throw new errors_FsSafeError("not-file", "not a file");
45202
45251
  }
45203
45252
  return stat;
45204
- });
45253
+ };
45254
+ preOpenStat = process.platform === "win32"
45255
+ ? strict_file_identity_inspectFileIdentitySync(() => inspect(external_node_fs_.lstatSync(filePath, { bigint: true })))
45256
+ : await strict_file_identity_inspectFileIdentity(async () => inspect(await promises_.lstat(filePath, { bigint: true })));
45205
45257
  }
45206
45258
  catch (err) {
45207
45259
  if (err instanceof errors_FsSafeError || observedBeforeOpen) {
@@ -45238,12 +45290,16 @@ async function openLocalFileDescriptor(filePath, options) {
45238
45290
  let openedIdentity;
45239
45291
  let identity;
45240
45292
  try {
45241
- identity = strict_file_identity_inspectFileIdentitySync(() => {
45242
- openedIdentity = external_node_fs_.fstatSync(handle.fd, { bigint: true });
45243
- if (!openedIdentity.isFile())
45293
+ const inspect = (stat) => {
45294
+ openedIdentity = stat;
45295
+ if (!stat.isFile())
45244
45296
  throw new errors_FsSafeError("not-file", "not a file");
45245
- return openedIdentity;
45246
- }, preOpenStat && !preOpenStat.isSymbolicLink() ? preOpenStat : undefined);
45297
+ return stat;
45298
+ };
45299
+ const expected = preOpenStat && !preOpenStat.isSymbolicLink() ? preOpenStat : undefined;
45300
+ identity = process.platform === "win32"
45301
+ ? strict_file_identity_inspectFileIdentitySync(() => inspect(external_node_fs_.fstatSync(handle.fd, { bigint: true })), expected)
45302
+ : await strict_file_identity_inspectFileIdentity(async () => inspect(await handle.stat({ bigint: true })), expected);
45247
45303
  }
45248
45304
  catch (error) {
45249
45305
  if (openedIdentity && [0n, 1n].includes(openedIdentity.nlink)) {
@@ -48144,6 +48200,8 @@ async function movePathNative(root, params, paths, overwrite = false) {
48144
48200
 
48145
48201
 
48146
48202
 
48203
+
48204
+
48147
48205
  function resolveFinalOpenedRealPath(filePath) {
48148
48206
  try {
48149
48207
  return realpath_realpathSync.native(filePath);
@@ -48167,6 +48225,12 @@ function inspectOpenedPathIdentitySync(filePath, symlinks) {
48167
48225
  }
48168
48226
  return stat;
48169
48227
  }
48228
+ async function inspectOpenedPathIdentity(filePath, symlinks) {
48229
+ const stat = await (symlinks === "follow-within-root" ? promises_.stat(filePath, { bigint: true }) : promises_.lstat(filePath, { bigint: true }));
48230
+ if (stat.isSymbolicLink() && symlinks !== "follow-within-root")
48231
+ throw new errors_FsSafeError("symlink", "symlink not allowed");
48232
+ return stat;
48233
+ }
48170
48234
  async function admitRootReadHandle(params) {
48171
48235
  try {
48172
48236
  if (params.hardlinks !== "allow" && params.opened.stat.nlink > 1) {
@@ -48175,14 +48239,20 @@ async function admitRootReadHandle(params) {
48175
48239
  if (params.beforeFinalFence) {
48176
48240
  await params.beforeFinalFence(params.filePath, params.opened.handle);
48177
48241
  }
48178
- try {
48179
- root_context_assertRootIdentityCurrentSync(params.root);
48242
+ function* admit() {
48243
+ const synchronous = process.platform === "win32";
48244
+ if (synchronous)
48245
+ root_context_assertRootIdentityCurrentSync(params.root);
48246
+ else
48247
+ yield* wait(assertRootIdentityCurrent(params.root));
48180
48248
  let realPath;
48181
48249
  try {
48182
- const current = strict_file_identity_inspectFileIdentitySync(() => inspectOpenedPathIdentitySync(params.filePath, params.symlinks), params.identity);
48250
+ const current = synchronous
48251
+ ? strict_file_identity_inspectFileIdentitySync(() => inspectOpenedPathIdentitySync(params.filePath, params.symlinks), params.identity)
48252
+ : yield* wait(strict_file_identity_inspectFileIdentity(() => inspectOpenedPathIdentity(params.filePath, params.symlinks), params.identity));
48183
48253
  if (params.hardlinks !== "allow" && current.nlink > 1n)
48184
48254
  throw hardlinkedPathNotAllowedError();
48185
- const canonicalPath = resolveFinalOpenedRealPath(params.filePath);
48255
+ const canonicalPath = synchronous ? resolveFinalOpenedRealPath(params.filePath) : yield* wait(realpath_realpathNative(params.filePath));
48186
48256
  windows_path_alias_assertNoWindowsPathAlias(canonicalPath, "filesystem", "resolved file path uses a Windows filesystem namespace alias");
48187
48257
  const admittedRealPath = root_boundary_admitPathInsideRoot({
48188
48258
  rootPath: params.root.rootReal,
@@ -48194,7 +48264,9 @@ async function admitRootReadHandle(params) {
48194
48264
  }
48195
48265
  // This is a fresh no-follow observation even when canonicalPath and
48196
48266
  // filePath have the same spelling; realpath may have raced a replacement.
48197
- const canonical = strict_file_identity_inspectFileIdentitySync(() => inspectOpenedPathIdentitySync(canonicalPath, undefined), params.identity);
48267
+ const canonical = synchronous
48268
+ ? strict_file_identity_inspectFileIdentitySync(() => inspectOpenedPathIdentitySync(canonicalPath, undefined), params.identity)
48269
+ : yield* wait(strict_file_identity_inspectFileIdentity(() => inspectOpenedPathIdentity(canonicalPath), params.identity));
48198
48270
  if (params.hardlinks !== "allow" && canonical.nlink > 1n)
48199
48271
  throw hardlinkedPathNotAllowedError();
48200
48272
  realPath = admittedRealPath.path;
@@ -48205,9 +48277,15 @@ async function admitRootReadHandle(params) {
48205
48277
  : error;
48206
48278
  }
48207
48279
  params.afterPathIdentityCheck?.(params.filePath, params.opened.handle);
48208
- root_context_assertRootIdentityCurrentSync(params.root);
48280
+ if (synchronous)
48281
+ root_context_assertRootIdentityCurrentSync(params.root);
48282
+ else
48283
+ yield* wait(assertRootIdentityCurrent(params.root));
48209
48284
  return { ...params.opened, realPath };
48210
48285
  }
48286
+ try {
48287
+ return process.platform === "win32" ? atomic_io_runSync(admit()) : await runAsync(admit());
48288
+ }
48211
48289
  catch (error) {
48212
48290
  if (params.identity.nlink <= 1n) {
48213
48291
  await recordOpenedFileFailure(error, params.opened.handle, params.filePath, params.identity);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lousy-agents/mcp",
3
- "version": "5.23.3",
3
+ "version": "5.23.4",
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": {