@wonderwhy-er/desktop-commander 0.2.5 → 0.2.7

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.
Files changed (113) hide show
  1. package/dist/index-dxt.js +10 -47
  2. package/dist/server.js +6 -0
  3. package/dist/tools/filesystem.js +37 -4
  4. package/dist/utils/usageTracker.js +8 -5
  5. package/dist/version.d.ts +1 -1
  6. package/dist/version.js +1 -1
  7. package/package.json +2 -1
  8. package/dist/REPLSessionManager.d.ts +0 -109
  9. package/dist/REPLSessionManager.js +0 -364
  10. package/dist/REPLSessionManager.test.d.ts +0 -1
  11. package/dist/REPLSessionManager.test.js +0 -75
  12. package/dist/client/replClient.d.ts +0 -63
  13. package/dist/client/replClient.js +0 -217
  14. package/dist/client/sshClient.d.ts +0 -82
  15. package/dist/client/sshClient.js +0 -200
  16. package/dist/command-manager.js.map +0 -1
  17. package/dist/config-manager.js.map +0 -1
  18. package/dist/config.js.map +0 -1
  19. package/dist/custom-stdio.js.map +0 -1
  20. package/dist/error-handlers.js.map +0 -1
  21. package/dist/handlers/command-handlers.d.ts +0 -13
  22. package/dist/handlers/command-handlers.js +0 -43
  23. package/dist/handlers/edit-search-handlers.js.map +0 -1
  24. package/dist/handlers/filesystem-handlers.js.map +0 -1
  25. package/dist/handlers/fuzzy-search-log-handlers.d.ts +0 -13
  26. package/dist/handlers/fuzzy-search-log-handlers.js +0 -179
  27. package/dist/handlers/index.js.map +0 -1
  28. package/dist/handlers/process-handlers.js.map +0 -1
  29. package/dist/handlers/repl-handlers.d.ts +0 -21
  30. package/dist/handlers/repl-handlers.js +0 -37
  31. package/dist/handlers/replCommandHandler.d.ts +0 -125
  32. package/dist/handlers/replCommandHandler.js +0 -255
  33. package/dist/handlers/replCommandHandler.test.d.ts +0 -1
  34. package/dist/handlers/replCommandHandler.test.js +0 -103
  35. package/dist/handlers/terminal-handlers.js.map +0 -1
  36. package/dist/index-with-startup-detection.d.ts +0 -5
  37. package/dist/index-with-startup-detection.js +0 -180
  38. package/dist/index.js.map +0 -1
  39. package/dist/logging.d.ts +0 -2
  40. package/dist/logging.js +0 -28
  41. package/dist/polyform-license-src/edit/edit.d.ts +0 -15
  42. package/dist/polyform-license-src/edit/edit.js +0 -163
  43. package/dist/polyform-license-src/edit/fuzzySearch.d.ts +0 -30
  44. package/dist/polyform-license-src/edit/fuzzySearch.js +0 -121
  45. package/dist/polyform-license-src/edit/handlers.d.ts +0 -16
  46. package/dist/polyform-license-src/edit/handlers.js +0 -24
  47. package/dist/polyform-license-src/edit/index.d.ts +0 -12
  48. package/dist/polyform-license-src/edit/index.js +0 -13
  49. package/dist/polyform-license-src/edit/schemas.d.ts +0 -25
  50. package/dist/polyform-license-src/edit/schemas.js +0 -16
  51. package/dist/polyform-license-src/index.d.ts +0 -9
  52. package/dist/polyform-license-src/index.js +0 -10
  53. package/dist/repl-manager.d.ts +0 -73
  54. package/dist/repl-manager.js +0 -407
  55. package/dist/replIntegration.d.ts +0 -14
  56. package/dist/replIntegration.js +0 -27
  57. package/dist/sandbox/index.d.ts +0 -9
  58. package/dist/sandbox/index.js +0 -50
  59. package/dist/sandbox/mac-sandbox.d.ts +0 -19
  60. package/dist/sandbox/mac-sandbox.js +0 -174
  61. package/dist/server.js.map +0 -1
  62. package/dist/setup.log +0 -32
  63. package/dist/terminal-manager.js.map +0 -1
  64. package/dist/tools/client.d.ts +0 -10
  65. package/dist/tools/client.js +0 -13
  66. package/dist/tools/command-block.d.ts +0 -18
  67. package/dist/tools/command-block.js +0 -62
  68. package/dist/tools/config.js.map +0 -1
  69. package/dist/tools/debug-path.d.ts +0 -1
  70. package/dist/tools/debug-path.js +0 -44
  71. package/dist/tools/edit.js.map +0 -1
  72. package/dist/tools/enhanced-read-output.js +0 -69
  73. package/dist/tools/enhanced-send-input.js +0 -111
  74. package/dist/tools/environment.d.ts +0 -55
  75. package/dist/tools/environment.js +0 -65
  76. package/dist/tools/execute.d.ts +0 -10
  77. package/dist/tools/execute.js +0 -158
  78. package/dist/tools/execute.js.map +0 -1
  79. package/dist/tools/filesystem-fixed.d.ts +0 -22
  80. package/dist/tools/filesystem-fixed.js +0 -176
  81. package/dist/tools/filesystem.js.map +0 -1
  82. package/dist/tools/fuzzySearch.js.map +0 -1
  83. package/dist/tools/mime-types.js.map +0 -1
  84. package/dist/tools/pdf-reader.d.ts +0 -13
  85. package/dist/tools/pdf-reader.js +0 -214
  86. package/dist/tools/process.js.map +0 -1
  87. package/dist/tools/progress.d.ts +0 -20
  88. package/dist/tools/progress.js +0 -59
  89. package/dist/tools/repl.d.ts +0 -21
  90. package/dist/tools/repl.js +0 -217
  91. package/dist/tools/schemas.js.map +0 -1
  92. package/dist/tools/search.js.map +0 -1
  93. package/dist/tools/send-input.d.ts +0 -2
  94. package/dist/tools/send-input.js +0 -45
  95. package/dist/types.js.map +0 -1
  96. package/dist/utils/capture.js.map +0 -1
  97. package/dist/utils/early-logger.d.ts +0 -4
  98. package/dist/utils/early-logger.js +0 -35
  99. package/dist/utils/fuzzySearchLogger.js.map +0 -1
  100. package/dist/utils/lineEndingHandler.js.map +0 -1
  101. package/dist/utils/lineEndingHandler_optimized.d.ts +0 -21
  102. package/dist/utils/lineEndingHandler_optimized.js +0 -77
  103. package/dist/utils/mcp-logger.d.ts +0 -30
  104. package/dist/utils/mcp-logger.js +0 -59
  105. package/dist/utils/smithery-detector.d.ts +0 -94
  106. package/dist/utils/smithery-detector.js +0 -292
  107. package/dist/utils/startup-detector.d.ts +0 -65
  108. package/dist/utils/startup-detector.js +0 -390
  109. package/dist/utils/trackTools.js.map +0 -1
  110. package/dist/utils/withTimeout.js.map +0 -1
  111. package/dist/utils.d.ts +0 -26
  112. package/dist/utils.js +0 -227
  113. package/dist/version.js.map +0 -1
@@ -1,103 +0,0 @@
1
- import { expect } from 'chai';
2
- import { describe, it, beforeEach, afterEach } from 'mocha';
3
- import * as sinon from 'sinon';
4
- import { initializeREPLManager, replCommandHandler } from './replCommandHandler';
5
- describe('REPL Command Handler', () => {
6
- let mockSessionManager;
7
- let sandbox;
8
- beforeEach(() => {
9
- // Create a sinon sandbox for test isolation
10
- sandbox = sinon.createSandbox();
11
- // Create mock for REPLSessionManager
12
- mockSessionManager = {
13
- createSession: sandbox.stub().resolves(12345),
14
- executeCode: sandbox.stub().resolves({
15
- success: true,
16
- output: 'test output'
17
- }),
18
- createSSHSession: sandbox.stub().resolves(54321),
19
- sendAndReadREPL: sandbox.stub().resolves({
20
- success: true,
21
- output: 'ssh output'
22
- }),
23
- listSessions: sandbox.stub().returns([
24
- { pid: 12345, language: 'node' },
25
- { pid: 54321, language: 'ssh' }
26
- ]),
27
- closeSession: sandbox.stub().resolves(true),
28
- closeIdleSessions: sandbox.stub().resolves(2)
29
- };
30
- // Create a mock terminal manager
31
- const mockTerminalManager = {};
32
- // Use a more direct approach to set up the testing environment
33
- // Override the module's private replManager variable with our mock
34
- global.replManager = mockSessionManager;
35
- initializeREPLManager(mockTerminalManager);
36
- });
37
- afterEach(() => {
38
- // Restore all stubbed methods
39
- sandbox.restore();
40
- // Reset the module state
41
- global.replManager = null;
42
- });
43
- it('should create a REPL session', async () => {
44
- const result = await replCommandHandler.createREPLSession({
45
- language: 'node'
46
- });
47
- expect(result.success).to.be.true;
48
- expect(result.pid).to.equal(12345);
49
- });
50
- it('should execute code in a REPL session', async () => {
51
- const result = await replCommandHandler.executeREPLCode({
52
- pid: 12345,
53
- code: 'console.log("test")'
54
- });
55
- expect(result.success).to.be.true;
56
- expect(result.output).to.equal('test output');
57
- });
58
- it('should create an SSH session', async () => {
59
- const result = await replCommandHandler.createSSHSession({
60
- host: 'example.com',
61
- username: 'user'
62
- });
63
- expect(result.success).to.be.true;
64
- expect(result.pid).to.equal(54321);
65
- });
66
- it('should execute a command in an SSH session', async () => {
67
- const result = await replCommandHandler.executeSSHCommand({
68
- pid: 54321,
69
- command: 'ls -la'
70
- });
71
- expect(result.success).to.be.true;
72
- expect(result.output).to.equal('ssh output');
73
- });
74
- it('should list all REPL sessions', () => {
75
- const result = replCommandHandler.listREPLSessions();
76
- expect(result.success).to.be.true;
77
- expect(result.sessions).to.have.length(2);
78
- expect(result.sessions[0].pid).to.equal(12345);
79
- expect(result.sessions[1].pid).to.equal(54321);
80
- });
81
- it('should close a REPL session', async () => {
82
- const result = await replCommandHandler.closeREPLSession({
83
- pid: 12345
84
- });
85
- expect(result.success).to.be.true;
86
- });
87
- it('should close idle REPL sessions', async () => {
88
- const result = await replCommandHandler.closeIdleREPLSessions({
89
- maxIdleMs: 3600000 // 1 hour
90
- });
91
- expect(result.success).to.be.true;
92
- expect(result.closedCount).to.equal(2);
93
- });
94
- it('should handle errors when REPL manager is not initialized', async () => {
95
- // Reset the handler to simulate uninitialized state
96
- initializeREPLManager(null);
97
- const result = await replCommandHandler.createREPLSession({
98
- language: 'node'
99
- });
100
- expect(result.success).to.be.false;
101
- expect(result.error).to.equal('REPL Manager not initialized');
102
- });
103
- });
@@ -1 +0,0 @@
1
- {"version":3,"file":"terminal-handlers.js","sourceRoot":"","sources":["../../src/handlers/terminal-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,EACd,UAAU,EACV,cAAc,EACd,YAAY,EACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,wBAAwB,EACxB,oBAAoB,EACpB,wBAAwB,EAE3B,MAAM,qBAAqB,CAAC;AAI7B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAa;IACpD,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAa;IAChD,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAa;IACpD,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACpC,OAAO,YAAY,EAAE,CAAC;AAC1B,CAAC"}
@@ -1,5 +0,0 @@
1
- /**
2
- * Example integration of startup detection in your server.ts file
3
- * This shows how to add startup detection to your existing server
4
- */
5
- export {};
@@ -1,180 +0,0 @@
1
- /**
2
- * Example integration of startup detection in your server.ts file
3
- * This shows how to add startup detection to your existing server
4
- */
5
- import { FilteredStdioServerTransport } from './custom-stdio.js';
6
- import { server } from './server.js';
7
- import { configManager } from './config-manager.js';
8
- import { getStartupInfo, getStartupMethod, isProduction, isDevelopment, isDocker, isCi } from './utils/startup-detector.js';
9
- import { capture } from './utils/capture.js';
10
- import { join, dirname } from 'path';
11
- import { fileURLToPath, pathToFileURL } from 'url';
12
- import { platform } from 'os';
13
- const __filename = fileURLToPath(import.meta.url);
14
- const __dirname = dirname(__filename);
15
- const isWindows = platform() === 'win32';
16
- function createFileURL(filePath) {
17
- if (isWindows) {
18
- const normalizedPath = filePath.replace(/\\/g, '/');
19
- if (normalizedPath.startsWith('/')) {
20
- return new URL(`file://${normalizedPath}`);
21
- }
22
- else {
23
- return new URL(`file:///${normalizedPath}`);
24
- }
25
- }
26
- else {
27
- return pathToFileURL(filePath);
28
- }
29
- }
30
- async function runSetup() {
31
- try {
32
- const setupScriptPath = join(__dirname, 'setup-claude-server.js');
33
- const setupScriptUrl = createFileURL(setupScriptPath);
34
- const { default: setupModule } = await import(setupScriptUrl.href);
35
- if (typeof setupModule === 'function') {
36
- await setupModule();
37
- }
38
- }
39
- catch (error) {
40
- console.error('Error running setup:', error);
41
- process.exit(1);
42
- }
43
- }
44
- async function runServer() {
45
- try {
46
- // Check if first argument is "setup"
47
- if (process.argv[2] === 'setup') {
48
- await runSetup();
49
- return;
50
- }
51
- // ============ NEW: Startup Detection Integration ============
52
- const startupInfo = getStartupInfo();
53
- const startupMethod = getStartupMethod();
54
- // Log startup information
55
- console.error(`🚀 Desktop Commander starting via: ${startupMethod}`);
56
- console.error(`📍 Environment: ${startupInfo.environment}`);
57
- console.error(`🔍 Detection confidence: ${startupInfo.confidence}%`);
58
- if (startupInfo.details.evidence.length > 0) {
59
- console.error(`📝 Evidence: ${startupInfo.details.evidence.join(', ')}`);
60
- }
61
- // Conditional behavior based on startup method
62
- if (isProduction()) {
63
- console.error('🏭 Production mode: Enhanced error handling enabled');
64
- // Enable production-specific features
65
- process.on('uncaughtException', (error) => {
66
- console.error('[PRODUCTION] Uncaught exception:', error);
67
- // More robust error handling in production
68
- process.exit(1);
69
- });
70
- }
71
- else if (isDevelopment()) {
72
- console.error('🛠️ Development mode: Debug features enabled');
73
- // Enable development-specific features
74
- }
75
- if (isDocker()) {
76
- console.error('🐳 Docker environment detected');
77
- // Docker-specific configuration
78
- }
79
- if (isCi()) {
80
- console.error('🤖 CI/CD environment detected');
81
- // CI-specific behavior (minimal logging, etc.)
82
- }
83
- // Log startup analytics
84
- capture('desktop_commander_startup', {
85
- startup_method: startupInfo.method,
86
- environment: startupInfo.environment,
87
- confidence: startupInfo.confidence,
88
- npm_script: startupInfo.details.npmScript || null,
89
- ci_platform: startupInfo.details.ciPlatform || null,
90
- docker_container: startupInfo.details.dockerContainer || false
91
- });
92
- // Adjust logging verbosity based on environment
93
- const logLevel = isProduction() ? 'error' :
94
- isDevelopment() ? 'debug' :
95
- isCi() ? 'warn' : 'info';
96
- console.error(`📊 Log level set to: ${logLevel}`);
97
- // ========================================================
98
- const transport = new FilteredStdioServerTransport();
99
- // Enhanced error handling with startup context
100
- process.on('uncaughtException', async (error) => {
101
- const errorMessage = error instanceof Error ? error.message : String(error);
102
- if (errorMessage.includes('JSON') && errorMessage.includes('Unexpected token')) {
103
- process.stderr.write(`[desktop-commander] JSON parsing error: ${errorMessage}\n`);
104
- return;
105
- }
106
- // Include startup context in error capture
107
- capture('run_server_uncaught_exception', {
108
- error: errorMessage,
109
- startup_method: startupInfo.method,
110
- environment: startupInfo.environment
111
- });
112
- process.stderr.write(`[desktop-commander] Uncaught exception: ${errorMessage}\n`);
113
- process.exit(1);
114
- });
115
- process.on('unhandledRejection', async (reason) => {
116
- const errorMessage = reason instanceof Error ? reason.message : String(reason);
117
- if (errorMessage.includes('JSON') && errorMessage.includes('Unexpected token')) {
118
- process.stderr.write(`[desktop-commander] JSON parsing rejection: ${errorMessage}\n`);
119
- return;
120
- }
121
- capture('run_server_unhandled_rejection', {
122
- error: errorMessage,
123
- startup_method: startupInfo.method,
124
- environment: startupInfo.environment
125
- });
126
- process.stderr.write(`[desktop-commander] Unhandled rejection: ${errorMessage}\n`);
127
- process.exit(1);
128
- });
129
- capture('run_server_start', {
130
- startup_method: startupInfo.method,
131
- environment: startupInfo.environment
132
- });
133
- try {
134
- console.error("Loading configuration...");
135
- await configManager.loadConfig();
136
- console.error("Configuration loaded successfully");
137
- }
138
- catch (configError) {
139
- console.error(`Failed to load configuration: ${configError instanceof Error ? configError.message : String(configError)}`);
140
- console.error(configError instanceof Error && configError.stack ? configError.stack : 'No stack trace available');
141
- console.error("Continuing with in-memory configuration only");
142
- }
143
- console.error("Connecting server...");
144
- await server.connect(transport);
145
- console.error("✅ Server connected successfully");
146
- console.error(`🎯 Running in ${startupInfo.environment} environment via ${startupMethod}`);
147
- }
148
- catch (error) {
149
- const errorMessage = error instanceof Error ? error.message : String(error);
150
- console.error(`FATAL ERROR: ${errorMessage}`);
151
- console.error(error instanceof Error && error.stack ? error.stack : 'No stack trace available');
152
- process.stderr.write(JSON.stringify({
153
- type: 'error',
154
- timestamp: new Date().toISOString(),
155
- message: `Failed to start server: ${errorMessage}`,
156
- startup_method: getStartupInfo().method
157
- }) + '\n');
158
- capture('run_server_failed_start_error', {
159
- error: errorMessage,
160
- startup_method: getStartupInfo().method
161
- });
162
- process.exit(1);
163
- }
164
- }
165
- runServer().catch(async (error) => {
166
- const errorMessage = error instanceof Error ? error.message : String(error);
167
- console.error(`RUNTIME ERROR: ${errorMessage}`);
168
- console.error(error instanceof Error && error.stack ? error.stack : 'No stack trace available');
169
- process.stderr.write(JSON.stringify({
170
- type: 'error',
171
- timestamp: new Date().toISOString(),
172
- message: `Fatal error running server: ${errorMessage}`,
173
- startup_method: getStartupInfo().method
174
- }) + '\n');
175
- capture('run_server_fatal_error', {
176
- error: errorMessage,
177
- startup_method: getStartupInfo().method
178
- });
179
- process.exit(1);
180
- });
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/logging.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare function logToFile(message: string): Promise<void>;
2
- export declare function logError(message: string): Promise<void>;
package/dist/logging.js DELETED
@@ -1,28 +0,0 @@
1
- import { appendFileSync } from 'fs';
2
- import { join } from 'path';
3
- import { fileURLToPath } from 'url';
4
- import { dirname } from 'path';
5
- const __filename = fileURLToPath(import.meta.url);
6
- const __dirname = dirname(__filename);
7
- const LOG_FILE = join(__dirname, '..', 'server.log');
8
- const ERROR_LOG_FILE = join(__dirname, '..', 'error.log');
9
- export async function logToFile(message) {
10
- const timestamp = new Date().toISOString();
11
- const logMessage = `${timestamp} - ${message}\n`;
12
- try {
13
- appendFileSync(LOG_FILE, logMessage);
14
- }
15
- catch (err) {
16
- console.error('Failed to write to log file:', err);
17
- }
18
- }
19
- export async function logError(message) {
20
- const timestamp = new Date().toISOString();
21
- const logMessage = `${timestamp} - ERROR: ${message}\n`;
22
- try {
23
- appendFileSync(ERROR_LOG_FILE, logMessage);
24
- }
25
- catch (err) {
26
- console.error('Failed to write to error log file:', err);
27
- }
28
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * SPDX-License-Identifier: PolyForm-Small-Business-1.0.0
3
- *
4
- * Copyright (c) 2025 Desktope Commander MCP Contributors
5
- *
6
- * This file is licensed under the PolyForm Small Business License 1.0.0
7
- * See the LICENSE file in the /src/polyform directory for the full license text.
8
- */
9
- import { ServerResult } from '../../types.js';
10
- interface SearchReplace {
11
- search: string;
12
- replace: string;
13
- }
14
- export declare function performSearchReplace(filePath: string, block: SearchReplace, expectedReplacements?: number): Promise<ServerResult>;
15
- export {};
@@ -1,163 +0,0 @@
1
- /**
2
- * SPDX-License-Identifier: PolyForm-Small-Business-1.0.0
3
- *
4
- * Copyright (c) 2025 Desktope Commander MCP Contributors
5
- *
6
- * This file is licensed under the PolyForm Small Business License 1.0.0
7
- * See the LICENSE file in the /src/polyform directory for the full license text.
8
- */
9
- import { readFile, writeFile } from '../../tools/filesystem.js';
10
- import { recursiveFuzzyIndexOf, getSimilarityRatio } from './fuzzySearch.js';
11
- import { capture } from '../../utils.js';
12
- /**
13
- * Threshold for fuzzy matching - similarity must be at least this value to be considered
14
- * (0-1 scale where 1 is perfect match and 0 is completely different)
15
- */
16
- const FUZZY_THRESHOLD = 0.7;
17
- export async function performSearchReplace(filePath, block, expectedReplacements = 1) {
18
- // Check for empty search string to prevent infinite loops
19
- if (block.search === "") {
20
- return {
21
- content: [{
22
- type: "text",
23
- text: "Empty search strings are not allowed. Please provide a non-empty string to search for."
24
- }],
25
- };
26
- }
27
- // Read file as plain string
28
- const { content } = await readFile(filePath);
29
- // Make sure content is a string
30
- if (typeof content !== 'string') {
31
- throw new Error('Wrong content for file ' + filePath);
32
- }
33
- // First try exact match
34
- let tempContent = content;
35
- let count = 0;
36
- let pos = tempContent.indexOf(block.search);
37
- while (pos !== -1) {
38
- count++;
39
- pos = tempContent.indexOf(block.search, pos + 1);
40
- }
41
- // If exact match found and count matches expected replacements, proceed with exact replacement
42
- if (count > 0 && count === expectedReplacements) {
43
- // Replace all occurrences
44
- let newContent = content;
45
- // If we're only replacing one occurrence, replace it directly
46
- if (expectedReplacements === 1) {
47
- const searchIndex = newContent.indexOf(block.search);
48
- newContent =
49
- newContent.substring(0, searchIndex) +
50
- block.replace +
51
- newContent.substring(searchIndex + block.search.length);
52
- }
53
- else {
54
- // Replace all occurrences using split and join for multiple replacements
55
- newContent = newContent.split(block.search).join(block.replace);
56
- }
57
- await writeFile(filePath, newContent);
58
- return {
59
- content: [{
60
- type: "text",
61
- text: `Successfully applied ${expectedReplacements} edit${expectedReplacements > 1 ? 's' : ''} to ${filePath}`
62
- }],
63
- };
64
- }
65
- // If exact match found but count doesn't match expected, inform the user
66
- if (count > 0 && count !== expectedReplacements) {
67
- return {
68
- content: [{
69
- type: "text",
70
- text: `Expected ${expectedReplacements} occurrences but found ${count} in ${filePath}. ` +
71
- `If you want to replace all ${count} occurrences, set expected_replacements to ${count}. ` +
72
- `If you want to replace a specific occurrence, make your search string more unique by adding context.`
73
- }],
74
- };
75
- }
76
- // If exact match not found, try fuzzy search
77
- if (count === 0) {
78
- // Track fuzzy search time
79
- const startTime = performance.now();
80
- // Perform fuzzy search
81
- const fuzzyResult = recursiveFuzzyIndexOf(content, block.search);
82
- const similarity = getSimilarityRatio(block.search, fuzzyResult.value);
83
- // Calculate execution time in milliseconds
84
- const executionTime = performance.now() - startTime;
85
- // Check if the fuzzy match is "close enough"
86
- if (similarity >= FUZZY_THRESHOLD) {
87
- // Format differences for clearer output
88
- const diff = highlightDifferences(block.search, fuzzyResult.value);
89
- // Capture the fuzzy search event
90
- capture('server_fuzzy_search_performed', {
91
- similarity: similarity,
92
- execution_time_ms: executionTime,
93
- search_length: block.search.length,
94
- file_size: content.length,
95
- threshold: FUZZY_THRESHOLD,
96
- found_text_length: fuzzyResult.value.length
97
- });
98
- // If we allow fuzzy matches, we would make the replacement here
99
- // For now, we'll return a detailed message about the fuzzy match
100
- return {
101
- content: [{
102
- type: "text",
103
- text: `Exact match not found, but found a similar text with ${Math.round(similarity * 100)}% similarity (found in ${executionTime.toFixed(2)}ms):\n\n` +
104
- `Differences:\n${diff}\n\n` +
105
- `To replace this text, use the exact text found in the file.`
106
- }],
107
- };
108
- }
109
- else {
110
- // If the fuzzy match isn't close enough
111
- // Still capture the fuzzy search event even for unsuccessful matches
112
- capture('server_fuzzy_search_performed', {
113
- similarity: similarity,
114
- execution_time_ms: executionTime,
115
- search_length: block.search.length,
116
- file_size: content.length,
117
- threshold: FUZZY_THRESHOLD,
118
- found_text_length: fuzzyResult.value.length,
119
- file_path: filePath,
120
- below_threshold: true
121
- });
122
- return {
123
- content: [{
124
- type: "text",
125
- text: `Search content not found in ${filePath}. The closest match was "${fuzzyResult.value}" ` +
126
- `with only ${Math.round(similarity * 100)}% similarity, which is below the ${Math.round(FUZZY_THRESHOLD * 100)}% threshold. ` +
127
- `(Fuzzy search completed in ${executionTime.toFixed(2)}ms)`
128
- }],
129
- };
130
- }
131
- }
132
- throw new Error("Unexpected error during search and replace operation.");
133
- }
134
- /**
135
- * Generates a character-level diff using standard {-removed-}{+added+} format
136
- * @param expected The string that was searched for
137
- * @param actual The string that was found
138
- * @returns A formatted string showing character-level differences
139
- */
140
- function highlightDifferences(expected, actual) {
141
- // Implementation of a simplified character-level diff
142
- // Find common prefix and suffix
143
- let prefixLength = 0;
144
- const minLength = Math.min(expected.length, actual.length);
145
- // Determine common prefix length
146
- while (prefixLength < minLength &&
147
- expected[prefixLength] === actual[prefixLength]) {
148
- prefixLength++;
149
- }
150
- // Determine common suffix length
151
- let suffixLength = 0;
152
- while (suffixLength < minLength - prefixLength &&
153
- expected[expected.length - 1 - suffixLength] === actual[actual.length - 1 - suffixLength]) {
154
- suffixLength++;
155
- }
156
- // Extract the common and different parts
157
- const commonPrefix = expected.substring(0, prefixLength);
158
- const commonSuffix = expected.substring(expected.length - suffixLength);
159
- const expectedDiff = expected.substring(prefixLength, expected.length - suffixLength);
160
- const actualDiff = actual.substring(prefixLength, actual.length - suffixLength);
161
- // Format the output as a character-level diff
162
- return `${commonPrefix}{-${expectedDiff}-}{+${actualDiff}+}${commonSuffix}`;
163
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * SPDX-License-Identifier: PolyForm-Small-Business-1.0.0
3
- *
4
- * Copyright (c) 2025 Desktope Commander MCP Contributors
5
- *
6
- * This file is licensed under the PolyForm Small Business License 1.0.0
7
- * See the LICENSE file in the /src/polyform directory for the full license text.
8
- */
9
- /**
10
- * Recursively finds the closest match to a query string within text using fuzzy matching
11
- * @param text The text to search within
12
- * @param query The query string to find
13
- * @param start Start index in the text (default: 0)
14
- * @param end End index in the text (default: text.length)
15
- * @param parentDistance Best distance found so far (default: Infinity)
16
- * @returns Object with start and end indices, matched value, and Levenshtein distance
17
- */
18
- export declare function recursiveFuzzyIndexOf(text: string, query: string, start?: number, end?: number | null, parentDistance?: number, depth?: number): {
19
- start: number;
20
- end: number;
21
- value: string;
22
- distance: number;
23
- };
24
- /**
25
- * Calculates the similarity ratio between two strings
26
- * @param a First string
27
- * @param b Second string
28
- * @returns Similarity ratio (0-1)
29
- */
30
- export declare function getSimilarityRatio(a: string, b: string): number;