@wonderwhy-er/desktop-commander 0.2.9 → 0.2.11

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/setup.log ADDED
@@ -0,0 +1,63 @@
1
+ 2025-08-21T08:55:05.547Z - ✅ Desktop Commander MCP v0.2.9 successfully added to Claude’s configuration.
2
+ 2025-08-21T08:55:05.547Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
3
+ 2025-08-21T08:55:08.757Z -
4
+ ✅ Claude has been restarted automatically!
5
+ 2025-08-21T08:55:08.778Z -
6
+ ✅ Installation successfully completed! Thank you for using Desktop Commander!
7
+
8
+ 2025-08-21T08:55:08.779Z -
9
+ The server is available as "desktop-commander" in Claude's MCP server list
10
+ 2025-08-21T08:55:08.779Z - Future updates will install automatically — no need to run this setup again.
11
+
12
+
13
+ 2025-08-21T08:55:08.779Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
14
+
15
+
16
+ 2025-08-21T08:55:08.779Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
17
+
18
+
19
+ 2025-08-21T08:55:08.779Z - or join our community: https://discord.com/invite/kQ27sNnZr7
20
+
21
+
22
+ 2025-08-21T14:58:41.568Z - ✅ Desktop Commander MCP v0.2.9 successfully added to Claude’s configuration.
23
+ 2025-08-21T14:58:41.568Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
24
+ 2025-08-21T14:58:44.701Z -
25
+ ✅ Claude has been restarted automatically!
26
+ 2025-08-21T14:58:44.728Z -
27
+ ✅ Installation successfully completed! Thank you for using Desktop Commander!
28
+
29
+ 2025-08-21T14:58:44.728Z -
30
+ The server is available as "desktop-commander" in Claude's MCP server list
31
+ 2025-08-21T14:58:44.728Z - Future updates will install automatically — no need to run this setup again.
32
+
33
+
34
+ 2025-08-21T14:58:44.728Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
35
+
36
+
37
+ 2025-08-21T14:58:44.728Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
38
+
39
+
40
+ 2025-08-21T14:58:44.728Z - or join our community: https://discord.com/invite/kQ27sNnZr7
41
+
42
+
43
+ 2025-08-21T15:01:40.796Z - ✅ Desktop Commander MCP v0.2.9 successfully added to Claude’s configuration.
44
+ 2025-08-21T15:01:40.796Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
45
+ 2025-08-21T15:01:43.911Z -
46
+ ✅ Claude has been restarted automatically!
47
+ 2025-08-21T15:01:43.932Z -
48
+ ✅ Installation successfully completed! Thank you for using Desktop Commander!
49
+
50
+ 2025-08-21T15:01:43.932Z -
51
+ The server is available as "desktop-commander" in Claude's MCP server list
52
+ 2025-08-21T15:01:43.932Z - Future updates will install automatically — no need to run this setup again.
53
+
54
+
55
+ 2025-08-21T15:01:43.932Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
56
+
57
+
58
+ 2025-08-21T15:01:43.932Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
59
+
60
+
61
+ 2025-08-21T15:01:43.932Z - or join our community: https://discord.com/invite/kQ27sNnZr7
62
+
63
+
@@ -768,6 +768,63 @@ export async function moveFile(sourcePath, destinationPath) {
768
768
  await fs.rename(validSourcePath, validDestPath);
769
769
  }
770
770
  export async function searchFiles(rootPath, pattern) {
771
+ // Use the new search manager for better performance
772
+ // This provides a temporary compatibility layer until we fully migrate to search sessions
773
+ const { searchManager } = await import('../search-manager.js');
774
+ try {
775
+ const result = await searchManager.startSearch({
776
+ rootPath,
777
+ pattern,
778
+ searchType: 'files',
779
+ ignoreCase: true,
780
+ maxResults: 5000, // Higher limit for compatibility
781
+ earlyTermination: true, // Use early termination for better performance
782
+ });
783
+ const sessionId = result.sessionId;
784
+ // Poll for results until complete
785
+ let allResults = [];
786
+ let isComplete = result.isComplete;
787
+ let startTime = Date.now();
788
+ // Add initial results
789
+ for (const searchResult of result.results) {
790
+ if (searchResult.type === 'file') {
791
+ allResults.push(searchResult.file);
792
+ }
793
+ }
794
+ while (!isComplete) {
795
+ await new Promise(resolve => setTimeout(resolve, 100)); // Wait 100ms
796
+ const results = searchManager.readSearchResults(sessionId);
797
+ isComplete = results.isComplete;
798
+ // Add new file paths to results
799
+ for (const searchResult of results.results) {
800
+ if (searchResult.file !== '__LAST_READ_MARKER__' && searchResult.type === 'file') {
801
+ allResults.push(searchResult.file);
802
+ }
803
+ }
804
+ // Safety check to prevent infinite loops (30 second timeout)
805
+ if (Date.now() - startTime > 30000) {
806
+ searchManager.terminateSearch(sessionId);
807
+ break;
808
+ }
809
+ }
810
+ // Log only the count of found files, not their paths
811
+ capture('server_search_files_complete', {
812
+ resultsCount: allResults.length,
813
+ patternLength: pattern.length,
814
+ usedRipgrep: true
815
+ });
816
+ return allResults;
817
+ }
818
+ catch (error) {
819
+ // Fallback to original Node.js implementation if ripgrep fails
820
+ capture('server_search_files_ripgrep_fallback', {
821
+ error: error instanceof Error ? error.message : 'Unknown error'
822
+ });
823
+ return await searchFilesNodeJS(rootPath, pattern);
824
+ }
825
+ }
826
+ // Keep the original Node.js implementation as fallback
827
+ async function searchFilesNodeJS(rootPath, pattern) {
771
828
  const results = [];
772
829
  async function search(currentPath) {
773
830
  let entries;
@@ -800,7 +857,8 @@ export async function searchFiles(rootPath, pattern) {
800
857
  // Log only the count of found files, not their paths
801
858
  capture('server_search_files_complete', {
802
859
  resultsCount: results.length,
803
- patternLength: pattern.length
860
+ patternLength: pattern.length,
861
+ usedRipgrep: false
804
862
  });
805
863
  return results;
806
864
  }
@@ -109,19 +109,6 @@ export declare const MoveFileArgsSchema: z.ZodObject<{
109
109
  source: string;
110
110
  destination: string;
111
111
  }>;
112
- export declare const SearchFilesArgsSchema: z.ZodObject<{
113
- path: z.ZodString;
114
- pattern: z.ZodString;
115
- timeoutMs: z.ZodOptional<z.ZodNumber>;
116
- }, "strip", z.ZodTypeAny, {
117
- path: string;
118
- pattern: string;
119
- timeoutMs?: number | undefined;
120
- }, {
121
- path: string;
122
- pattern: string;
123
- timeoutMs?: number | undefined;
124
- }>;
125
112
  export declare const GetFileInfoArgsSchema: z.ZodObject<{
126
113
  path: z.ZodString;
127
114
  }, "strip", z.ZodTypeAny, {
@@ -129,34 +116,6 @@ export declare const GetFileInfoArgsSchema: z.ZodObject<{
129
116
  }, {
130
117
  path: string;
131
118
  }>;
132
- export declare const SearchCodeArgsSchema: z.ZodObject<{
133
- path: z.ZodString;
134
- pattern: z.ZodString;
135
- filePattern: z.ZodOptional<z.ZodString>;
136
- ignoreCase: z.ZodOptional<z.ZodBoolean>;
137
- maxResults: z.ZodOptional<z.ZodNumber>;
138
- includeHidden: z.ZodOptional<z.ZodBoolean>;
139
- contextLines: z.ZodOptional<z.ZodNumber>;
140
- timeoutMs: z.ZodOptional<z.ZodNumber>;
141
- }, "strip", z.ZodTypeAny, {
142
- path: string;
143
- pattern: string;
144
- timeoutMs?: number | undefined;
145
- filePattern?: string | undefined;
146
- ignoreCase?: boolean | undefined;
147
- maxResults?: number | undefined;
148
- includeHidden?: boolean | undefined;
149
- contextLines?: number | undefined;
150
- }, {
151
- path: string;
152
- pattern: string;
153
- timeoutMs?: number | undefined;
154
- filePattern?: string | undefined;
155
- ignoreCase?: boolean | undefined;
156
- maxResults?: number | undefined;
157
- includeHidden?: boolean | undefined;
158
- contextLines?: number | undefined;
159
- }>;
160
119
  export declare const EditBlockArgsSchema: z.ZodObject<{
161
120
  file_path: z.ZodString;
162
121
  old_string: z.ZodString;
@@ -191,3 +150,58 @@ export declare const InteractWithProcessArgsSchema: z.ZodObject<{
191
150
  }>;
192
151
  export declare const GetUsageStatsArgsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
193
152
  export declare const GiveFeedbackArgsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
153
+ export declare const StartSearchArgsSchema: z.ZodObject<{
154
+ path: z.ZodString;
155
+ pattern: z.ZodString;
156
+ searchType: z.ZodDefault<z.ZodEnum<["files", "content"]>>;
157
+ filePattern: z.ZodOptional<z.ZodString>;
158
+ ignoreCase: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
159
+ maxResults: z.ZodOptional<z.ZodNumber>;
160
+ includeHidden: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
161
+ contextLines: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
162
+ timeout_ms: z.ZodOptional<z.ZodNumber>;
163
+ earlyTermination: z.ZodOptional<z.ZodBoolean>;
164
+ }, "strip", z.ZodTypeAny, {
165
+ path: string;
166
+ pattern: string;
167
+ searchType: "content" | "files";
168
+ ignoreCase: boolean;
169
+ includeHidden: boolean;
170
+ contextLines: number;
171
+ timeout_ms?: number | undefined;
172
+ filePattern?: string | undefined;
173
+ maxResults?: number | undefined;
174
+ earlyTermination?: boolean | undefined;
175
+ }, {
176
+ path: string;
177
+ pattern: string;
178
+ timeout_ms?: number | undefined;
179
+ searchType?: "content" | "files" | undefined;
180
+ filePattern?: string | undefined;
181
+ ignoreCase?: boolean | undefined;
182
+ maxResults?: number | undefined;
183
+ includeHidden?: boolean | undefined;
184
+ contextLines?: number | undefined;
185
+ earlyTermination?: boolean | undefined;
186
+ }>;
187
+ export declare const GetMoreSearchResultsArgsSchema: z.ZodObject<{
188
+ sessionId: z.ZodString;
189
+ offset: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
190
+ length: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
191
+ }, "strip", z.ZodTypeAny, {
192
+ length: number;
193
+ offset: number;
194
+ sessionId: string;
195
+ }, {
196
+ sessionId: string;
197
+ length?: number | undefined;
198
+ offset?: number | undefined;
199
+ }>;
200
+ export declare const StopSearchArgsSchema: z.ZodObject<{
201
+ sessionId: z.ZodString;
202
+ }, "strip", z.ZodTypeAny, {
203
+ sessionId: string;
204
+ }, {
205
+ sessionId: string;
206
+ }>;
207
+ export declare const ListSearchesArgsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
@@ -49,25 +49,9 @@ export const MoveFileArgsSchema = z.object({
49
49
  source: z.string(),
50
50
  destination: z.string(),
51
51
  });
52
- export const SearchFilesArgsSchema = z.object({
53
- path: z.string(),
54
- pattern: z.string(),
55
- timeoutMs: z.number().optional(),
56
- });
57
52
  export const GetFileInfoArgsSchema = z.object({
58
53
  path: z.string(),
59
54
  });
60
- // Search tools schema
61
- export const SearchCodeArgsSchema = z.object({
62
- path: z.string(),
63
- pattern: z.string(),
64
- filePattern: z.string().optional(),
65
- ignoreCase: z.boolean().optional(),
66
- maxResults: z.number().optional(),
67
- includeHidden: z.boolean().optional(),
68
- contextLines: z.number().optional(),
69
- timeoutMs: z.number().optional(),
70
- });
71
55
  // Edit tools schema
72
56
  export const EditBlockArgsSchema = z.object({
73
57
  file_path: z.string(),
@@ -93,3 +77,25 @@ export const GiveFeedbackArgsSchema = z.object({
93
77
  // - platform (auto)
94
78
  // - client_id (auto)
95
79
  });
80
+ // Search schemas (renamed for natural language)
81
+ export const StartSearchArgsSchema = z.object({
82
+ path: z.string(),
83
+ pattern: z.string(),
84
+ searchType: z.enum(['files', 'content']).default('files'),
85
+ filePattern: z.string().optional(),
86
+ ignoreCase: z.boolean().optional().default(true),
87
+ maxResults: z.number().optional(),
88
+ includeHidden: z.boolean().optional().default(false),
89
+ contextLines: z.number().optional().default(5),
90
+ timeout_ms: z.number().optional(), // Match process naming convention
91
+ earlyTermination: z.boolean().optional(), // Stop search early when exact filename match is found (default: true for files, false for content)
92
+ });
93
+ export const GetMoreSearchResultsArgsSchema = z.object({
94
+ sessionId: z.string(),
95
+ offset: z.number().optional().default(0), // Same as file reading
96
+ length: z.number().optional().default(100), // Same as file reading (but smaller default)
97
+ });
98
+ export const StopSearchArgsSchema = z.object({
99
+ sessionId: z.string(),
100
+ });
101
+ export const ListSearchesArgsSchema = z.object({});
@@ -27,7 +27,15 @@ export async function searchCode(options) {
27
27
  args.push('-C', contextLines.toString());
28
28
  }
29
29
  if (filePattern) {
30
- args.push('-g', filePattern);
30
+ const patterns = filePattern
31
+ .split('|')
32
+ .map(p => p.trim()) // remove surrounding spaces
33
+ .filter(Boolean); // drop empty tokens
34
+ // If all patterns were empty, return no results
35
+ if (patterns.length === 0) {
36
+ return [];
37
+ }
38
+ patterns.forEach(p => args.push('-g', p));
31
39
  }
32
40
  // Add pattern and path
33
41
  args.push(pattern, validPath);
@@ -97,7 +105,21 @@ export async function searchCodeFallback(options) {
97
105
  const validPath = await validatePath(rootPath);
98
106
  const results = [];
99
107
  const regex = new RegExp(pattern, ignoreCase ? 'i' : '');
100
- const fileRegex = filePattern ? new RegExp(filePattern) : null;
108
+ // Handle filePattern similarly to main implementation
109
+ let fileRegex = null;
110
+ if (filePattern) {
111
+ const patterns = filePattern
112
+ .split('|')
113
+ .map(p => p.trim())
114
+ .filter(Boolean);
115
+ // If all patterns were empty, return no results
116
+ if (patterns.length === 0) {
117
+ return [];
118
+ }
119
+ // Create a regex that matches any of the patterns
120
+ const combinedPattern = patterns.map(p => p.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.')).join('|');
121
+ fileRegex = new RegExp(`^(${combinedPattern})$`);
122
+ }
101
123
  async function searchDir(dirPath) {
102
124
  if (results.length >= maxResults)
103
125
  return;
@@ -163,12 +185,18 @@ export async function searchCodeFallback(options) {
163
185
  // Main function that tries ripgrep first, falls back to native implementation
164
186
  export async function searchTextInFiles(options) {
165
187
  try {
188
+ // For better performance and consistency, prefer the search session manager
189
+ // when doing content search, but keep the original direct ripgrep approach as primary
166
190
  return await searchCode(options);
167
191
  }
168
192
  catch (error) {
193
+ capture('searchTextInFiles_ripgrep_fallback', {
194
+ error: error instanceof Error ? error.message : 'Unknown error'
195
+ });
196
+ // Use consistent exclusions - remove 'dist' to match ripgrep behavior
169
197
  return searchCodeFallback({
170
198
  ...options,
171
- excludeDirs: ['node_modules', '.git', 'dist']
199
+ excludeDirs: ['node_modules', '.git']
172
200
  });
173
201
  }
174
202
  }