@wonderwhy-er/desktop-commander 0.2.10 → 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/README.md +17 -5
- package/dist/custom-stdio.d.ts +14 -0
- package/dist/custom-stdio.js +140 -13
- package/dist/handlers/edit-search-handlers.d.ts +0 -5
- package/dist/handlers/edit-search-handlers.js +0 -82
- package/dist/handlers/filesystem-handlers.d.ts +0 -4
- package/dist/handlers/filesystem-handlers.js +2 -36
- package/dist/handlers/index.d.ts +1 -0
- package/dist/handlers/index.js +1 -0
- package/dist/handlers/search-handlers.d.ts +17 -0
- package/dist/handlers/search-handlers.js +219 -0
- package/dist/index.js +43 -24
- package/dist/search-manager.d.ts +107 -0
- package/dist/search-manager.js +467 -0
- package/dist/server.js +99 -31
- package/dist/tools/filesystem.js +59 -1
- package/dist/tools/schemas.d.ts +55 -41
- package/dist/tools/schemas.js +22 -16
- package/dist/tools/search.js +31 -3
- package/dist/utils/capture.js +56 -8
- package/dist/utils/dedent.d.ts +8 -0
- package/dist/utils/dedent.js +38 -0
- package/dist/utils/logger.d.ts +32 -0
- package/dist/utils/logger.js +72 -0
- package/dist/utils/system-info.d.ts +8 -2
- package/dist/utils/system-info.js +247 -30
- package/dist/utils/usageTracker.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
### Search, update, manage files and run terminal commands with AI
|
|
3
3
|
|
|
4
4
|
[](https://www.npmjs.com/package/@wonderwhy-er/desktop-commander)
|
|
5
|
+
[](https://archestra.ai/mcp-catalog/wonderwhy-er__desktopcommandermcp)
|
|
5
6
|
[](https://smithery.ai/server/@wonderwhy-er/desktop-commander)
|
|
6
7
|
[](https://www.buymeacoffee.com/wonderwhyer)
|
|
7
8
|
|
|
@@ -130,7 +131,7 @@ Add this entry to your claude_desktop_config.json:
|
|
|
130
131
|
"command": "npx",
|
|
131
132
|
"args": [
|
|
132
133
|
"-y",
|
|
133
|
-
"@wonderwhy-er/desktop-commander"
|
|
134
|
+
"@wonderwhy-er/desktop-commander@latest"
|
|
134
135
|
]
|
|
135
136
|
}
|
|
136
137
|
}
|
|
@@ -400,8 +401,10 @@ The server provides a comprehensive set of tools organized into several categori
|
|
|
400
401
|
| | `create_directory` | Create a new directory or ensure it exists |
|
|
401
402
|
| | `list_directory` | Get detailed listing of files and directories |
|
|
402
403
|
| | `move_file` | Move or rename files and directories |
|
|
403
|
-
| | `
|
|
404
|
-
| | `
|
|
404
|
+
| | `start_search` | Start streaming search for files by name or content patterns (unified ripgrep-based search) |
|
|
405
|
+
| | `get_more_search_results` | Get paginated results from active search with offset support |
|
|
406
|
+
| | `stop_search` | Stop an active search gracefully |
|
|
407
|
+
| | `list_searches` | List all active search sessions |
|
|
405
408
|
| | `get_file_info` | Retrieve detailed metadata about a file or directory |
|
|
406
409
|
| **Text Editing** | `edit_block` | Apply targeted text replacements with enhanced prompting for smaller edits (includes character-level diff feedback) |
|
|
407
410
|
| **Analytics** | `get_usage_stats` | Get usage statistics for your own insight |
|
|
@@ -564,9 +567,15 @@ For commands that may take a while:
|
|
|
564
567
|
|
|
565
568
|
### ⚠️ Important Security Warnings
|
|
566
569
|
|
|
567
|
-
|
|
570
|
+
> **For comprehensive security information and vulnerability reporting**: See [SECURITY.md](SECURITY.md)
|
|
568
571
|
|
|
569
|
-
|
|
572
|
+
1. **Known security limitations**: Directory restrictions and command blocking can be bypassed through various methods including symlinks, command substitution, and absolute paths or code execution
|
|
573
|
+
|
|
574
|
+
2. **Always change configuration in a separate chat window** from where you're doing your actual work. Claude may sometimes attempt to modify configuration settings (like `allowedDirectories`) if it encounters filesystem access restrictions.
|
|
575
|
+
|
|
576
|
+
3. **The `allowedDirectories` setting currently only restricts filesystem operations**, not terminal commands. Terminal commands can still access files outside allowed directories.
|
|
577
|
+
|
|
578
|
+
4. **For production security**: Use the [Docker installation](#option-6-docker-installation-🐳-⭐-auto-updates-no-nodejs-required) which provides complete isolation from your host system.
|
|
570
579
|
|
|
571
580
|
### Configuration Tools
|
|
572
581
|
|
|
@@ -853,6 +862,9 @@ Yes, when installed through npx or Smithery, Desktop Commander automatically upd
|
|
|
853
862
|
### I'm having trouble installing or using the tool. Where can I get help?
|
|
854
863
|
Join our [Discord server](https://discord.gg/kQ27sNnZr7) for community support, check the [GitHub issues](https://github.com/wonderwhy-er/DesktopCommanderMCP/issues) for known problems, or review the [full FAQ](FAQ.md) for troubleshooting tips. You can also visit our [website FAQ section](https://desktopcommander.app#faq) for a more user-friendly experience. If you encounter a new issue, please consider [opening a GitHub issue](https://github.com/wonderwhy-er/DesktopCommanderMCP/issues/new) with details about your problem.
|
|
855
864
|
|
|
865
|
+
### How do I report security vulnerabilities?
|
|
866
|
+
Please create a [GitHub Issue](https://github.com/wonderwhy-er/DesktopCommanderMCP/issues) with detailed information about any security vulnerabilities you discover. See our [Security Policy](SECURITY.md) for complete guidelines on responsible disclosure.
|
|
867
|
+
|
|
856
868
|
## Data Collection & Privacy
|
|
857
869
|
|
|
858
870
|
Desktop Commander collects limited anonymous telemetry data to help improve the tool. No personal information, file contents, file paths, or command arguments are collected.
|
package/dist/custom-stdio.d.ts
CHANGED
|
@@ -6,7 +6,21 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
6
6
|
export declare class FilteredStdioServerTransport extends StdioServerTransport {
|
|
7
7
|
private originalConsole;
|
|
8
8
|
private originalStdoutWrite;
|
|
9
|
+
private isInitialized;
|
|
10
|
+
private messageBuffer;
|
|
9
11
|
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* Call this method after MCP initialization is complete to enable JSON-RPC notifications
|
|
14
|
+
*/
|
|
15
|
+
enableNotifications(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Check if notifications are enabled
|
|
18
|
+
*/
|
|
19
|
+
get isNotificationsEnabled(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Get the current count of buffered messages
|
|
22
|
+
*/
|
|
23
|
+
get bufferedMessageCount(): number;
|
|
10
24
|
private setupConsoleRedirection;
|
|
11
25
|
private setupStdoutFiltering;
|
|
12
26
|
private sendLogNotification;
|
package/dist/custom-stdio.js
CHANGED
|
@@ -7,6 +7,8 @@ import process from "node:process";
|
|
|
7
7
|
export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
8
8
|
constructor() {
|
|
9
9
|
super();
|
|
10
|
+
this.isInitialized = false;
|
|
11
|
+
this.messageBuffer = [];
|
|
10
12
|
// Store original methods
|
|
11
13
|
this.originalConsole = {
|
|
12
14
|
log: console.log,
|
|
@@ -20,24 +22,100 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
20
22
|
this.setupConsoleRedirection();
|
|
21
23
|
// Setup stdout filtering for any other output
|
|
22
24
|
this.setupStdoutFiltering();
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
+
// Send initialization notification
|
|
26
|
+
this.sendLogNotification('info', ['Enhanced FilteredStdioServerTransport initialized']);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Call this method after MCP initialization is complete to enable JSON-RPC notifications
|
|
30
|
+
*/
|
|
31
|
+
enableNotifications() {
|
|
32
|
+
this.isInitialized = true;
|
|
33
|
+
// Replay all buffered messages in chronological order
|
|
34
|
+
if (this.messageBuffer.length > 0) {
|
|
35
|
+
this.sendLogNotification('info', [`Replaying ${this.messageBuffer.length} buffered initialization messages`]);
|
|
36
|
+
this.messageBuffer
|
|
37
|
+
.sort((a, b) => a.timestamp - b.timestamp)
|
|
38
|
+
.forEach(msg => {
|
|
39
|
+
this.sendLogNotification(msg.level, msg.args);
|
|
40
|
+
});
|
|
41
|
+
// Clear the buffer
|
|
42
|
+
this.messageBuffer = [];
|
|
43
|
+
}
|
|
44
|
+
this.sendLogNotification('info', ['JSON-RPC notifications enabled']);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if notifications are enabled
|
|
48
|
+
*/
|
|
49
|
+
get isNotificationsEnabled() {
|
|
50
|
+
return this.isInitialized;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get the current count of buffered messages
|
|
54
|
+
*/
|
|
55
|
+
get bufferedMessageCount() {
|
|
56
|
+
return this.messageBuffer.length;
|
|
25
57
|
}
|
|
26
58
|
setupConsoleRedirection() {
|
|
27
59
|
console.log = (...args) => {
|
|
28
|
-
this.
|
|
60
|
+
if (this.isInitialized) {
|
|
61
|
+
this.sendLogNotification("info", args);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Buffer for later replay to client
|
|
65
|
+
this.messageBuffer.push({
|
|
66
|
+
level: "info",
|
|
67
|
+
args,
|
|
68
|
+
timestamp: Date.now()
|
|
69
|
+
});
|
|
70
|
+
}
|
|
29
71
|
};
|
|
30
72
|
console.info = (...args) => {
|
|
31
|
-
this.
|
|
73
|
+
if (this.isInitialized) {
|
|
74
|
+
this.sendLogNotification("info", args);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.messageBuffer.push({
|
|
78
|
+
level: "info",
|
|
79
|
+
args,
|
|
80
|
+
timestamp: Date.now()
|
|
81
|
+
});
|
|
82
|
+
}
|
|
32
83
|
};
|
|
33
84
|
console.warn = (...args) => {
|
|
34
|
-
this.
|
|
85
|
+
if (this.isInitialized) {
|
|
86
|
+
this.sendLogNotification("warning", args);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.messageBuffer.push({
|
|
90
|
+
level: "warning",
|
|
91
|
+
args,
|
|
92
|
+
timestamp: Date.now()
|
|
93
|
+
});
|
|
94
|
+
}
|
|
35
95
|
};
|
|
36
96
|
console.error = (...args) => {
|
|
37
|
-
this.
|
|
97
|
+
if (this.isInitialized) {
|
|
98
|
+
this.sendLogNotification("error", args);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.messageBuffer.push({
|
|
102
|
+
level: "error",
|
|
103
|
+
args,
|
|
104
|
+
timestamp: Date.now()
|
|
105
|
+
});
|
|
106
|
+
}
|
|
38
107
|
};
|
|
39
108
|
console.debug = (...args) => {
|
|
40
|
-
this.
|
|
109
|
+
if (this.isInitialized) {
|
|
110
|
+
this.sendLogNotification("debug", args);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.messageBuffer.push({
|
|
114
|
+
level: "debug",
|
|
115
|
+
args,
|
|
116
|
+
timestamp: Date.now()
|
|
117
|
+
});
|
|
118
|
+
}
|
|
41
119
|
};
|
|
42
120
|
}
|
|
43
121
|
setupStdoutFiltering() {
|
|
@@ -54,7 +132,17 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
54
132
|
}
|
|
55
133
|
else if (trimmed.length > 0) {
|
|
56
134
|
// Non-JSON-RPC output, wrap it in a log notification
|
|
57
|
-
this.
|
|
135
|
+
if (this.isInitialized) {
|
|
136
|
+
this.sendLogNotification("info", [buffer.replace(/\n$/, '')]);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
// Buffer for later replay to client
|
|
140
|
+
this.messageBuffer.push({
|
|
141
|
+
level: "info",
|
|
142
|
+
args: [buffer.replace(/\n$/, '')],
|
|
143
|
+
timestamp: Date.now()
|
|
144
|
+
});
|
|
145
|
+
}
|
|
58
146
|
if (callback)
|
|
59
147
|
callback();
|
|
60
148
|
return true;
|
|
@@ -99,8 +187,17 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
99
187
|
this.originalStdoutWrite.call(process.stdout, JSON.stringify(notification) + '\n');
|
|
100
188
|
}
|
|
101
189
|
catch (error) {
|
|
102
|
-
// Fallback to
|
|
103
|
-
|
|
190
|
+
// Fallback to a simple JSON-RPC error notification if JSON serialization fails
|
|
191
|
+
const fallbackNotification = {
|
|
192
|
+
jsonrpc: "2.0",
|
|
193
|
+
method: "notifications/message",
|
|
194
|
+
params: {
|
|
195
|
+
level: "error",
|
|
196
|
+
logger: "desktop-commander",
|
|
197
|
+
data: `Log serialization failed: ${args.join(' ')}`
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
this.originalStdoutWrite.call(process.stdout, JSON.stringify(fallbackNotification) + '\n');
|
|
104
201
|
}
|
|
105
202
|
}
|
|
106
203
|
/**
|
|
@@ -120,7 +217,17 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
120
217
|
this.originalStdoutWrite.call(process.stdout, JSON.stringify(notification) + '\n');
|
|
121
218
|
}
|
|
122
219
|
catch (error) {
|
|
123
|
-
|
|
220
|
+
// Fallback to basic JSON-RPC notification
|
|
221
|
+
const fallbackNotification = {
|
|
222
|
+
jsonrpc: "2.0",
|
|
223
|
+
method: "notifications/message",
|
|
224
|
+
params: {
|
|
225
|
+
level: "error",
|
|
226
|
+
logger: "desktop-commander",
|
|
227
|
+
data: `sendLog failed: ${message}`
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
this.originalStdoutWrite.call(process.stdout, JSON.stringify(fallbackNotification) + '\n');
|
|
124
231
|
}
|
|
125
232
|
}
|
|
126
233
|
/**
|
|
@@ -140,7 +247,17 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
140
247
|
this.originalStdoutWrite.call(process.stdout, JSON.stringify(notification) + '\n');
|
|
141
248
|
}
|
|
142
249
|
catch (error) {
|
|
143
|
-
|
|
250
|
+
// Fallback to basic JSON-RPC notification for progress
|
|
251
|
+
const fallbackNotification = {
|
|
252
|
+
jsonrpc: "2.0",
|
|
253
|
+
method: "notifications/message",
|
|
254
|
+
params: {
|
|
255
|
+
level: "info",
|
|
256
|
+
logger: "desktop-commander",
|
|
257
|
+
data: `Progress ${token}: ${value}${total ? `/${total}` : ''}`
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
this.originalStdoutWrite.call(process.stdout, JSON.stringify(fallbackNotification) + '\n');
|
|
144
261
|
}
|
|
145
262
|
}
|
|
146
263
|
/**
|
|
@@ -156,7 +273,17 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
156
273
|
this.originalStdoutWrite.call(process.stdout, JSON.stringify(notification) + '\n');
|
|
157
274
|
}
|
|
158
275
|
catch (error) {
|
|
159
|
-
|
|
276
|
+
// Fallback to basic JSON-RPC notification for custom notifications
|
|
277
|
+
const fallbackNotification = {
|
|
278
|
+
jsonrpc: "2.0",
|
|
279
|
+
method: "notifications/message",
|
|
280
|
+
params: {
|
|
281
|
+
level: "error",
|
|
282
|
+
logger: "desktop-commander",
|
|
283
|
+
data: `Custom notification failed: ${method}: ${JSON.stringify(params)}`
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
this.originalStdoutWrite.call(process.stdout, JSON.stringify(fallbackNotification) + '\n');
|
|
160
287
|
}
|
|
161
288
|
}
|
|
162
289
|
/**
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { handleEditBlock } from '../tools/edit.js';
|
|
2
|
-
import { ServerResult } from '../types.js';
|
|
3
2
|
/**
|
|
4
3
|
* Handle edit_block command
|
|
5
4
|
* Uses the enhanced implementation with multiple occurrence support and fuzzy matching
|
|
6
5
|
*/
|
|
7
6
|
export { handleEditBlock };
|
|
8
|
-
/**
|
|
9
|
-
* Handle search_code command
|
|
10
|
-
*/
|
|
11
|
-
export declare function handleSearchCode(args: unknown): Promise<ServerResult>;
|
|
@@ -1,88 +1,6 @@
|
|
|
1
|
-
import { searchTextInFiles } from '../tools/search.js';
|
|
2
|
-
import { SearchCodeArgsSchema } from '../tools/schemas.js';
|
|
3
1
|
import { handleEditBlock } from '../tools/edit.js';
|
|
4
|
-
import { capture } from '../utils/capture.js';
|
|
5
|
-
import { withTimeout } from '../utils/withTimeout.js';
|
|
6
2
|
/**
|
|
7
3
|
* Handle edit_block command
|
|
8
4
|
* Uses the enhanced implementation with multiple occurrence support and fuzzy matching
|
|
9
5
|
*/
|
|
10
6
|
export { handleEditBlock };
|
|
11
|
-
/**
|
|
12
|
-
* Handle search_code command
|
|
13
|
-
*/
|
|
14
|
-
export async function handleSearchCode(args) {
|
|
15
|
-
const parsed = SearchCodeArgsSchema.parse(args);
|
|
16
|
-
const timeoutMs = parsed.timeoutMs || 30000; // 30 seconds default
|
|
17
|
-
// Limit maxResults to prevent overwhelming responses
|
|
18
|
-
const safeMaxResults = parsed.maxResults ? Math.min(parsed.maxResults, 5000) : 2000; // Default to 2000 instead of 1000
|
|
19
|
-
// Apply timeout at the handler level
|
|
20
|
-
const searchOperation = async () => {
|
|
21
|
-
return await searchTextInFiles({
|
|
22
|
-
rootPath: parsed.path,
|
|
23
|
-
pattern: parsed.pattern,
|
|
24
|
-
filePattern: parsed.filePattern,
|
|
25
|
-
ignoreCase: parsed.ignoreCase,
|
|
26
|
-
maxResults: safeMaxResults,
|
|
27
|
-
includeHidden: parsed.includeHidden,
|
|
28
|
-
contextLines: parsed.contextLines,
|
|
29
|
-
// Don't pass timeoutMs down to the implementation
|
|
30
|
-
});
|
|
31
|
-
};
|
|
32
|
-
// Use withTimeout at the handler level
|
|
33
|
-
const results = await withTimeout(searchOperation(), timeoutMs, 'Code search operation', [] // Empty array as default on timeout
|
|
34
|
-
);
|
|
35
|
-
// If timeout occurred, try to terminate the ripgrep process
|
|
36
|
-
if (results.length === 0 && globalThis.currentSearchProcess) {
|
|
37
|
-
try {
|
|
38
|
-
console.log(`Terminating timed out search process (PID: ${globalThis.currentSearchProcess.pid})`);
|
|
39
|
-
globalThis.currentSearchProcess.kill();
|
|
40
|
-
delete globalThis.currentSearchProcess;
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
capture('server_request_error', {
|
|
44
|
-
error: 'Error terminating search process'
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (results.length === 0) {
|
|
49
|
-
if (timeoutMs > 0) {
|
|
50
|
-
return {
|
|
51
|
-
content: [{ type: "text", text: `No matches found or search timed out after ${timeoutMs}ms.` }],
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
return {
|
|
55
|
-
content: [{ type: "text", text: "No matches found" }],
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
// Format the results in a VS Code-like format with early truncation
|
|
59
|
-
let currentFile = "";
|
|
60
|
-
let formattedResults = "";
|
|
61
|
-
const MAX_RESPONSE_SIZE = 900000; // 900KB limit - well below the 1MB API limit
|
|
62
|
-
let resultsProcessed = 0;
|
|
63
|
-
let totalResults = results.length;
|
|
64
|
-
for (const result of results) {
|
|
65
|
-
// Check if adding this result would exceed our limit
|
|
66
|
-
const newFileHeader = result.file !== currentFile ? `\n${result.file}:\n` : '';
|
|
67
|
-
const newLine = ` ${result.line}: ${result.match}\n`;
|
|
68
|
-
const potentialAddition = newFileHeader + newLine;
|
|
69
|
-
// If adding this would exceed the limit, truncate here
|
|
70
|
-
if (formattedResults.length + potentialAddition.length > MAX_RESPONSE_SIZE) {
|
|
71
|
-
const remainingResults = totalResults - resultsProcessed;
|
|
72
|
-
const avgResultLength = formattedResults.length / Math.max(resultsProcessed, 1);
|
|
73
|
-
const estimatedRemainingChars = remainingResults * avgResultLength;
|
|
74
|
-
const truncationMessage = `\n\n[Results truncated - ${remainingResults} more results available (approximately ${Math.round(estimatedRemainingChars).toLocaleString()} more characters). Try refining your search pattern or using a more specific file pattern to get fewer results.]`;
|
|
75
|
-
formattedResults += truncationMessage;
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
if (result.file !== currentFile) {
|
|
79
|
-
formattedResults += newFileHeader;
|
|
80
|
-
currentFile = result.file;
|
|
81
|
-
}
|
|
82
|
-
formattedResults += newLine;
|
|
83
|
-
resultsProcessed++;
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
content: [{ type: "text", text: formattedResults.trim() }],
|
|
87
|
-
};
|
|
88
|
-
}
|
|
@@ -23,10 +23,6 @@ export declare function handleListDirectory(args: unknown): Promise<ServerResult
|
|
|
23
23
|
* Handle move_file command
|
|
24
24
|
*/
|
|
25
25
|
export declare function handleMoveFile(args: unknown): Promise<ServerResult>;
|
|
26
|
-
/**
|
|
27
|
-
* Handle search_files command
|
|
28
|
-
*/
|
|
29
|
-
export declare function handleSearchFiles(args: unknown): Promise<ServerResult>;
|
|
30
26
|
/**
|
|
31
27
|
* Handle get_file_info command
|
|
32
28
|
*/
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { readFile, readMultipleFiles, writeFile, createDirectory, listDirectory, moveFile,
|
|
1
|
+
import { readFile, readMultipleFiles, writeFile, createDirectory, listDirectory, moveFile, getFileInfo } from '../tools/filesystem.js';
|
|
2
2
|
import { withTimeout } from '../utils/withTimeout.js';
|
|
3
3
|
import { createErrorResponse } from '../error-handlers.js';
|
|
4
4
|
import { configManager } from '../config-manager.js';
|
|
5
|
-
import { ReadFileArgsSchema, ReadMultipleFilesArgsSchema, WriteFileArgsSchema, CreateDirectoryArgsSchema, ListDirectoryArgsSchema, MoveFileArgsSchema,
|
|
5
|
+
import { ReadFileArgsSchema, ReadMultipleFilesArgsSchema, WriteFileArgsSchema, CreateDirectoryArgsSchema, ListDirectoryArgsSchema, MoveFileArgsSchema, GetFileInfoArgsSchema } from '../tools/schemas.js';
|
|
6
6
|
/**
|
|
7
7
|
* Helper function to check if path contains an error
|
|
8
8
|
*/
|
|
@@ -193,40 +193,6 @@ export async function handleMoveFile(args) {
|
|
|
193
193
|
return createErrorResponse(errorMessage);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
-
/**
|
|
197
|
-
* Handle search_files command
|
|
198
|
-
*/
|
|
199
|
-
export async function handleSearchFiles(args) {
|
|
200
|
-
try {
|
|
201
|
-
const parsed = SearchFilesArgsSchema.parse(args);
|
|
202
|
-
const timeoutMs = parsed.timeoutMs || 30000; // 30 seconds default
|
|
203
|
-
// Apply timeout at the handler level
|
|
204
|
-
const searchOperation = async () => {
|
|
205
|
-
return await searchFiles(parsed.path, parsed.pattern);
|
|
206
|
-
};
|
|
207
|
-
// Use withTimeout at the handler level
|
|
208
|
-
const results = await withTimeout(searchOperation(), timeoutMs, 'File search operation', [] // Empty array as default on timeout
|
|
209
|
-
);
|
|
210
|
-
if (results.length === 0) {
|
|
211
|
-
// Similar approach as in handleSearchCode
|
|
212
|
-
if (timeoutMs > 0) {
|
|
213
|
-
return {
|
|
214
|
-
content: [{ type: "text", text: `No matches found or search timed out after ${timeoutMs}ms.` }],
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
return {
|
|
218
|
-
content: [{ type: "text", text: "No matches found" }],
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
return {
|
|
222
|
-
content: [{ type: "text", text: results.join('\n') }],
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
catch (error) {
|
|
226
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
227
|
-
return createErrorResponse(errorMessage);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
196
|
/**
|
|
231
197
|
* Handle get_file_info command
|
|
232
198
|
*/
|
package/dist/handlers/index.d.ts
CHANGED
package/dist/handlers/index.js
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ServerResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Handle start_search command
|
|
4
|
+
*/
|
|
5
|
+
export declare function handleStartSearch(args: unknown): Promise<ServerResult>;
|
|
6
|
+
/**
|
|
7
|
+
* Handle get_more_search_results command
|
|
8
|
+
*/
|
|
9
|
+
export declare function handleGetMoreSearchResults(args: unknown): Promise<ServerResult>;
|
|
10
|
+
/**
|
|
11
|
+
* Handle stop_search command
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleStopSearch(args: unknown): Promise<ServerResult>;
|
|
14
|
+
/**
|
|
15
|
+
* Handle list_searches command
|
|
16
|
+
*/
|
|
17
|
+
export declare function handleListSearches(): Promise<ServerResult>;
|