@wonderwhy-er/desktop-commander 0.2.18-alpha.9 → 0.2.21
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/config-manager.js +9 -1
- package/dist/custom-stdio.d.ts +7 -0
- package/dist/custom-stdio.js +33 -0
- package/dist/server.js +5 -0
- package/dist/setup-claude-server.js +31 -78
- package/dist/setup.log +191 -0
- package/dist/terminal-manager.js +88 -8
- package/dist/test-setup.js +14 -0
- package/dist/utils/feature-flags.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -1
package/dist/config-manager.js
CHANGED
|
@@ -101,7 +101,15 @@ class ConfigManager {
|
|
|
101
101
|
"cipher", // Encrypt/decrypt files or wipe data
|
|
102
102
|
"takeown" // Take ownership of files
|
|
103
103
|
],
|
|
104
|
-
defaultShell:
|
|
104
|
+
defaultShell: (() => {
|
|
105
|
+
if (os.platform() === 'win32') {
|
|
106
|
+
return 'powershell.exe';
|
|
107
|
+
}
|
|
108
|
+
// Use user's actual shell from environment, or fall back to /bin/sh
|
|
109
|
+
const userShell = process.env.SHELL || '/bin/sh';
|
|
110
|
+
// Return just the shell path - we'll handle login shell flag elsewhere
|
|
111
|
+
return userShell;
|
|
112
|
+
})(),
|
|
105
113
|
allowedDirectories: [],
|
|
106
114
|
telemetryEnabled: true, // Default to opt-out approach (telemetry on by default)
|
|
107
115
|
fileWriteLineLimit: 50, // Default line limit for file write operations (changed from 100)
|
package/dist/custom-stdio.d.ts
CHANGED
|
@@ -8,11 +8,18 @@ export declare class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
8
8
|
private originalStdoutWrite;
|
|
9
9
|
private isInitialized;
|
|
10
10
|
private messageBuffer;
|
|
11
|
+
private clientName;
|
|
12
|
+
private disableNotifications;
|
|
11
13
|
constructor();
|
|
12
14
|
/**
|
|
13
15
|
* Call this method after MCP initialization is complete to enable JSON-RPC notifications
|
|
14
16
|
*/
|
|
15
17
|
enableNotifications(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Configure client-specific behavior
|
|
20
|
+
* Call this BEFORE enableNotifications()
|
|
21
|
+
*/
|
|
22
|
+
configureForClient(clientName: string): void;
|
|
16
23
|
/**
|
|
17
24
|
* Check if notifications are enabled
|
|
18
25
|
*/
|
package/dist/custom-stdio.js
CHANGED
|
@@ -9,6 +9,8 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
9
9
|
super();
|
|
10
10
|
this.isInitialized = false;
|
|
11
11
|
this.messageBuffer = [];
|
|
12
|
+
this.clientName = 'unknown';
|
|
13
|
+
this.disableNotifications = false;
|
|
12
14
|
// Store original methods
|
|
13
15
|
this.originalConsole = {
|
|
14
16
|
log: console.log,
|
|
@@ -30,6 +32,15 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
30
32
|
*/
|
|
31
33
|
enableNotifications() {
|
|
32
34
|
this.isInitialized = true;
|
|
35
|
+
// Check if notifications should be disabled based on client
|
|
36
|
+
if (this.disableNotifications) {
|
|
37
|
+
// Clear buffer without sending - just log to stderr instead
|
|
38
|
+
if (this.messageBuffer.length > 0) {
|
|
39
|
+
process.stderr.write(`[INFO] ${this.messageBuffer.length} buffered messages suppressed for ${this.clientName}\n`);
|
|
40
|
+
}
|
|
41
|
+
this.messageBuffer = [];
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
33
44
|
// Send the deferred initialization notification first
|
|
34
45
|
this.sendLogNotification('info', ['Enhanced FilteredStdioServerTransport initialized']);
|
|
35
46
|
// Replay all buffered messages in chronological order
|
|
@@ -45,6 +56,20 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
45
56
|
}
|
|
46
57
|
this.sendLogNotification('info', ['JSON-RPC notifications enabled']);
|
|
47
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Configure client-specific behavior
|
|
61
|
+
* Call this BEFORE enableNotifications()
|
|
62
|
+
*/
|
|
63
|
+
configureForClient(clientName) {
|
|
64
|
+
this.clientName = clientName.toLowerCase();
|
|
65
|
+
// Detect Cline and disable notifications
|
|
66
|
+
if (this.clientName.includes('cline') ||
|
|
67
|
+
this.clientName.includes('vscode') ||
|
|
68
|
+
this.clientName === 'claude-dev') {
|
|
69
|
+
this.disableNotifications = true;
|
|
70
|
+
process.stderr.write(`[INFO] Desktop Commander: Notifications disabled for ${clientName}\n`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
48
73
|
/**
|
|
49
74
|
* Check if notifications are enabled
|
|
50
75
|
*/
|
|
@@ -155,6 +180,10 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
155
180
|
};
|
|
156
181
|
}
|
|
157
182
|
sendLogNotification(level, args) {
|
|
183
|
+
// Skip if notifications are disabled (e.g., for Cline)
|
|
184
|
+
if (this.disableNotifications) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
158
187
|
try {
|
|
159
188
|
// For data, we can send structured data or string according to MCP spec
|
|
160
189
|
let data;
|
|
@@ -206,6 +235,10 @@ export class FilteredStdioServerTransport extends StdioServerTransport {
|
|
|
206
235
|
* Public method to send log notifications from anywhere in the application
|
|
207
236
|
*/
|
|
208
237
|
sendLog(level, message, data) {
|
|
238
|
+
// Skip if notifications are disabled (e.g., for Cline)
|
|
239
|
+
if (this.disableNotifications) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
209
242
|
try {
|
|
210
243
|
const notification = {
|
|
211
244
|
jsonrpc: "2.0",
|
package/dist/server.js
CHANGED
|
@@ -70,6 +70,11 @@ server.setRequestHandler(InitializeRequestSchema, async (request) => {
|
|
|
70
70
|
name: clientInfo.name || 'unknown',
|
|
71
71
|
version: clientInfo.version || 'unknown'
|
|
72
72
|
};
|
|
73
|
+
// Configure transport for client-specific behavior
|
|
74
|
+
const transport = global.mcpTransport;
|
|
75
|
+
if (transport && typeof transport.configureForClient === 'function') {
|
|
76
|
+
transport.configureForClient(currentClient.name);
|
|
77
|
+
}
|
|
73
78
|
// Defer client connection message until after initialization
|
|
74
79
|
deferLog('info', `Client connected: ${currentClient.name} v${currentClient.version}`);
|
|
75
80
|
}
|
|
@@ -207,74 +207,43 @@ function detectShell() {
|
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
// Function to get the package spec that was used to run this script
|
|
210
|
-
function getPackageSpec() {
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
debug(`[DEBUG getPackageSpec] process.argv: ${JSON.stringify(process.argv)}`);
|
|
216
|
-
debug(`[DEBUG getPackageSpec] __dirname: ${__dirname}`);
|
|
217
|
-
debug(`[DEBUG getPackageSpec] __filename: ${__filename}`);
|
|
218
|
-
|
|
219
|
-
// Strategy: Check multiple sources to detect the version
|
|
220
|
-
// 1. Check process.argv[1] which contains the actual script path
|
|
221
|
-
// 2. Check package.json in the script's directory
|
|
222
|
-
// 3. Fall back to @latest for stable, keep version for pre-release
|
|
223
|
-
|
|
224
|
-
// Method 1: Check the script path (process.argv[1] or __dirname)
|
|
225
|
-
// npx extracts packages to: ~/.npm/_npx/<hash>/node_modules/@scope/package-name/
|
|
226
|
-
// The actual script path will contain this structure
|
|
227
|
-
const scriptPath = __dirname;
|
|
228
|
-
debug('[DEBUG getPackageSpec] Checking script path for version...');
|
|
229
|
-
|
|
230
|
-
// Look for node_modules/@wonderwhy-er/desktop-commander in the path
|
|
231
|
-
// This works because npx extracts to a predictable location
|
|
232
|
-
const nodeModulesMatch = scriptPath.match(/node_modules\/@wonderwhy-er\/desktop-commander/);
|
|
233
|
-
if (nodeModulesMatch) {
|
|
234
|
-
debug('[DEBUG getPackageSpec] Script is in node_modules, reading package.json...');
|
|
210
|
+
function getPackageSpec(versionArg = null) {
|
|
211
|
+
// If explicit version/tag argument provided, use it
|
|
212
|
+
// Usage: npx @wonderwhy-er/desktop-commander setup alpha
|
|
213
|
+
if (versionArg) {
|
|
214
|
+
return `@wonderwhy-er/desktop-commander@${versionArg}`;
|
|
235
215
|
}
|
|
236
216
|
|
|
237
|
-
//
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
if (version.includes('alpha') || version.includes('beta') || version.includes('rc')) {
|
|
250
|
-
const spec = `@wonderwhy-er/desktop-commander@${version}`;
|
|
251
|
-
debug(`[DEBUG getPackageSpec] ✓ Using pre-release version: ${spec}`);
|
|
252
|
-
return spec;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// For stable versions, use @latest tag
|
|
256
|
-
debug('[DEBUG getPackageSpec] ✓ Stable version, using @latest');
|
|
257
|
-
return '@wonderwhy-er/desktop-commander@latest';
|
|
217
|
+
// Check if running via npx - look for the package spec in process.argv
|
|
218
|
+
// e.g., npx @wonderwhy-er/desktop-commander@0.2.18-alpha setup
|
|
219
|
+
const argv = process.argv;
|
|
220
|
+
|
|
221
|
+
// Look for the package name in argv
|
|
222
|
+
for (let i = 0; i < argv.length; i++) {
|
|
223
|
+
const arg = argv[i];
|
|
224
|
+
if (arg.includes('@wonderwhy-er/desktop-commander')) {
|
|
225
|
+
// Extract just the package spec (e.g., @wonderwhy-er/desktop-commander@0.2.18-alpha)
|
|
226
|
+
const match = arg.match(/(@wonderwhy-er\/desktop-commander(@[^\/\s]+)?)/);
|
|
227
|
+
if (match) {
|
|
228
|
+
return match[1];
|
|
258
229
|
}
|
|
259
|
-
} else {
|
|
260
|
-
debug('[DEBUG getPackageSpec] ✗ package.json not found');
|
|
261
230
|
}
|
|
262
|
-
} catch (error) {
|
|
263
|
-
debug(`[DEBUG getPackageSpec] ✗ Error reading package.json: ${error.message}`);
|
|
264
231
|
}
|
|
265
232
|
|
|
266
|
-
// Fallback
|
|
267
|
-
debug('[DEBUG getPackageSpec] ⚠ Falling back to @latest');
|
|
233
|
+
// Fallback to @latest if we can't detect
|
|
268
234
|
return '@wonderwhy-er/desktop-commander@latest';
|
|
269
235
|
}
|
|
270
236
|
|
|
237
|
+
function isNPX() {
|
|
238
|
+
return process.env.npm_lifecycle_event === 'npx' ||
|
|
239
|
+
process.env.npm_execpath?.includes('npx') ||
|
|
240
|
+
process.env._?.includes('npx') ||
|
|
241
|
+
import.meta.url.includes('node_modules');
|
|
242
|
+
}
|
|
271
243
|
// Function to determine execution context
|
|
272
244
|
function getExecutionContext() {
|
|
273
245
|
// Check if running from npx
|
|
274
|
-
const isNpx =
|
|
275
|
-
process.env.npm_execpath?.includes('npx') ||
|
|
276
|
-
process.env._?.includes('npx') ||
|
|
277
|
-
import.meta.url.includes('node_modules');
|
|
246
|
+
const isNpx = isNPX();
|
|
278
247
|
|
|
279
248
|
// Check if installed globally
|
|
280
249
|
const isGlobal = process.env.npm_config_global === 'true' ||
|
|
@@ -674,13 +643,9 @@ async function restartClaude() {
|
|
|
674
643
|
|
|
675
644
|
// Main function to export for ESM compatibility
|
|
676
645
|
export default async function setup() {
|
|
677
|
-
//
|
|
678
|
-
process.
|
|
679
|
-
|
|
680
|
-
process.stderr.write(`__filename: ${__filename}\n`);
|
|
681
|
-
process.stderr.write(`process.argv: ${JSON.stringify(process.argv)}\n`);
|
|
682
|
-
process.stderr.write('=============================================\n\n');
|
|
683
|
-
|
|
646
|
+
// Parse command line arguments for version/tag
|
|
647
|
+
const versionArg = process.argv[3]; // argv[0]=node, argv[1]=script, argv[2]=version/tag
|
|
648
|
+
|
|
684
649
|
// Add tracking for setup function entry
|
|
685
650
|
await trackEvent('npx_setup_function_started');
|
|
686
651
|
|
|
@@ -779,9 +744,7 @@ export default async function setup() {
|
|
|
779
744
|
const configPrepStep = addSetupStep('prepare_server_config');
|
|
780
745
|
|
|
781
746
|
// Determine if running through npx or locally
|
|
782
|
-
const isNpx =
|
|
783
|
-
process.stderr.write(`\n[SETUP] import.meta.url: ${import.meta.url}\n`);
|
|
784
|
-
process.stderr.write(`[SETUP] isNpx: ${isNpx}\n`);
|
|
747
|
+
const isNpx = isNPX();
|
|
785
748
|
await trackEvent('npx_setup_execution_mode', { isNpx });
|
|
786
749
|
|
|
787
750
|
// Fix Windows path handling for npx execution
|
|
@@ -799,7 +762,7 @@ export default async function setup() {
|
|
|
799
762
|
"DEBUG": "*"
|
|
800
763
|
};
|
|
801
764
|
|
|
802
|
-
const packageSpec = getPackageSpec();
|
|
765
|
+
const packageSpec = getPackageSpec(versionArg);
|
|
803
766
|
serverConfig = {
|
|
804
767
|
"command": isWindows ? "node.exe" : "node",
|
|
805
768
|
"args": [
|
|
@@ -835,15 +798,13 @@ export default async function setup() {
|
|
|
835
798
|
} else {
|
|
836
799
|
// Standard configuration without debug
|
|
837
800
|
if (isNpx) {
|
|
838
|
-
const packageSpec = getPackageSpec();
|
|
839
|
-
process.stderr.write(`\n[SETUP] Creating config with package spec: ${packageSpec}\n`);
|
|
801
|
+
const packageSpec = getPackageSpec(versionArg);
|
|
840
802
|
serverConfig = {
|
|
841
803
|
"command": isWindows ? "npx.cmd" : "npx",
|
|
842
804
|
"args": [
|
|
843
805
|
packageSpec
|
|
844
806
|
]
|
|
845
807
|
};
|
|
846
|
-
process.stderr.write(`[SETUP] serverConfig.args: ${JSON.stringify(serverConfig.args)}\n`);
|
|
847
808
|
await trackEvent('npx_setup_config_standard_npx', { packageSpec });
|
|
848
809
|
} else {
|
|
849
810
|
// For local installation, use absolute path to handle Windows properly
|
|
@@ -881,16 +842,8 @@ export default async function setup() {
|
|
|
881
842
|
// Add or update the terminal server config with the proper name "desktop-commander"
|
|
882
843
|
config.mcpServers["desktop-commander"] = serverConfig;
|
|
883
844
|
|
|
884
|
-
process.stderr.write('\n[SETUP] Writing config to Claude:\n');
|
|
885
|
-
process.stderr.write(`[SETUP] desktop-commander args: ${JSON.stringify(config.mcpServers["desktop-commander"].args)}\n`);
|
|
886
|
-
|
|
887
845
|
// Write the updated config back
|
|
888
846
|
writeFileSync(claudeConfigPath, JSON.stringify(config, null, 2), 'utf8');
|
|
889
|
-
|
|
890
|
-
// Verify what was written
|
|
891
|
-
const writtenConfig = JSON.parse(readFileSync(claudeConfigPath, 'utf8'));
|
|
892
|
-
process.stderr.write(`[SETUP] Verified written args: ${JSON.stringify(writtenConfig.mcpServers["desktop-commander"].args)}\n\n`);
|
|
893
|
-
|
|
894
847
|
updateSetupStep(updateConfigStep, 'completed');
|
|
895
848
|
await trackEvent('npx_setup_update_config');
|
|
896
849
|
} catch (updateError) {
|
package/dist/setup.log
CHANGED
|
@@ -82,3 +82,194 @@ The server is available as "desktop-commander" in Claude's MCP server list
|
|
|
82
82
|
2025-10-22T15:22:46.665Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
83
83
|
|
|
84
84
|
|
|
85
|
+
2025-10-23T10:10:37.029Z - ✅ Desktop Commander MCP v0.2.18-alpha.13 successfully added to Claude’s configuration.
|
|
86
|
+
2025-10-23T10:10:37.030Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
87
|
+
2025-10-23T10:10:40.163Z -
|
|
88
|
+
✅ Claude has been restarted automatically!
|
|
89
|
+
2025-10-23T10:10:40.184Z -
|
|
90
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
91
|
+
|
|
92
|
+
2025-10-23T10:10:40.184Z -
|
|
93
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
94
|
+
2025-10-23T10:10:40.184Z - Future updates will install automatically — no need to run this setup again.
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
2025-10-23T10:10:40.184Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
2025-10-23T10:10:40.184Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
2025-10-23T10:10:40.184Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
2025-10-23T10:11:28.520Z - ✅ Desktop Commander MCP v0.2.18-alpha.13 successfully added to Claude’s configuration.
|
|
107
|
+
2025-10-23T10:11:28.520Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
108
|
+
2025-10-23T10:11:31.626Z -
|
|
109
|
+
✅ Claude has been restarted automatically!
|
|
110
|
+
2025-10-23T10:11:31.645Z -
|
|
111
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
112
|
+
|
|
113
|
+
2025-10-23T10:11:31.645Z -
|
|
114
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
115
|
+
2025-10-23T10:11:31.645Z - Future updates will install automatically — no need to run this setup again.
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
2025-10-23T10:11:31.645Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
2025-10-23T10:11:31.645Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
2025-10-23T10:11:31.645Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
2025-10-23T10:19:51.580Z - ✅ Desktop Commander MCP v0.2.18-alpha.13 successfully added to Claude’s configuration.
|
|
128
|
+
2025-10-23T10:19:51.580Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
129
|
+
2025-10-23T10:19:54.733Z -
|
|
130
|
+
✅ Claude has been restarted automatically!
|
|
131
|
+
2025-10-23T10:19:54.755Z -
|
|
132
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
133
|
+
|
|
134
|
+
2025-10-23T10:19:54.755Z -
|
|
135
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
136
|
+
2025-10-23T10:19:54.756Z - Future updates will install automatically — no need to run this setup again.
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
2025-10-23T10:19:54.756Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
2025-10-23T10:19:54.756Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
2025-10-23T10:19:54.756Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
2025-10-23T10:20:46.785Z - ✅ Desktop Commander MCP v0.2.18-alpha.13 successfully added to Claude’s configuration.
|
|
149
|
+
2025-10-23T10:20:46.785Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
150
|
+
2025-10-23T10:20:49.891Z -
|
|
151
|
+
✅ Claude has been restarted automatically!
|
|
152
|
+
2025-10-23T10:20:49.913Z -
|
|
153
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
154
|
+
|
|
155
|
+
2025-10-23T10:20:49.913Z -
|
|
156
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
157
|
+
2025-10-23T10:20:49.913Z - Future updates will install automatically — no need to run this setup again.
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
2025-10-23T10:20:49.913Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
2025-10-23T10:20:49.913Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
2025-10-23T10:20:49.913Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
2025-10-23T10:23:37.739Z - ✅ Desktop Commander MCP v0.2.18-alpha.14 successfully added to Claude’s configuration.
|
|
170
|
+
2025-10-23T10:23:37.739Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
171
|
+
2025-10-23T10:23:40.846Z -
|
|
172
|
+
✅ Claude has been restarted automatically!
|
|
173
|
+
2025-10-23T10:23:40.867Z -
|
|
174
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
175
|
+
|
|
176
|
+
2025-10-23T10:23:40.867Z -
|
|
177
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
178
|
+
2025-10-23T10:23:40.867Z - Future updates will install automatically — no need to run this setup again.
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
2025-10-23T10:23:40.867Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
2025-10-23T10:23:40.867Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
2025-10-23T10:23:40.867Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
2025-10-23T10:39:56.359Z - ✅ Desktop Commander MCP v0.2.18-alpha.15 successfully added to Claude’s configuration.
|
|
191
|
+
2025-10-23T10:39:56.360Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
192
|
+
2025-10-23T10:39:59.526Z -
|
|
193
|
+
✅ Claude has been restarted automatically!
|
|
194
|
+
2025-10-23T10:39:59.567Z -
|
|
195
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
196
|
+
|
|
197
|
+
2025-10-23T10:39:59.567Z -
|
|
198
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
199
|
+
2025-10-23T10:39:59.567Z - Future updates will install automatically — no need to run this setup again.
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
2025-10-23T10:39:59.567Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
2025-10-23T10:39:59.567Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
2025-10-23T10:39:59.567Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
2025-10-23T10:57:55.850Z - ✅ Desktop Commander MCP v0.2.18-alpha.15 successfully added to Claude’s configuration.
|
|
212
|
+
2025-10-23T10:57:55.851Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
213
|
+
2025-10-23T10:57:59.008Z -
|
|
214
|
+
✅ Claude has been restarted automatically!
|
|
215
|
+
2025-10-23T10:57:59.051Z -
|
|
216
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
217
|
+
|
|
218
|
+
2025-10-23T10:57:59.052Z -
|
|
219
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
220
|
+
2025-10-23T10:57:59.052Z - Future updates will install automatically — no need to run this setup again.
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
2025-10-23T10:57:59.052Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
2025-10-23T10:57:59.052Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
2025-10-23T10:57:59.052Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
2025-10-23T11:06:27.679Z - ERROR: Command args:
|
|
233
|
+
2025-10-23T11:06:32.852Z - ✅ Desktop Commander MCP v0.2.18-alpha.16 successfully added to Claude’s configuration.
|
|
234
|
+
2025-10-23T11:06:32.852Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
235
|
+
2025-10-23T11:06:36.008Z -
|
|
236
|
+
✅ Claude has been restarted automatically!
|
|
237
|
+
2025-10-23T11:06:36.050Z -
|
|
238
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
239
|
+
|
|
240
|
+
2025-10-23T11:06:36.050Z -
|
|
241
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
242
|
+
2025-10-23T11:06:36.050Z - Future updates will install automatically — no need to run this setup again.
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
2025-10-23T11:06:36.050Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
2025-10-23T11:06:36.050Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
2025-10-23T11:06:36.050Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
2025-10-23T11:17:02.302Z - ERROR: Command args:
|
|
255
|
+
2025-10-23T11:17:02.385Z - ✅ Desktop Commander MCP v0.2.18-alpha.16 successfully added to Claude’s configuration.
|
|
256
|
+
2025-10-23T11:17:02.385Z - Configuration location: /Users/fiberta/Library/Application Support/Claude/claude_desktop_config.json
|
|
257
|
+
2025-10-23T11:17:05.568Z -
|
|
258
|
+
✅ Claude has been restarted automatically!
|
|
259
|
+
2025-10-23T11:17:05.612Z -
|
|
260
|
+
✅ Installation successfully completed! Thank you for using Desktop Commander!
|
|
261
|
+
|
|
262
|
+
2025-10-23T11:17:05.612Z -
|
|
263
|
+
The server is available as "desktop-commander" in Claude's MCP server list
|
|
264
|
+
2025-10-23T11:17:05.612Z - Future updates will install automatically — no need to run this setup again.
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
2025-10-23T11:17:05.612Z - 🤔 Need help or have feedback? Happy to jump on a quick call:
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
2025-10-23T11:17:05.612Z - https://calendar.app.google/SHMNZN5MJznJWC5A7
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
2025-10-23T11:17:05.613Z - or join our community: https://discord.com/invite/kQ27sNnZr7
|
|
274
|
+
|
|
275
|
+
|
package/dist/terminal-manager.js
CHANGED
|
@@ -1,8 +1,63 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
import { DEFAULT_COMMAND_TIMEOUT } from './config.js';
|
|
3
4
|
import { configManager } from './config-manager.js';
|
|
4
5
|
import { capture } from "./utils/capture.js";
|
|
5
6
|
import { analyzeProcessState } from './utils/process-detection.js';
|
|
7
|
+
/**
|
|
8
|
+
* Get the appropriate spawn configuration for a given shell
|
|
9
|
+
* This handles login shell flags for different shell types
|
|
10
|
+
*/
|
|
11
|
+
function getShellSpawnArgs(shellPath, command) {
|
|
12
|
+
const shellName = path.basename(shellPath).toLowerCase();
|
|
13
|
+
// Unix shells with login flag support
|
|
14
|
+
if (shellName.includes('bash') || shellName.includes('zsh')) {
|
|
15
|
+
return {
|
|
16
|
+
executable: shellPath,
|
|
17
|
+
args: ['-l', '-c', command],
|
|
18
|
+
useShellOption: false
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
// PowerShell Core (cross-platform, supports -Login)
|
|
22
|
+
if (shellName === 'pwsh' || shellName === 'pwsh.exe') {
|
|
23
|
+
return {
|
|
24
|
+
executable: shellPath,
|
|
25
|
+
args: ['-Login', '-Command', command],
|
|
26
|
+
useShellOption: false
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// Windows PowerShell 5.1 (no login flag support)
|
|
30
|
+
if (shellName === 'powershell' || shellName === 'powershell.exe') {
|
|
31
|
+
return {
|
|
32
|
+
executable: shellPath,
|
|
33
|
+
args: ['-Command', command],
|
|
34
|
+
useShellOption: false
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
// CMD
|
|
38
|
+
if (shellName === 'cmd' || shellName === 'cmd.exe') {
|
|
39
|
+
return {
|
|
40
|
+
executable: shellPath,
|
|
41
|
+
args: ['/c', command],
|
|
42
|
+
useShellOption: false
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// Fish shell (uses -l for login, -c for command)
|
|
46
|
+
if (shellName.includes('fish')) {
|
|
47
|
+
return {
|
|
48
|
+
executable: shellPath,
|
|
49
|
+
args: ['-l', '-c', command],
|
|
50
|
+
useShellOption: false
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Unknown/other shells - use shell option for safety
|
|
54
|
+
// This provides a fallback for shells we don't explicitly handle
|
|
55
|
+
return {
|
|
56
|
+
executable: command,
|
|
57
|
+
args: [],
|
|
58
|
+
useShellOption: shellPath
|
|
59
|
+
};
|
|
60
|
+
}
|
|
6
61
|
export class TerminalManager {
|
|
7
62
|
constructor() {
|
|
8
63
|
this.sessions = new Map();
|
|
@@ -54,15 +109,40 @@ export class TerminalManager {
|
|
|
54
109
|
enhancedCommand = command.replace(/^ssh /, 'ssh -t ');
|
|
55
110
|
console.log(`Enhanced SSH command: ${enhancedCommand}`);
|
|
56
111
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
112
|
+
// Get the appropriate spawn configuration for the shell
|
|
113
|
+
let spawnConfig;
|
|
114
|
+
let spawnOptions;
|
|
115
|
+
if (typeof shellToUse === 'string') {
|
|
116
|
+
// Use shell-specific configuration with login flags where appropriate
|
|
117
|
+
spawnConfig = getShellSpawnArgs(shellToUse, enhancedCommand);
|
|
118
|
+
spawnOptions = {
|
|
119
|
+
env: {
|
|
120
|
+
...process.env,
|
|
121
|
+
TERM: 'xterm-256color' // Better terminal compatibility
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
// Add shell option if needed (for unknown shells)
|
|
125
|
+
if (spawnConfig.useShellOption) {
|
|
126
|
+
spawnOptions.shell = spawnConfig.useShellOption;
|
|
62
127
|
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
// Boolean or undefined shell - use default shell option behavior
|
|
131
|
+
spawnConfig = {
|
|
132
|
+
executable: enhancedCommand,
|
|
133
|
+
args: [],
|
|
134
|
+
useShellOption: shellToUse
|
|
135
|
+
};
|
|
136
|
+
spawnOptions = {
|
|
137
|
+
shell: shellToUse,
|
|
138
|
+
env: {
|
|
139
|
+
...process.env,
|
|
140
|
+
TERM: 'xterm-256color'
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// Spawn the process with appropriate arguments
|
|
145
|
+
const childProcess = spawn(spawnConfig.executable, spawnConfig.args, spawnOptions);
|
|
66
146
|
let output = '';
|
|
67
147
|
// Ensure childProcess.pid is defined before proceeding
|
|
68
148
|
if (!childProcess.pid) {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test what argv looks like when called as a bin script
|
|
4
|
+
console.log('=== Test Script Argv ===');
|
|
5
|
+
console.log('process.argv:');
|
|
6
|
+
process.argv.forEach((arg, index) => {
|
|
7
|
+
console.log(` ${index}: "${arg}"`);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const versionArg2 = process.argv[2];
|
|
11
|
+
const versionArg3 = process.argv[3];
|
|
12
|
+
|
|
13
|
+
console.log('\nUsing argv[2]:', versionArg2);
|
|
14
|
+
console.log('Using argv[3]:', versionArg3);
|
|
@@ -7,7 +7,7 @@ class FeatureFlagManager {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
this.flags = {};
|
|
9
9
|
this.lastFetch = 0;
|
|
10
|
-
this.cacheMaxAge = 30 * 60 * 1000;
|
|
10
|
+
this.cacheMaxAge = 30 * 60 * 1000;
|
|
11
11
|
this.refreshInterval = null;
|
|
12
12
|
const configDir = path.dirname(CONFIG_FILE);
|
|
13
13
|
this.cachePath = path.join(configDir, 'feature-flags.json');
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.2.
|
|
1
|
+
export declare const VERSION = "0.2.21";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.2.
|
|
1
|
+
export const VERSION = '0.2.21';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wonderwhy-er/desktop-commander",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.21",
|
|
4
4
|
"description": "MCP server for terminal operations and file editing",
|
|
5
5
|
"mcpName": "io.github.wonderwhy-er/desktop-commander",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"clean": "shx rm -rf dist",
|
|
40
40
|
"test": "npm run build && node test/run-all-tests.js",
|
|
41
41
|
"test:debug": "node --inspect test/run-all-tests.js",
|
|
42
|
+
"validate:tools": "npm run build && node scripts/validate-tools-sync.js",
|
|
42
43
|
"link:local": "npm run build && npm link",
|
|
43
44
|
"unlink:local": "npm unlink",
|
|
44
45
|
"inspector": "npx @modelcontextprotocol/inspector dist/index.js",
|
|
@@ -86,6 +87,7 @@
|
|
|
86
87
|
"zod-to-json-schema": "^3.23.5"
|
|
87
88
|
},
|
|
88
89
|
"devDependencies": {
|
|
90
|
+
"@anthropic-ai/mcpb": "^1.2.0",
|
|
89
91
|
"@types/node": "^20.17.24",
|
|
90
92
|
"commander": "^13.1.0",
|
|
91
93
|
"nexe": "^5.0.0-beta.4",
|