@wonderwhy-er/desktop-commander 0.1.27 → 0.1.28
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 +41 -1
- package/dist/index.js +1 -0
- package/dist/server.js +136 -61
- package/dist/setup-claude-server.js +85 -25
- package/dist/tools/filesystem.js +8 -3
- package/dist/utils.js +17 -9
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Desktop Commander MCP
|
|
2
|
+
### Search, update, manage files and run terminal commands with AI
|
|
2
3
|
|
|
3
4
|
[](https://www.npmjs.com/package/@wonderwhy-er/desktop-commander)
|
|
4
5
|
[](https://smithery.ai/server/@wonderwhy-er/desktop-commander)
|
|
@@ -8,8 +9,8 @@
|
|
|
8
9
|
|
|
9
10
|
Short version. Two key things. Terminal commands and diff based file editing.
|
|
10
11
|
|
|
11
|
-

|
|
12
12
|
|
|
13
|
+

|
|
13
14
|
<a href="https://glama.ai/mcp/servers/zempur9oh4">
|
|
14
15
|
<img width="380" height="200" src="https://glama.ai/mcp/servers/zempur9oh4/badge" alt="Claude Desktop Commander MCP server" />
|
|
15
16
|
</a>
|
|
@@ -55,6 +56,11 @@ Just run this in terminal
|
|
|
55
56
|
```
|
|
56
57
|
npx @wonderwhy-er/desktop-commander@latest setup
|
|
57
58
|
```
|
|
59
|
+
|
|
60
|
+
For debugging mode (allows Node.js inspector connection):
|
|
61
|
+
```
|
|
62
|
+
npx @wonderwhy-er/desktop-commander@latest setup --debug
|
|
63
|
+
```
|
|
58
64
|
Restart Claude if running
|
|
59
65
|
|
|
60
66
|
### Option 2: Installing via Smithery
|
|
@@ -156,6 +162,40 @@ For commands that may take a while:
|
|
|
156
162
|
3. Use `read_output` with PID to get new output
|
|
157
163
|
4. Use `force_terminate` to stop if needed
|
|
158
164
|
|
|
165
|
+
## Debugging
|
|
166
|
+
|
|
167
|
+
If you need to debug the server, you can install it in debug mode:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Using npx
|
|
171
|
+
npx @wonderwhy-er/desktop-commander@latest setup --debug
|
|
172
|
+
|
|
173
|
+
# Or if installed locally
|
|
174
|
+
npm run setup:debug
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
This will:
|
|
178
|
+
1. Configure Claude to use a separate "desktop-commander" server
|
|
179
|
+
2. Enable Node.js inspector protocol with `--inspect-brk=9229` flag
|
|
180
|
+
3. Pause execution at the start until a debugger connects
|
|
181
|
+
4. Enable additional debugging environment variables
|
|
182
|
+
|
|
183
|
+
To connect a debugger:
|
|
184
|
+
- In Chrome, visit `chrome://inspect` and look for the Node.js instance
|
|
185
|
+
- In VS Code, use the "Attach to Node Process" debug configuration
|
|
186
|
+
- Other IDEs/tools may have similar "attach" options for Node.js debugging
|
|
187
|
+
|
|
188
|
+
Important debugging notes:
|
|
189
|
+
- The server will pause on startup until a debugger connects (due to the `--inspect-brk` flag)
|
|
190
|
+
- If you don't see activity during debugging, ensure you're connected to the correct Node.js process
|
|
191
|
+
- Multiple Node processes may be running; connect to the one on port 9229
|
|
192
|
+
- The debug server is identified as "desktop-commander-debug" in Claude's MCP server list
|
|
193
|
+
|
|
194
|
+
Troubleshooting:
|
|
195
|
+
- If Claude times out while trying to use the debug server, your debugger might not be properly connected
|
|
196
|
+
- When properly connected, the process will continue execution after hitting the first breakpoint
|
|
197
|
+
- You can add additional breakpoints in your IDE once connected
|
|
198
|
+
|
|
159
199
|
## Model Context Protocol Integration
|
|
160
200
|
|
|
161
201
|
This project extends the MCP Filesystem Server to enable:
|
package/dist/index.js
CHANGED
|
@@ -80,6 +80,7 @@ async function runServer() {
|
|
|
80
80
|
process.stderr.write(`[desktop-commander] Unhandled rejection: ${errorMessage}\n`);
|
|
81
81
|
process.exit(1);
|
|
82
82
|
});
|
|
83
|
+
capture('run_server_start');
|
|
83
84
|
// Load blocked commands from config file
|
|
84
85
|
await commandManager.loadBlockedCommands();
|
|
85
86
|
await server.connect(transport);
|
package/dist/server.js
CHANGED
|
@@ -179,9 +179,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
179
179
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
180
180
|
try {
|
|
181
181
|
const { name, arguments: args } = request.params;
|
|
182
|
+
capture('server_call_tool');
|
|
182
183
|
switch (name) {
|
|
183
184
|
// Terminal tools
|
|
184
185
|
case "execute_command": {
|
|
186
|
+
capture('server_execute_command');
|
|
185
187
|
const parsed = ExecuteCommandArgsSchema.parse(args);
|
|
186
188
|
return executeCommand(parsed);
|
|
187
189
|
}
|
|
@@ -232,9 +234,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
232
234
|
// Filesystem tools
|
|
233
235
|
case "edit_block": {
|
|
234
236
|
capture('server_edit_block');
|
|
235
|
-
const parsed = EditBlockArgsSchema.parse(args);
|
|
236
|
-
const { filePath, searchReplace } = await parseEditBlock(parsed.blockContent);
|
|
237
237
|
try {
|
|
238
|
+
const parsed = EditBlockArgsSchema.parse(args);
|
|
239
|
+
const { filePath, searchReplace } = await parseEditBlock(parsed.blockContent);
|
|
238
240
|
await performSearchReplace(filePath, searchReplace);
|
|
239
241
|
return {
|
|
240
242
|
content: [{ type: "text", text: `Successfully applied edit to ${filePath}` }],
|
|
@@ -243,81 +245,146 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
243
245
|
catch (error) {
|
|
244
246
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
245
247
|
return {
|
|
246
|
-
content: [{ type: "text", text: errorMessage }],
|
|
248
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
247
249
|
};
|
|
248
250
|
}
|
|
249
251
|
}
|
|
250
252
|
case "read_file": {
|
|
251
253
|
capture('server_read_file');
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
try {
|
|
255
|
+
const parsed = ReadFileArgsSchema.parse(args);
|
|
256
|
+
const content = await readFile(parsed.path);
|
|
257
|
+
return {
|
|
258
|
+
content: [{ type: "text", text: content }],
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
263
|
+
return {
|
|
264
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
265
|
+
};
|
|
266
|
+
}
|
|
257
267
|
}
|
|
258
268
|
case "read_multiple_files": {
|
|
259
269
|
capture('server_read_multiple_files');
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
270
|
+
try {
|
|
271
|
+
const parsed = ReadMultipleFilesArgsSchema.parse(args);
|
|
272
|
+
const results = await readMultipleFiles(parsed.paths);
|
|
273
|
+
return {
|
|
274
|
+
content: [{ type: "text", text: results.join("\n---\n") }],
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
279
|
+
return {
|
|
280
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
281
|
+
};
|
|
282
|
+
}
|
|
265
283
|
}
|
|
266
284
|
case "write_file": {
|
|
267
285
|
capture('server_write_file');
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
286
|
+
try {
|
|
287
|
+
const parsed = WriteFileArgsSchema.parse(args);
|
|
288
|
+
await writeFile(parsed.path, parsed.content);
|
|
289
|
+
return {
|
|
290
|
+
content: [{ type: "text", text: `Successfully wrote to ${parsed.path}` }],
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
295
|
+
return {
|
|
296
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
297
|
+
};
|
|
298
|
+
}
|
|
273
299
|
}
|
|
274
300
|
case "create_directory": {
|
|
275
301
|
capture('server_create_directory');
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
302
|
+
try {
|
|
303
|
+
const parsed = CreateDirectoryArgsSchema.parse(args);
|
|
304
|
+
await createDirectory(parsed.path);
|
|
305
|
+
return {
|
|
306
|
+
content: [{ type: "text", text: `Successfully created directory ${parsed.path}` }],
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
311
|
+
return {
|
|
312
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
313
|
+
};
|
|
314
|
+
}
|
|
281
315
|
}
|
|
282
316
|
case "list_directory": {
|
|
283
317
|
capture('server_list_directory');
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
318
|
+
try {
|
|
319
|
+
const parsed = ListDirectoryArgsSchema.parse(args);
|
|
320
|
+
const entries = await listDirectory(parsed.path);
|
|
321
|
+
return {
|
|
322
|
+
content: [{ type: "text", text: entries.join('\n') }],
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
327
|
+
return {
|
|
328
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
329
|
+
};
|
|
330
|
+
}
|
|
289
331
|
}
|
|
290
332
|
case "move_file": {
|
|
291
333
|
capture('server_move_file');
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
334
|
+
try {
|
|
335
|
+
const parsed = MoveFileArgsSchema.parse(args);
|
|
336
|
+
await moveFile(parsed.source, parsed.destination);
|
|
337
|
+
return {
|
|
338
|
+
content: [{ type: "text", text: `Successfully moved ${parsed.source} to ${parsed.destination}` }],
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
343
|
+
return {
|
|
344
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
345
|
+
};
|
|
346
|
+
}
|
|
297
347
|
}
|
|
298
348
|
case "search_files": {
|
|
299
349
|
capture('server_search_files');
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
350
|
+
try {
|
|
351
|
+
const parsed = SearchFilesArgsSchema.parse(args);
|
|
352
|
+
const results = await searchFiles(parsed.path, parsed.pattern);
|
|
353
|
+
return {
|
|
354
|
+
content: [{ type: "text", text: results.length > 0 ? results.join('\n') : "No matches found" }],
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
359
|
+
return {
|
|
360
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
361
|
+
};
|
|
362
|
+
}
|
|
305
363
|
}
|
|
306
364
|
case "search_code": {
|
|
307
365
|
capture('server_search_code');
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
366
|
+
let results = [];
|
|
367
|
+
try {
|
|
368
|
+
const parsed = SearchCodeArgsSchema.parse(args);
|
|
369
|
+
results = await searchTextInFiles({
|
|
370
|
+
rootPath: parsed.path,
|
|
371
|
+
pattern: parsed.pattern,
|
|
372
|
+
filePattern: parsed.filePattern,
|
|
373
|
+
ignoreCase: parsed.ignoreCase,
|
|
374
|
+
maxResults: parsed.maxResults,
|
|
375
|
+
includeHidden: parsed.includeHidden,
|
|
376
|
+
contextLines: parsed.contextLines,
|
|
377
|
+
});
|
|
378
|
+
if (results.length === 0) {
|
|
379
|
+
return {
|
|
380
|
+
content: [{ type: "text", text: "No matches found" }],
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
319
386
|
return {
|
|
320
|
-
content: [{ type: "text", text:
|
|
387
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
321
388
|
};
|
|
322
389
|
}
|
|
323
390
|
// Format the results in a VS Code-like format
|
|
@@ -336,20 +403,28 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
336
403
|
}
|
|
337
404
|
case "get_file_info": {
|
|
338
405
|
capture('server_get_file_info');
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
.
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
406
|
+
try {
|
|
407
|
+
const parsed = GetFileInfoArgsSchema.parse(args);
|
|
408
|
+
const info = await getFileInfo(parsed.path);
|
|
409
|
+
return {
|
|
410
|
+
content: [{
|
|
411
|
+
type: "text",
|
|
412
|
+
text: Object.entries(info)
|
|
413
|
+
.map(([key, value]) => `${key}: ${value}`)
|
|
414
|
+
.join('\n')
|
|
415
|
+
}],
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
420
|
+
return {
|
|
421
|
+
content: [{ type: "text", text: `Error: ${errorMessage}` }],
|
|
422
|
+
};
|
|
423
|
+
}
|
|
349
424
|
}
|
|
350
425
|
case "list_allowed_directories": {
|
|
351
|
-
const directories = listAllowedDirectories();
|
|
352
426
|
capture('server_list_allowed_directories');
|
|
427
|
+
const directories = listAllowedDirectories();
|
|
353
428
|
return {
|
|
354
429
|
content: [{
|
|
355
430
|
type: "text",
|
|
@@ -239,15 +239,16 @@ async function restartClaude() {
|
|
|
239
239
|
}
|
|
240
240
|
} catch {}
|
|
241
241
|
await new Promise((resolve) => setTimeout(resolve, 3000))
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
242
|
+
try {
|
|
243
|
+
if (platform === "win32") {
|
|
244
|
+
// it will never start claude
|
|
245
|
+
// await execAsync(`start "" "Claude.exe"`)
|
|
246
|
+
} else if (platform === "darwin") {
|
|
247
|
+
await execAsync(`open -a "Claude"`)
|
|
248
|
+
} else if (platform === "linux") {
|
|
249
|
+
await execAsync(`claude`)
|
|
250
|
+
}
|
|
251
|
+
} catch{}
|
|
251
252
|
|
|
252
253
|
logToFile(`Claude has been restarted.`)
|
|
253
254
|
} catch (error) {
|
|
@@ -287,8 +288,17 @@ if (!existsSync(claudeConfigPath)) {
|
|
|
287
288
|
logToFile('Default config file created. Please update it with your Claude API credentials.');
|
|
288
289
|
}
|
|
289
290
|
|
|
291
|
+
// Function to check for debug mode argument
|
|
292
|
+
function isDebugMode() {
|
|
293
|
+
return process.argv.includes('--debug');
|
|
294
|
+
}
|
|
295
|
+
|
|
290
296
|
// Main function to export for ESM compatibility
|
|
291
297
|
export default async function setup() {
|
|
298
|
+
const debugMode = isDebugMode();
|
|
299
|
+
if (debugMode) {
|
|
300
|
+
logToFile('Debug mode enabled. Will configure with Node.js inspector options.');
|
|
301
|
+
}
|
|
292
302
|
try {
|
|
293
303
|
// Read existing config
|
|
294
304
|
const configData = readFileSync(claudeConfigPath, 'utf8');
|
|
@@ -300,22 +310,67 @@ export default async function setup() {
|
|
|
300
310
|
|
|
301
311
|
// Fix Windows path handling for npx execution
|
|
302
312
|
let serverConfig;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
313
|
+
|
|
314
|
+
if (debugMode) {
|
|
315
|
+
// Use Node.js with inspector flag for debugging
|
|
316
|
+
if (isNpx) {
|
|
317
|
+
// Debug with npx
|
|
318
|
+
logToFile('Setting up debug configuration with npx. The process will pause on start until a debugger connects.');
|
|
319
|
+
// Add environment variables to help with debugging
|
|
320
|
+
const debugEnv = {
|
|
321
|
+
"NODE_OPTIONS": "--trace-warnings --trace-exit",
|
|
322
|
+
"DEBUG": "*"
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
serverConfig = {
|
|
326
|
+
"command": isWindows ? "node.exe" : "node",
|
|
327
|
+
"args": [
|
|
328
|
+
"--inspect-brk=9229",
|
|
329
|
+
isWindows ?
|
|
330
|
+
join(process.env.APPDATA || '', "npm", "npx.cmd").replace(/\\/g, '\\\\') :
|
|
331
|
+
"$(which npx)",
|
|
332
|
+
"@wonderwhy-er/desktop-commander"
|
|
333
|
+
],
|
|
334
|
+
"env": debugEnv
|
|
335
|
+
};
|
|
336
|
+
} else {
|
|
337
|
+
// Debug with local installation path
|
|
338
|
+
const indexPath = join(__dirname, 'dist', 'index.js');
|
|
339
|
+
logToFile('Setting up debug configuration with local path. The process will pause on start until a debugger connects.');
|
|
340
|
+
// Add environment variables to help with debugging
|
|
341
|
+
const debugEnv = {
|
|
342
|
+
"NODE_OPTIONS": "--trace-warnings --trace-exit",
|
|
343
|
+
"DEBUG": "*"
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
serverConfig = {
|
|
347
|
+
"command": isWindows ? "node.exe" : "node",
|
|
348
|
+
"args": [
|
|
349
|
+
"--inspect-brk=9229",
|
|
350
|
+
indexPath.replace(/\\/g, '\\\\') // Double escape backslashes for JSON
|
|
351
|
+
],
|
|
352
|
+
"env": debugEnv
|
|
353
|
+
};
|
|
354
|
+
}
|
|
310
355
|
} else {
|
|
311
|
-
//
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
356
|
+
// Standard configuration without debug
|
|
357
|
+
if (isNpx) {
|
|
358
|
+
serverConfig = {
|
|
359
|
+
"command": isWindows ? "npx.cmd" : "npx",
|
|
360
|
+
"args": [
|
|
361
|
+
"@wonderwhy-er/desktop-commander"
|
|
362
|
+
]
|
|
363
|
+
};
|
|
364
|
+
} else {
|
|
365
|
+
// For local installation, use absolute path to handle Windows properly
|
|
366
|
+
const indexPath = join(__dirname, 'dist', 'index.js');
|
|
367
|
+
serverConfig = {
|
|
368
|
+
"command": "node",
|
|
369
|
+
"args": [
|
|
370
|
+
indexPath.replace(/\\/g, '\\\\') // Double escape backslashes for JSON
|
|
371
|
+
]
|
|
372
|
+
};
|
|
373
|
+
}
|
|
319
374
|
}
|
|
320
375
|
|
|
321
376
|
// Initialize mcpServers if it doesn't exist
|
|
@@ -337,7 +392,12 @@ export default async function setup() {
|
|
|
337
392
|
await trackEvent('npx_setup_update_config');
|
|
338
393
|
logToFile('Successfully added MCP server to Claude configuration!');
|
|
339
394
|
logToFile(`Configuration location: ${claudeConfigPath}`);
|
|
340
|
-
|
|
395
|
+
|
|
396
|
+
if (debugMode) {
|
|
397
|
+
logToFile('\nTo use the debug server:\n1. Restart Claude if it\'s currently running\n2. The server will be available as "desktop-commander-debug" in Claude\'s MCP server list\n3. Connect your debugger to port 9229');
|
|
398
|
+
} else {
|
|
399
|
+
logToFile('\nTo use the server:\n1. Restart Claude if it\'s currently running\n2. The server will be available as "desktop-commander" in Claude\'s MCP server list');
|
|
400
|
+
}
|
|
341
401
|
|
|
342
402
|
await restartClaude();
|
|
343
403
|
|
package/dist/tools/filesystem.js
CHANGED
|
@@ -27,17 +27,21 @@ function expandHome(filepath) {
|
|
|
27
27
|
export async function validatePath(requestedPath) {
|
|
28
28
|
// Temporarily allow all paths by just returning the resolved path
|
|
29
29
|
// TODO: Implement configurable path validation
|
|
30
|
+
// Expand home directory if present
|
|
30
31
|
const expandedPath = expandHome(requestedPath);
|
|
32
|
+
// Convert to absolute path
|
|
31
33
|
const absolute = path.isAbsolute(expandedPath)
|
|
32
34
|
? path.resolve(expandedPath)
|
|
33
35
|
: path.resolve(process.cwd(), expandedPath);
|
|
34
|
-
//
|
|
36
|
+
// Check if path exists
|
|
35
37
|
try {
|
|
38
|
+
const stats = await fs.stat(absolute);
|
|
39
|
+
// If path exists, resolve any symlinks
|
|
36
40
|
return await fs.realpath(absolute);
|
|
37
41
|
}
|
|
38
42
|
catch (error) {
|
|
39
|
-
//
|
|
40
|
-
|
|
43
|
+
// Path doesn't exist, throw an error
|
|
44
|
+
throw new Error(`Path does not exist: ${absolute}`);
|
|
41
45
|
}
|
|
42
46
|
/* Original implementation commented out for future reference
|
|
43
47
|
const expandedPath = expandHome(requestedPath);
|
|
@@ -135,6 +139,7 @@ export async function searchFiles(rootPath, pattern) {
|
|
|
135
139
|
}
|
|
136
140
|
}
|
|
137
141
|
}
|
|
142
|
+
// if path not exist, it will throw an error
|
|
138
143
|
const validPath = await validatePath(rootPath);
|
|
139
144
|
await search(validPath);
|
|
140
145
|
return results;
|
package/dist/utils.js
CHANGED
|
@@ -6,16 +6,24 @@ let posthog = null;
|
|
|
6
6
|
// Try to load PostHog without breaking if it's not available
|
|
7
7
|
try {
|
|
8
8
|
// Dynamic imports to prevent crashing if dependencies aren't available
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
import('posthog-node').then((posthogModule) => {
|
|
10
|
+
const PostHog = posthogModule.PostHog;
|
|
11
|
+
import('node-machine-id').then((machineIdModule) => {
|
|
12
|
+
// Access the default export from the module
|
|
13
|
+
uniqueUserId = machineIdModule.default.machineIdSync();
|
|
14
|
+
if (isTrackingEnabled) {
|
|
15
|
+
posthog = new PostHog('phc_TFQqTkCwtFGxlwkXDY3gSs7uvJJcJu8GurfXd6mV063', {
|
|
16
|
+
host: 'https://eu.i.posthog.com',
|
|
17
|
+
flushAt: 3, // send all every time
|
|
18
|
+
flushInterval: 5 // send always
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}).catch(() => {
|
|
22
|
+
// Silently fail - we don't want analytics issues to break functionality
|
|
17
23
|
});
|
|
18
|
-
}
|
|
24
|
+
}).catch(() => {
|
|
25
|
+
// Silently fail - we don't want analytics issues to break functionality
|
|
26
|
+
});
|
|
19
27
|
}
|
|
20
28
|
catch (error) {
|
|
21
29
|
//console.log('Analytics module not available - continuing without tracking');
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.1.
|
|
1
|
+
export declare const VERSION = "0.1.28";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.1.
|
|
1
|
+
export const VERSION = '0.1.28';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wonderwhy-er/desktop-commander",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"description": "MCP server for terminal operations and file editing",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Eduards Ruzga",
|
|
@@ -27,7 +27,9 @@
|
|
|
27
27
|
"build": "tsc && shx cp setup-claude-server.js dist/ && shx chmod +x dist/*.js",
|
|
28
28
|
"watch": "tsc --watch",
|
|
29
29
|
"start": "node dist/index.js",
|
|
30
|
+
"start:debug": "node --inspect-brk=9229 dist/index.js",
|
|
30
31
|
"setup": "npm install && npm run build && node setup-claude-server.js",
|
|
32
|
+
"setup:debug": "npm install && npm run build && node setup-claude-server.js --debug",
|
|
31
33
|
"prepare": "npm run build",
|
|
32
34
|
"test": "node test/test.js",
|
|
33
35
|
"test:watch": "nodemon test/test.js",
|