@lousy-agents/mcp 5.15.3 → 5.15.5

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 +270 -51
  2. package/package.json +1 -1
@@ -6559,7 +6559,7 @@ function escapeJsonPtr(str) {
6559
6559
 
6560
6560
 
6561
6561
  },
6562
- 2229(__unused_rspack_module, __unused_rspack___webpack_exports__, __webpack_require__) {
6562
+ 8705(__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);
@@ -6715,7 +6715,7 @@ const regexes_base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0
6715
6715
  const regexes_base64url = /^[A-Za-z0-9_-]*$/;
6716
6716
  // based on https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address
6717
6717
  // export const hostname: RegExp = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+$/;
6718
- const hostname = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
6718
+ const regexes_hostname = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
6719
6719
  const domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
6720
6720
  const httpProtocol = /^https?$/;
6721
6721
  // https://blog.stevenlevithan.com/archives/validate-phone-number#r4-3 (regex sans spaces)
@@ -26673,6 +26673,7 @@ function hasNonEmptyString(value) {
26673
26673
 
26674
26674
 
26675
26675
 
26676
+
26676
26677
  const NOT_FOUND_CODES = new Set(["ENOENT", "ENOTDIR"]);
26677
26678
  const SYMLINK_OPEN_CODES = new Set(["ELOOP", "EINVAL", "ENOTSUP"]);
26678
26679
  const POSIX_SEPARATOR_CHAR_CODE = 0x2f;
@@ -26872,6 +26873,29 @@ function directory_guard_createNearestExistingSyncDirectoryGuard(rootReal, targe
26872
26873
  return directory_guard_createSyncDirectoryGuard(root);
26873
26874
  }
26874
26875
 
26876
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/fsync.js
26877
+
26878
+
26879
+ async function syncDirectoryBestEffort(dirPath) {
26880
+ if (process.platform === "win32") {
26881
+ return;
26882
+ }
26883
+ let handle;
26884
+ try {
26885
+ const flags = external_node_fs_.constants.O_RDONLY |
26886
+ ("O_DIRECTORY" in external_node_fs_.constants ? external_node_fs_.constants.O_DIRECTORY : 0) |
26887
+ ("O_NOFOLLOW" in external_node_fs_.constants ? external_node_fs_.constants.O_NOFOLLOW : 0);
26888
+ handle = await promises_.open(dirPath, flags);
26889
+ await handle.sync();
26890
+ }
26891
+ catch {
26892
+ // Some filesystems reject directory handles; keep the write usable there.
26893
+ }
26894
+ finally {
26895
+ await handle?.close().catch(() => undefined);
26896
+ }
26897
+ }
26898
+
26875
26899
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/guarded-mkdir.js
26876
26900
 
26877
26901
 
@@ -27970,6 +27994,7 @@ async function runPinnedPathHelper(params) {
27970
27994
 
27971
27995
 
27972
27996
 
27997
+
27973
27998
  function pinned_write_byteLength(input, encoding) {
27974
27999
  return typeof input === "string"
27975
28000
  ? Buffer.byteLength(input, encoding ?? "utf8")
@@ -28162,11 +28187,13 @@ async function runPinnedWriteFallback(params) {
28162
28187
  throw new errors_FsSafeError("path-mismatch", "fallback temp path changed during write");
28163
28188
  }
28164
28189
  const expectedTempStat = tempStat;
28190
+ await handle.sync();
28165
28191
  await handle.close().catch(() => undefined);
28166
28192
  handle = undefined;
28167
28193
  await withAsyncDirectoryGuards([parentGuard], async () => {
28168
28194
  await promises_.rename(tempPath, targetPath);
28169
28195
  renamed = true;
28196
+ await syncDirectoryBestEffort(parentPath);
28170
28197
  targetStat = await promises_.lstat(targetPath);
28171
28198
  if (targetStat.isSymbolicLink() || !file_identity_sameFileIdentity(targetStat, expectedTempStat)) {
28172
28199
  throw new errors_FsSafeError("path-mismatch", "fallback target changed during write");
@@ -28840,6 +28867,197 @@ function path_policy_shortPath(value) {
28840
28867
  return value;
28841
28868
  }
28842
28869
 
28870
+ // EXTERNAL MODULE: external "node:url"
28871
+ var external_node_url_ = __webpack_require__(3136);
28872
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/local-file-access.js
28873
+
28874
+
28875
+
28876
+ const ENCODED_FILE_URL_SEPARATOR_RE = /%(?:2f|5c)/i;
28877
+ function isLocalFileUrlHost(hostname) {
28878
+ const normalized = normalizeLowercaseStringOrEmpty(hostname);
28879
+ return normalized === "" || normalized === "localhost";
28880
+ }
28881
+ function hasEncodedFileUrlSeparator(pathname) {
28882
+ return ENCODED_FILE_URL_SEPARATOR_RE.test(pathname);
28883
+ }
28884
+ function isWindowsNetworkPath(filePath, platform = process.platform) {
28885
+ if (platform !== "win32") {
28886
+ return false;
28887
+ }
28888
+ const normalized = filePath.replace(/\//g, "\\");
28889
+ return normalized.startsWith("\\\\?\\UNC\\") || normalized.startsWith("\\\\");
28890
+ }
28891
+ function isWindowsDriveLetterPath(filePath, platform = process.platform) {
28892
+ return platform === "win32" && /^[A-Za-z]:[\\/]/.test(filePath);
28893
+ }
28894
+ function assertNoWindowsNetworkPath(filePath, label = "Path") {
28895
+ if (isWindowsNetworkPath(filePath)) {
28896
+ throw new Error(`${label} cannot use Windows network paths: ${filePath}`);
28897
+ }
28898
+ }
28899
+ function safeFileURLToPath(fileUrl) {
28900
+ let parsed;
28901
+ try {
28902
+ parsed = new external_node_url_.URL(fileUrl);
28903
+ }
28904
+ catch {
28905
+ throw new Error(`Invalid file:// URL: ${fileUrl}`);
28906
+ }
28907
+ if (parsed.protocol !== "file:") {
28908
+ throw new Error(`Invalid file:// URL: ${fileUrl}`);
28909
+ }
28910
+ if (!isLocalFileUrlHost(parsed.hostname)) {
28911
+ throw new Error(`file:// URLs with remote hosts are not allowed: ${fileUrl}`);
28912
+ }
28913
+ if (hasEncodedFileUrlSeparator(parsed.pathname)) {
28914
+ throw new Error(`file:// URLs cannot encode path separators: ${fileUrl}`);
28915
+ }
28916
+ const filePath = (0,external_node_url_.fileURLToPath)(parsed);
28917
+ assertNoWindowsNetworkPath(filePath, "Local file URL");
28918
+ return filePath;
28919
+ }
28920
+ function trySafeFileURLToPath(fileUrl) {
28921
+ try {
28922
+ return safeFileURLToPath(fileUrl);
28923
+ }
28924
+ catch {
28925
+ return undefined;
28926
+ }
28927
+ }
28928
+ function basenameFromMediaSource(source) {
28929
+ if (!source) {
28930
+ return undefined;
28931
+ }
28932
+ if (source.startsWith("file://")) {
28933
+ const filePath = trySafeFileURLToPath(source);
28934
+ return filePath ? path.basename(filePath) || undefined : undefined;
28935
+ }
28936
+ if (/^https?:\/\//i.test(source)) {
28937
+ try {
28938
+ return path.basename(new URL(source).pathname) || undefined;
28939
+ }
28940
+ catch {
28941
+ return undefined;
28942
+ }
28943
+ }
28944
+ return path.basename(source) || undefined;
28945
+ }
28946
+
28947
+ ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/device-path.js
28948
+
28949
+
28950
+
28951
+ const POSIX_BLOCKED_DEVICE_PATHS = new Set([
28952
+ "/dev/zero",
28953
+ "/dev/random",
28954
+ "/dev/urandom",
28955
+ "/dev/full",
28956
+ "/dev/stdin",
28957
+ "/dev/stdout",
28958
+ "/dev/stderr",
28959
+ "/dev/tty",
28960
+ "/dev/console",
28961
+ ]);
28962
+ const WINDOWS_RESERVED_DEVICE_NAMES = new Set([
28963
+ "CON",
28964
+ "PRN",
28965
+ "AUX",
28966
+ "NUL",
28967
+ "CLOCK$",
28968
+ "CONIN$",
28969
+ "CONOUT$",
28970
+ "COM1",
28971
+ "COM2",
28972
+ "COM3",
28973
+ "COM4",
28974
+ "COM5",
28975
+ "COM6",
28976
+ "COM7",
28977
+ "COM8",
28978
+ "COM9",
28979
+ "COM¹",
28980
+ "COM²",
28981
+ "COM³",
28982
+ "LPT1",
28983
+ "LPT2",
28984
+ "LPT3",
28985
+ "LPT4",
28986
+ "LPT5",
28987
+ "LPT6",
28988
+ "LPT7",
28989
+ "LPT8",
28990
+ "LPT9",
28991
+ "LPT¹",
28992
+ "LPT²",
28993
+ "LPT³",
28994
+ ]);
28995
+ function candidateReadPaths(filePath) {
28996
+ if (!filePath.startsWith("file://")) {
28997
+ return [filePath];
28998
+ }
28999
+ const parsed = trySafeFileURLToPath(filePath);
29000
+ return parsed === undefined ? [filePath] : [filePath, parsed];
29001
+ }
29002
+ function normalizePosixPath(filePath, cwd) {
29003
+ if (external_node_path_.posix.isAbsolute(filePath)) {
29004
+ return external_node_path_.posix.normalize(filePath);
29005
+ }
29006
+ const base = cwd && external_node_path_.posix.isAbsolute(cwd) ? cwd : process.cwd();
29007
+ return external_node_path_.posix.resolve(base, filePath);
29008
+ }
29009
+ function matchPosixDeviceReadPath(filePath, cwd) {
29010
+ const normalized = normalizePosixPath(filePath, cwd);
29011
+ if (POSIX_BLOCKED_DEVICE_PATHS.has(normalized)) {
29012
+ return { path: normalized, reason: "posix-device" };
29013
+ }
29014
+ if (normalized === "/dev/fd" || normalized.startsWith("/dev/fd/")) {
29015
+ return { path: normalized, reason: "posix-fd" };
29016
+ }
29017
+ if (/^\/proc\/(?:self|thread-self|\d+)\/fd(?:\/|$)/.test(normalized)) {
29018
+ return { path: normalized, reason: "posix-fd" };
29019
+ }
29020
+ return undefined;
29021
+ }
29022
+ function normalizeWindowsDeviceBaseName(filePath) {
29023
+ const normalized = filePath.replace(/\//g, "\\").replace(/[\\]+$/g, "");
29024
+ const lastSegment = normalized.split("\\").filter(Boolean).at(-1) ?? normalized;
29025
+ const withoutStream = lastSegment.split(":")[0] ?? lastSegment;
29026
+ const withoutTrailingIgnoredChars = withoutStream.replace(/[ .]+$/g, "");
29027
+ return (withoutTrailingIgnoredChars.split(".")[0] ?? withoutTrailingIgnoredChars).toUpperCase();
29028
+ }
29029
+ function matchWindowsDeviceReadPath(filePath) {
29030
+ const normalized = filePath.replace(/\//g, "\\");
29031
+ if (/^\\\\\.\\/.test(normalized) || /^\\\\\?\\GLOBALROOT\\Device\\/i.test(normalized)) {
29032
+ return { path: normalized, reason: "windows-device" };
29033
+ }
29034
+ const baseName = normalizeWindowsDeviceBaseName(filePath);
29035
+ if (WINDOWS_RESERVED_DEVICE_NAMES.has(baseName)) {
29036
+ return { path: normalized, reason: "windows-device" };
29037
+ }
29038
+ return undefined;
29039
+ }
29040
+ function matchUnsafeDeviceReadPath(filePath, options = {}) {
29041
+ const platform = options.platform ?? process.platform;
29042
+ for (const candidate of candidateReadPaths(filePath)) {
29043
+ const match = platform === "win32"
29044
+ ? matchWindowsDeviceReadPath(candidate)
29045
+ : matchPosixDeviceReadPath(candidate, options.cwd);
29046
+ if (match) {
29047
+ return match;
29048
+ }
29049
+ }
29050
+ return undefined;
29051
+ }
29052
+ function isUnsafeDeviceReadPath(filePath, options) {
29053
+ return matchUnsafeDeviceReadPath(filePath, options) !== undefined;
29054
+ }
29055
+ function assertNoUnsafeDeviceReadPath(filePath, options) {
29056
+ if (matchUnsafeDeviceReadPath(filePath, options)) {
29057
+ throw new errors_FsSafeError("device-path", `file reads from unsafe device paths are not allowed: ${filePath}`);
29058
+ }
29059
+ }
29060
+
28843
29061
  ;// CONCATENATED MODULE: ../../node_modules/@openclaw/fs-safe/dist/read-opened-file.js
28844
29062
 
28845
29063
  async function read_opened_file_readOpenedFileSafely(params) {
@@ -29191,6 +29409,7 @@ async function serializePathWrite(key, run) {
29191
29409
 
29192
29410
 
29193
29411
 
29412
+
29194
29413
 
29195
29414
 
29196
29415
  function logWarn(message) {
@@ -29216,20 +29435,16 @@ const OPEN_APPEND_CREATE_FLAGS = external_node_fs_.constants.O_RDWR |
29216
29435
  external_node_fs_.constants.O_EXCL |
29217
29436
  (SUPPORTS_NOFOLLOW ? external_node_fs_.constants.O_NOFOLLOW : 0);
29218
29437
  const DEFAULT_ROOT_MAX_BYTES = 16 * 1024 * 1024;
29219
- function closeHandleForDispose(handle) {
29220
- return handle.close().catch(() => undefined);
29221
- }
29222
29438
  function openResult(params) {
29223
29439
  return {
29224
29440
  handle: params.handle,
29225
29441
  realPath: params.realPath,
29226
29442
  stat: params.stat,
29227
- [Symbol.asyncDispose]: async () => {
29228
- await closeHandleForDispose(params.handle);
29229
- },
29443
+ [Symbol.asyncDispose]: () => params.handle.close().catch(() => undefined),
29230
29444
  };
29231
29445
  }
29232
29446
  async function openVerifiedLocalFile(filePath, options) {
29447
+ assertNoUnsafeDeviceReadPath(filePath);
29233
29448
  const fsSafeTestHooks = getFsSafeTestHooks();
29234
29449
  // Reject directories before opening so we never surface EISDIR to callers (e.g. tool
29235
29450
  // results that get sent to messaging channels). See openclaw/openclaw#31186.
@@ -29754,9 +29969,7 @@ async function openWritableFileInRoot(root, params) {
29754
29969
  createdForWrite,
29755
29970
  realPath,
29756
29971
  stat,
29757
- [Symbol.asyncDispose]: async () => {
29758
- await closeHandleForDispose(handle);
29759
- },
29972
+ [Symbol.asyncDispose]: () => handle.close().catch(() => undefined),
29760
29973
  };
29761
29974
  }
29762
29975
  catch (err) {
@@ -29793,10 +30006,15 @@ async function appendFileInRoot(root, params) {
29793
30006
  }
29794
30007
  if (typeof params.data === "string") {
29795
30008
  await target.handle.appendFile(`${prefix}${params.data}`, params.encoding ?? "utf8");
29796
- return;
29797
30009
  }
29798
- const payload = prefix.length > 0 ? Buffer.concat([Buffer.from(prefix, "utf8"), params.data]) : params.data;
29799
- await target.handle.appendFile(payload);
30010
+ else {
30011
+ const payload = prefix.length > 0 ? Buffer.concat([Buffer.from(prefix, "utf8"), params.data]) : params.data;
30012
+ await target.handle.appendFile(payload);
30013
+ }
30014
+ await target.handle.sync();
30015
+ if (target.createdForWrite) {
30016
+ await syncDirectoryBestEffort(external_node_path_.dirname(target.realPath));
30017
+ }
29800
30018
  }
29801
30019
  finally {
29802
30020
  await target.handle.close().catch(() => { });
@@ -29853,42 +30071,45 @@ async function writeFileInRoot(root, params) {
29853
30071
  }
29854
30072
  const pinned = await resolvePinnedWriteTargetInRoot(root, params.relativePath, params.mode, params.denyMutations);
29855
30073
  await serializePathWrite(pinned.targetPath, async () => {
29856
- let identity;
29857
- try {
29858
- identity = await runPinnedWriteHelper({
29859
- rootPath: pinned.rootReal,
29860
- relativeParentPath: pinned.relativeParentPath,
29861
- basename: pinned.basename,
29862
- mkdir: params.mkdir !== false,
29863
- mode: params.mode ?? pinned.mode,
29864
- overwrite: params.overwrite,
29865
- input: {
29866
- kind: "buffer",
29867
- data: params.data,
29868
- encoding: params.encoding,
29869
- },
29870
- });
29871
- }
29872
- catch (error) {
29873
- if (params.overwrite === false && isAlreadyExistsError(error)) {
29874
- throw new errors_FsSafeError("already-exists", "file already exists", {
29875
- cause: error instanceof Error ? error : undefined,
29876
- });
29877
- }
29878
- throw normalizePinnedWriteError(error);
29879
- }
29880
- try {
29881
- await verifyAtomicWriteResult({
29882
- root,
29883
- targetPath: pinned.targetPath,
29884
- expectedIdentity: identity,
30074
+ await commitPinnedWriteInRoot(root, pinned, params);
30075
+ });
30076
+ }
30077
+ async function commitPinnedWriteInRoot(root, pinned, params) {
30078
+ let identity;
30079
+ try {
30080
+ identity = await runPinnedWriteHelper({
30081
+ rootPath: pinned.rootReal,
30082
+ relativeParentPath: pinned.relativeParentPath,
30083
+ basename: pinned.basename,
30084
+ mkdir: params.mkdir !== false,
30085
+ mode: params.mode ?? pinned.mode,
30086
+ overwrite: params.overwrite,
30087
+ input: {
30088
+ kind: "buffer",
30089
+ data: params.data,
30090
+ encoding: params.encoding,
30091
+ },
30092
+ });
30093
+ }
30094
+ catch (error) {
30095
+ if (params.overwrite === false && isAlreadyExistsError(error)) {
30096
+ throw new errors_FsSafeError("already-exists", "file already exists", {
30097
+ cause: error instanceof Error ? error : undefined,
29885
30098
  });
29886
30099
  }
29887
- catch (err) {
29888
- emitWriteBoundaryWarning(`post-write verification failed: ${String(err)}`);
29889
- throw err;
29890
- }
29891
- });
30100
+ throw normalizePinnedWriteError(error);
30101
+ }
30102
+ try {
30103
+ await verifyAtomicWriteResult({
30104
+ root,
30105
+ targetPath: pinned.targetPath,
30106
+ expectedIdentity: identity,
30107
+ });
30108
+ }
30109
+ catch (err) {
30110
+ emitWriteBoundaryWarning(`post-write verification failed: ${String(err)}`);
30111
+ throw err;
30112
+ }
29892
30113
  }
29893
30114
  async function copyFileInRoot(root, params) {
29894
30115
  assertValidRootRelativePath(params.relativePath);
@@ -30972,8 +31193,6 @@ const pathe_M_eThtNZ_path = (/* unused pure expression or super */ null && ({
30972
31193
 
30973
31194
  // EXTERNAL MODULE: ../../node_modules/dotenv/lib/main.js
30974
31195
  var lib_main = __webpack_require__(5599);
30975
- // EXTERNAL MODULE: external "node:url"
30976
- var external_node_url_ = __webpack_require__(3136);
30977
31196
  // EXTERNAL MODULE: external "node:assert"
30978
31197
  var external_node_assert_ = __webpack_require__(4589);
30979
31198
  // EXTERNAL MODULE: external "node:v8"
@@ -68370,4 +68589,4 @@ if (installedChunkData !== 0) { // 0 means "already installed".'
68370
68589
  // module factories are used so entry inlining is disabled
68371
68590
  // startup
68372
68591
  // Load entry module and return exports
68373
- var __webpack_exports__ = __webpack_require__(2229);
68592
+ var __webpack_exports__ = __webpack_require__(8705);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lousy-agents/mcp",
3
- "version": "5.15.3",
3
+ "version": "5.15.5",
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": {