@j0hanz/filesystem-mcp 1.5.2 → 1.5.3

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.
@@ -2,4 +2,5 @@ import { type Ignore } from 'ignore';
2
2
  export declare function loadRootGitignore(root: string, signal?: AbortSignal): Promise<Ignore | null>;
3
3
  export declare function isIgnoredByGitignore(matcher: Ignore, root: string, absolutePath: string, options?: {
4
4
  isDirectory?: boolean;
5
+ relativePath?: string;
5
6
  }): boolean;
@@ -33,7 +33,8 @@ export async function loadRootGitignore(root, signal) {
33
33
  return matcher;
34
34
  }
35
35
  export function isIgnoredByGitignore(matcher, root, absolutePath, options = {}) {
36
- const relative = path.relative(root, absolutePath);
36
+ let relative = options.relativePath;
37
+ relative ??= path.relative(root, absolutePath);
37
38
  if (relative.length === 0)
38
39
  return false;
39
40
  const normalized = toPosixPath(relative);
@@ -7,6 +7,7 @@ interface DirentLike {
7
7
  export declare function resolveEntryType(dirent: DirentLike): 'file' | 'directory' | 'symlink' | 'other';
8
8
  interface GlobEntry {
9
9
  path: string;
10
+ relativePath?: string;
10
11
  dirent: DirentLike;
11
12
  stats?: Stats;
12
13
  }
@@ -15,7 +15,7 @@ export function resolveEntryType(dirent) {
15
15
  }
16
16
  const GLOB_MAGIC_RE = /[*?[\]{}!]/u;
17
17
  const DEFAULT_MAX_HIDDEN_DEPTH = 10;
18
- const GLOB_BATCH_CONCURRENCY = 32;
18
+ const GLOB_BATCH_CONCURRENCY = 64;
19
19
  const SEP = '/';
20
20
  const DOT_CHAR_CODE = 46;
21
21
  const GLOB_BOOLEAN_OPTION_KEYS = [
@@ -221,6 +221,9 @@ async function resolveStringMatch(match, cwd, maxDepth, seen, onlyFiles, followS
221
221
  if (onlyFiles && !stats.isFile())
222
222
  return null;
223
223
  const entry = { path: absolutePath, dirent: stats };
224
+ if (!path.isAbsolute(match)) {
225
+ entry.relativePath = match;
226
+ }
224
227
  if (returnStats)
225
228
  entry.stats = stats;
226
229
  return entry;
@@ -115,7 +115,7 @@ async function collectFromStream(stream, root, rootDirectories, gitignoreMatcher
115
115
  break;
116
116
  state.filesScanned++;
117
117
  reportSearchFilesProgress(onProgress, state.filesScanned, normalized.maxFilesScanned);
118
- if (isEntryIgnoredByGitignore(gitignoreMatcher, root, entry.path)) {
118
+ if (isEntryIgnoredByGitignore(gitignoreMatcher, root, entry.path, entry.relativePath)) {
119
119
  continue;
120
120
  }
121
121
  const entryType = resolveEntryType(entry.dirent);
@@ -133,10 +133,10 @@ async function collectFromStream(stream, root, rootDirectories, gitignoreMatcher
133
133
  }
134
134
  reportSearchFilesProgress(onProgress, state.filesScanned, normalized.maxFilesScanned, true);
135
135
  }
136
- function isEntryIgnoredByGitignore(matcher, root, entryPath) {
136
+ function isEntryIgnoredByGitignore(matcher, root, entryPath, relativePath) {
137
137
  if (!matcher)
138
138
  return false;
139
- return isIgnoredByGitignore(matcher, root, entryPath);
139
+ return isIgnoredByGitignore(matcher, root, entryPath, relativePath ? { relativePath } : {});
140
140
  }
141
141
  async function isEntryAccessible(entry, entryType, rootDirectories, signal) {
142
142
  if (entryType === 'symlink') {
@@ -9,6 +9,7 @@ const HOMEDIR = os.homedir();
9
9
  const PATH_SEPARATOR = path.sep;
10
10
  const DRIVE_LETTER_REGEX = /^[A-Za-z]:/;
11
11
  const WINDOWS_DRIVE_REL_REGEX = /^[A-Za-z]:$/u;
12
+ const LEADING_SEPARATORS_RE = /^[/\\]+/;
12
13
  const RESERVED_DEVICE_NAMES = new Set([
13
14
  'CON',
14
15
  'PRN',
@@ -42,7 +43,7 @@ function expandHome(filepath) {
42
43
  // Accept both "~/" and "~\\" for cross-platform UX.
43
44
  if (filepath.startsWith('~/') || filepath.startsWith('~\\')) {
44
45
  // Avoid `path.join(HOMEDIR, "/foo")` resetting to the filesystem root.
45
- const rest = filepath.slice(2).replace(/^[/\\]+/, '');
46
+ const rest = filepath.slice(2).replace(LEADING_SEPARATORS_RE, '');
46
47
  return rest.length === 0 ? HOMEDIR : path.join(HOMEDIR, rest);
47
48
  }
48
49
  return filepath;
@@ -70,7 +71,11 @@ function rethrowIfAborted(error) {
70
71
  function isSamePath(left, right) {
71
72
  if (left === right)
72
73
  return true;
73
- return normalizeForComparison(left) === normalizeForComparison(right);
74
+ const leftResolved = path.resolve(left);
75
+ const rightResolved = path.resolve(right);
76
+ return IS_WINDOWS
77
+ ? leftResolved.toLowerCase() === rightResolved.toLowerCase()
78
+ : leftResolved === rightResolved;
74
79
  }
75
80
  function stripTrailingSeparator(normalized) {
76
81
  return normalized.length > 1 && normalized.endsWith(PATH_SEPARATOR)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@j0hanz/filesystem-mcp",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "mcpName": "io.github.j0hanz/filesystem-mcp",
5
5
  "description": "MCP Server that enables LLMs to interact with the local filesystem.",
6
6
  "type": "module",