@wonderwhy-er/desktop-commander 0.2.6 → 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.
- package/dist/index-dxt.js +10 -47
- package/dist/server.js +6 -0
- package/dist/tools/filesystem.js +37 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/dist/REPLSessionManager.d.ts +0 -109
- package/dist/REPLSessionManager.js +0 -364
- package/dist/REPLSessionManager.test.d.ts +0 -1
- package/dist/REPLSessionManager.test.js +0 -75
- package/dist/client/replClient.d.ts +0 -63
- package/dist/client/replClient.js +0 -217
- package/dist/client/sshClient.d.ts +0 -82
- package/dist/client/sshClient.js +0 -200
- package/dist/command-manager.js.map +0 -1
- package/dist/config-manager.js.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/custom-stdio.js.map +0 -1
- package/dist/error-handlers.js.map +0 -1
- package/dist/handlers/command-handlers.d.ts +0 -13
- package/dist/handlers/command-handlers.js +0 -43
- package/dist/handlers/edit-search-handlers.js.map +0 -1
- package/dist/handlers/filesystem-handlers.js.map +0 -1
- package/dist/handlers/fuzzy-search-log-handlers.d.ts +0 -13
- package/dist/handlers/fuzzy-search-log-handlers.js +0 -179
- package/dist/handlers/index.js.map +0 -1
- package/dist/handlers/process-handlers.js.map +0 -1
- package/dist/handlers/repl-handlers.d.ts +0 -21
- package/dist/handlers/repl-handlers.js +0 -37
- package/dist/handlers/replCommandHandler.d.ts +0 -125
- package/dist/handlers/replCommandHandler.js +0 -255
- package/dist/handlers/replCommandHandler.test.d.ts +0 -1
- package/dist/handlers/replCommandHandler.test.js +0 -103
- package/dist/handlers/terminal-handlers.js.map +0 -1
- package/dist/index-with-startup-detection.d.ts +0 -5
- package/dist/index-with-startup-detection.js +0 -180
- package/dist/index.js.map +0 -1
- package/dist/logging.d.ts +0 -2
- package/dist/logging.js +0 -28
- package/dist/polyform-license-src/edit/edit.d.ts +0 -15
- package/dist/polyform-license-src/edit/edit.js +0 -163
- package/dist/polyform-license-src/edit/fuzzySearch.d.ts +0 -30
- package/dist/polyform-license-src/edit/fuzzySearch.js +0 -121
- package/dist/polyform-license-src/edit/handlers.d.ts +0 -16
- package/dist/polyform-license-src/edit/handlers.js +0 -24
- package/dist/polyform-license-src/edit/index.d.ts +0 -12
- package/dist/polyform-license-src/edit/index.js +0 -13
- package/dist/polyform-license-src/edit/schemas.d.ts +0 -25
- package/dist/polyform-license-src/edit/schemas.js +0 -16
- package/dist/polyform-license-src/index.d.ts +0 -9
- package/dist/polyform-license-src/index.js +0 -10
- package/dist/repl-manager.d.ts +0 -73
- package/dist/repl-manager.js +0 -407
- package/dist/replIntegration.d.ts +0 -14
- package/dist/replIntegration.js +0 -27
- package/dist/sandbox/index.d.ts +0 -9
- package/dist/sandbox/index.js +0 -50
- package/dist/sandbox/mac-sandbox.d.ts +0 -19
- package/dist/sandbox/mac-sandbox.js +0 -174
- package/dist/server.js.map +0 -1
- package/dist/setup.log +0 -32
- package/dist/terminal-manager.js.map +0 -1
- package/dist/tools/client.d.ts +0 -10
- package/dist/tools/client.js +0 -13
- package/dist/tools/command-block.d.ts +0 -18
- package/dist/tools/command-block.js +0 -62
- package/dist/tools/config.js.map +0 -1
- package/dist/tools/debug-path.d.ts +0 -1
- package/dist/tools/debug-path.js +0 -44
- package/dist/tools/edit.js.map +0 -1
- package/dist/tools/enhanced-read-output.js +0 -69
- package/dist/tools/enhanced-send-input.js +0 -111
- package/dist/tools/environment.d.ts +0 -55
- package/dist/tools/environment.js +0 -65
- package/dist/tools/execute.d.ts +0 -10
- package/dist/tools/execute.js +0 -158
- package/dist/tools/execute.js.map +0 -1
- package/dist/tools/filesystem-fixed.d.ts +0 -22
- package/dist/tools/filesystem-fixed.js +0 -176
- package/dist/tools/filesystem.js.map +0 -1
- package/dist/tools/fuzzySearch.js.map +0 -1
- package/dist/tools/mime-types.js.map +0 -1
- package/dist/tools/pdf-reader.d.ts +0 -13
- package/dist/tools/pdf-reader.js +0 -214
- package/dist/tools/process.js.map +0 -1
- package/dist/tools/progress.d.ts +0 -20
- package/dist/tools/progress.js +0 -59
- package/dist/tools/repl.d.ts +0 -21
- package/dist/tools/repl.js +0 -217
- package/dist/tools/schemas.js.map +0 -1
- package/dist/tools/search.js.map +0 -1
- package/dist/tools/send-input.d.ts +0 -2
- package/dist/tools/send-input.js +0 -45
- package/dist/types.js.map +0 -1
- package/dist/utils/capture.js.map +0 -1
- package/dist/utils/early-logger.d.ts +0 -4
- package/dist/utils/early-logger.js +0 -35
- package/dist/utils/fuzzySearchLogger.js.map +0 -1
- package/dist/utils/lineEndingHandler.js.map +0 -1
- package/dist/utils/lineEndingHandler_optimized.d.ts +0 -21
- package/dist/utils/lineEndingHandler_optimized.js +0 -77
- package/dist/utils/mcp-logger.d.ts +0 -30
- package/dist/utils/mcp-logger.js +0 -59
- package/dist/utils/smithery-detector.d.ts +0 -94
- package/dist/utils/smithery-detector.js +0 -292
- package/dist/utils/startup-detector.d.ts +0 -65
- package/dist/utils/startup-detector.js +0 -390
- package/dist/utils/trackTools.js.map +0 -1
- package/dist/utils/withTimeout.js.map +0 -1
- package/dist/utils.d.ts +0 -26
- package/dist/utils.js +0 -227
- package/dist/version.js.map +0 -1
package/dist/repl-manager.js
DELETED
|
@@ -1,407 +0,0 @@
|
|
|
1
|
-
import { terminalManager } from './terminal-manager.js';
|
|
2
|
-
import { capture } from './utils/capture.js';
|
|
3
|
-
/**
|
|
4
|
-
* Manager for REPL (Read-Eval-Print Loop) sessions
|
|
5
|
-
* Provides a higher-level API for working with interactive programming environments
|
|
6
|
-
*/
|
|
7
|
-
export class REPLManager {
|
|
8
|
-
constructor() {
|
|
9
|
-
this.sessions = new Map();
|
|
10
|
-
// Language-specific configurations for various REPLs
|
|
11
|
-
this.languageConfigs = {
|
|
12
|
-
'python': {
|
|
13
|
-
command: process.platform === 'win32' ? 'python' : 'python3',
|
|
14
|
-
args: ['-i'],
|
|
15
|
-
promptPattern: /^(>>>|\.\.\.) /m,
|
|
16
|
-
errorPattern: /\b(Error|Exception|SyntaxError|TypeError|ValueError|NameError|ImportError|AttributeError)\b:.*$/m,
|
|
17
|
-
continuationPattern: /^\.\.\./m,
|
|
18
|
-
executeBlock: (code) => {
|
|
19
|
-
// Break code into lines
|
|
20
|
-
const lines = code.split('\n');
|
|
21
|
-
// For Python, we need to add an extra newline after blocks to execute them
|
|
22
|
-
if (lines.length > 1 && lines[lines.length - 1].trim() !== '') {
|
|
23
|
-
lines.push(''); // Add an empty line to end the block
|
|
24
|
-
}
|
|
25
|
-
return lines;
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
'node': {
|
|
29
|
-
command: 'node',
|
|
30
|
-
args: ['-i'], // Use the -i flag to force interactive mode
|
|
31
|
-
promptPattern: /^> ?$/m, // Updated to match exactly the Node.js prompt at beginning of line
|
|
32
|
-
errorPattern: /\b(Error|SyntaxError|TypeError|ReferenceError|RangeError)\b:.*$/m,
|
|
33
|
-
executeBlock: (code) => {
|
|
34
|
-
// For Node.js REPL, we need different handling for multi-line code
|
|
35
|
-
const lines = code.split('\n');
|
|
36
|
-
if (lines.length > 1) {
|
|
37
|
-
// For multi-line code, we'll just execute it as one string
|
|
38
|
-
// Node.js can handle this without entering editor mode
|
|
39
|
-
return [code];
|
|
40
|
-
}
|
|
41
|
-
return [code];
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
'bash': {
|
|
45
|
-
command: 'bash',
|
|
46
|
-
args: ['-i'],
|
|
47
|
-
promptPattern: /[\w\d\-_]+@[\w\d\-_]+:.*[$#] $/m,
|
|
48
|
-
errorPattern: /\b(command not found|No such file or directory|syntax error|Permission denied)\b/m
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Calculate an appropriate timeout based on code complexity
|
|
54
|
-
*/
|
|
55
|
-
calculateTimeout(code, language) {
|
|
56
|
-
// Base timeout
|
|
57
|
-
let timeout = 2000;
|
|
58
|
-
// Add time for loops
|
|
59
|
-
const loopCount = (code.match(/for|while/g) || []).length;
|
|
60
|
-
timeout += loopCount * 1000;
|
|
61
|
-
// Add time for imports/requires
|
|
62
|
-
const importPatterns = {
|
|
63
|
-
'python': [/import/g, /from\s+\w+\s+import/g],
|
|
64
|
-
'node': [/require\(/g, /import\s+.*\s+from/g],
|
|
65
|
-
'bash': [/source/g]
|
|
66
|
-
};
|
|
67
|
-
const patterns = importPatterns[language] || [];
|
|
68
|
-
let importCount = 0;
|
|
69
|
-
patterns.forEach(pattern => {
|
|
70
|
-
importCount += (code.match(pattern) || []).length;
|
|
71
|
-
});
|
|
72
|
-
timeout += importCount * 2000;
|
|
73
|
-
// Add more time for long scripts
|
|
74
|
-
const lineCount = code.split('\n').length;
|
|
75
|
-
timeout += lineCount * 200;
|
|
76
|
-
// Cap at reasonable maximum
|
|
77
|
-
return Math.min(timeout, 30000);
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Detect when a REPL is ready for input by looking for prompt patterns
|
|
81
|
-
*/
|
|
82
|
-
isReadyForInput(output, language) {
|
|
83
|
-
const config = this.languageConfigs[language];
|
|
84
|
-
if (!config || !config.promptPattern)
|
|
85
|
-
return false;
|
|
86
|
-
// For Node.js, look for the prompt at the end of the output
|
|
87
|
-
if (language === 'node') {
|
|
88
|
-
const lines = output.split('\n');
|
|
89
|
-
const lastLine = lines[lines.length - 1].trim();
|
|
90
|
-
return lastLine === '>' || lastLine === '...';
|
|
91
|
-
}
|
|
92
|
-
// For other languages, use the regular pattern
|
|
93
|
-
return config.promptPattern.test(output);
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Detect errors in REPL output
|
|
97
|
-
*/
|
|
98
|
-
detectErrors(output, language) {
|
|
99
|
-
const config = this.languageConfigs[language];
|
|
100
|
-
if (!config || !config.errorPattern)
|
|
101
|
-
return null;
|
|
102
|
-
const match = output.match(config.errorPattern);
|
|
103
|
-
return match ? match[0] : null;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Create a new REPL session for the specified language
|
|
107
|
-
*/
|
|
108
|
-
async createSession(language, timeout = 5000) {
|
|
109
|
-
try {
|
|
110
|
-
const config = this.languageConfigs[language];
|
|
111
|
-
if (!config) {
|
|
112
|
-
throw new Error(`Unsupported language: ${language}`);
|
|
113
|
-
}
|
|
114
|
-
// Prepare the command and arguments
|
|
115
|
-
const command = `${config.command} ${config.args.join(' ')}`.trim();
|
|
116
|
-
// Start the process
|
|
117
|
-
const result = await terminalManager.executeCommand(command, timeout);
|
|
118
|
-
if (result.pid <= 0) {
|
|
119
|
-
throw new Error(`Failed to start ${language} REPL: ${result.output}`);
|
|
120
|
-
}
|
|
121
|
-
// Record session information
|
|
122
|
-
this.sessions.set(result.pid, {
|
|
123
|
-
pid: result.pid,
|
|
124
|
-
language,
|
|
125
|
-
startTime: Date.now(),
|
|
126
|
-
lastActivity: Date.now(),
|
|
127
|
-
outputBuffer: result.output || ''
|
|
128
|
-
});
|
|
129
|
-
capture('repl_session_created', {
|
|
130
|
-
language,
|
|
131
|
-
pid: result.pid
|
|
132
|
-
});
|
|
133
|
-
return result.pid;
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
137
|
-
capture('repl_session_creation_failed', {
|
|
138
|
-
language,
|
|
139
|
-
error: errorMessage
|
|
140
|
-
});
|
|
141
|
-
throw error;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Send and read REPL output with a timeout
|
|
146
|
-
* This combines sending input and reading output in a single operation
|
|
147
|
-
*/
|
|
148
|
-
async sendAndReadREPL(pid, input, options = {}) {
|
|
149
|
-
const session = this.sessions.get(pid);
|
|
150
|
-
if (!session) {
|
|
151
|
-
return {
|
|
152
|
-
success: false,
|
|
153
|
-
output: null,
|
|
154
|
-
error: `No active session with PID ${pid}`,
|
|
155
|
-
timeout: false
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
try {
|
|
159
|
-
// Update last activity time
|
|
160
|
-
session.lastActivity = Date.now();
|
|
161
|
-
// Get the language configuration
|
|
162
|
-
const config = this.languageConfigs[session.language];
|
|
163
|
-
// Default timeout based on code complexity
|
|
164
|
-
const timeout = options.timeout || this.calculateTimeout(input, session.language);
|
|
165
|
-
// Clear any existing output
|
|
166
|
-
const existingOutput = terminalManager.getNewOutput(pid) || '';
|
|
167
|
-
if (existingOutput) {
|
|
168
|
-
session.outputBuffer += existingOutput;
|
|
169
|
-
}
|
|
170
|
-
// For Node.js, we need to handle the initial startup differently
|
|
171
|
-
if (session.language === 'node' && session.outputBuffer.length === 0) {
|
|
172
|
-
// Wait for Node.js to initialize if this is the first command
|
|
173
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
174
|
-
const initialOutput = terminalManager.getNewOutput(pid) || '';
|
|
175
|
-
if (initialOutput) {
|
|
176
|
-
session.outputBuffer += initialOutput;
|
|
177
|
-
}
|
|
178
|
-
// Add another small delay to ensure the Node.js REPL is fully ready
|
|
179
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
180
|
-
}
|
|
181
|
-
let output = "";
|
|
182
|
-
// For Node.js, always send the entire code block at once
|
|
183
|
-
if (session.language === 'node' && options.multiline && input.includes('\n')) {
|
|
184
|
-
const success = terminalManager.sendInputToProcess(pid, input.endsWith('\n') ? input : input + '\n');
|
|
185
|
-
if (!success) {
|
|
186
|
-
return {
|
|
187
|
-
success: false,
|
|
188
|
-
output: session.outputBuffer,
|
|
189
|
-
error: "Failed to send input to Node.js REPL",
|
|
190
|
-
timeout: false
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
// For other languages or single-line input, process according to language rules
|
|
195
|
-
else if (options.multiline && config.executeBlock) {
|
|
196
|
-
const lines = config.executeBlock(input);
|
|
197
|
-
// For other languages, send each line individually
|
|
198
|
-
for (const line of lines) {
|
|
199
|
-
const success = terminalManager.sendInputToProcess(pid, line + '\n');
|
|
200
|
-
if (!success) {
|
|
201
|
-
return {
|
|
202
|
-
success: false,
|
|
203
|
-
output: session.outputBuffer,
|
|
204
|
-
error: "Failed to send input to process",
|
|
205
|
-
timeout: false
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
// Wait a small amount of time between lines
|
|
209
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
// Single line input
|
|
214
|
-
const success = terminalManager.sendInputToProcess(pid, input.endsWith('\n') ? input : input + '\n');
|
|
215
|
-
if (!success) {
|
|
216
|
-
return {
|
|
217
|
-
success: false,
|
|
218
|
-
output: session.outputBuffer,
|
|
219
|
-
error: "Failed to send input to process",
|
|
220
|
-
timeout: false
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
// Wait for output with timeout
|
|
225
|
-
output = "";
|
|
226
|
-
const startTime = Date.now();
|
|
227
|
-
let isTimedOut = false;
|
|
228
|
-
let lastOutputLength = 0;
|
|
229
|
-
let noOutputTime = 0;
|
|
230
|
-
// Keep checking for output until timeout
|
|
231
|
-
while (Date.now() - startTime < timeout) {
|
|
232
|
-
// Check for new output
|
|
233
|
-
const newOutput = terminalManager.getNewOutput(pid) || '';
|
|
234
|
-
if (newOutput && newOutput.length > 0) {
|
|
235
|
-
output += newOutput;
|
|
236
|
-
session.outputBuffer += newOutput;
|
|
237
|
-
lastOutputLength = output.length;
|
|
238
|
-
noOutputTime = 0; // Reset no output timer
|
|
239
|
-
// If we're waiting for a prompt and it appears, we're done
|
|
240
|
-
if (options.waitForPrompt && this.isReadyForInput(output, session.language)) {
|
|
241
|
-
break;
|
|
242
|
-
}
|
|
243
|
-
// Check for errors if we're not ignoring them
|
|
244
|
-
if (!options.ignoreErrors) {
|
|
245
|
-
const error = this.detectErrors(output, session.language);
|
|
246
|
-
if (error) {
|
|
247
|
-
return {
|
|
248
|
-
success: false,
|
|
249
|
-
output,
|
|
250
|
-
error,
|
|
251
|
-
timeout: false
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
// If no new output, increment the no output timer
|
|
258
|
-
noOutputTime += 100;
|
|
259
|
-
}
|
|
260
|
-
// For Node.js, we need to be more patient due to REPL behavior
|
|
261
|
-
const nodeWaitThreshold = session.language === 'node' ? 2000 : 1000;
|
|
262
|
-
// If no new output for specified time and we have some output, we're probably done
|
|
263
|
-
if (output.length > 0 && output.length === lastOutputLength && noOutputTime > nodeWaitThreshold) {
|
|
264
|
-
// For Node.js, make sure we have a prompt before finishing
|
|
265
|
-
if (session.language === 'node') {
|
|
266
|
-
if (this.isReadyForInput(output, 'node')) {
|
|
267
|
-
break;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
else {
|
|
271
|
-
break;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
// Small delay between checks
|
|
275
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
276
|
-
}
|
|
277
|
-
// Check if we timed out
|
|
278
|
-
isTimedOut = (Date.now() - startTime) >= timeout;
|
|
279
|
-
return {
|
|
280
|
-
success: !isTimedOut || output.length > 0,
|
|
281
|
-
output,
|
|
282
|
-
timeout: isTimedOut
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
catch (error) {
|
|
286
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
287
|
-
capture('repl_command_failed', {
|
|
288
|
-
pid,
|
|
289
|
-
language: session.language,
|
|
290
|
-
error: errorMessage
|
|
291
|
-
});
|
|
292
|
-
return {
|
|
293
|
-
success: false,
|
|
294
|
-
output: null,
|
|
295
|
-
error: errorMessage,
|
|
296
|
-
timeout: false
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Execute a code block in a REPL session
|
|
302
|
-
*/
|
|
303
|
-
async executeCode(pid, code, options = {}) {
|
|
304
|
-
const session = this.sessions.get(pid);
|
|
305
|
-
if (!session) {
|
|
306
|
-
return {
|
|
307
|
-
success: false,
|
|
308
|
-
output: null,
|
|
309
|
-
error: `No active session with PID ${pid}`,
|
|
310
|
-
timeout: false
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
try {
|
|
314
|
-
capture('repl_execute_code', {
|
|
315
|
-
pid,
|
|
316
|
-
language: session.language,
|
|
317
|
-
codeLength: code.length,
|
|
318
|
-
lineCount: code.split('\n').length
|
|
319
|
-
});
|
|
320
|
-
// If code is multi-line, handle it accordingly
|
|
321
|
-
const isMultiline = code.includes('\n');
|
|
322
|
-
// For Node.js, use a longer timeout by default
|
|
323
|
-
if (session.language === 'node' && !options.timeout) {
|
|
324
|
-
options.timeout = Math.max(this.calculateTimeout(code, session.language), 5000);
|
|
325
|
-
}
|
|
326
|
-
// For Node.js, always wait for prompt
|
|
327
|
-
if (session.language === 'node' && options.waitForPrompt === undefined) {
|
|
328
|
-
options.waitForPrompt = true;
|
|
329
|
-
}
|
|
330
|
-
return this.sendAndReadREPL(pid, code, {
|
|
331
|
-
...options,
|
|
332
|
-
multiline: isMultiline
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
catch (error) {
|
|
336
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
337
|
-
capture('repl_execute_code_failed', {
|
|
338
|
-
pid,
|
|
339
|
-
language: session.language,
|
|
340
|
-
error: errorMessage
|
|
341
|
-
});
|
|
342
|
-
return {
|
|
343
|
-
success: false,
|
|
344
|
-
output: null,
|
|
345
|
-
error: errorMessage,
|
|
346
|
-
timeout: false
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Terminate a REPL session
|
|
352
|
-
*/
|
|
353
|
-
async terminateSession(pid) {
|
|
354
|
-
try {
|
|
355
|
-
const session = this.sessions.get(pid);
|
|
356
|
-
if (!session) {
|
|
357
|
-
return false;
|
|
358
|
-
}
|
|
359
|
-
// Terminate the process
|
|
360
|
-
const success = terminalManager.forceTerminate(pid);
|
|
361
|
-
// Remove from our sessions map
|
|
362
|
-
if (success) {
|
|
363
|
-
this.sessions.delete(pid);
|
|
364
|
-
capture('repl_session_terminated', {
|
|
365
|
-
pid,
|
|
366
|
-
language: session.language,
|
|
367
|
-
runtime: Date.now() - session.startTime
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
return success;
|
|
371
|
-
}
|
|
372
|
-
catch (error) {
|
|
373
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
374
|
-
capture('repl_session_termination_failed', {
|
|
375
|
-
pid,
|
|
376
|
-
error: errorMessage
|
|
377
|
-
});
|
|
378
|
-
return false;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* List all active REPL sessions
|
|
383
|
-
*/
|
|
384
|
-
listSessions() {
|
|
385
|
-
return Array.from(this.sessions.values()).map(session => ({
|
|
386
|
-
pid: session.pid,
|
|
387
|
-
language: session.language,
|
|
388
|
-
runtime: Date.now() - session.startTime
|
|
389
|
-
}));
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* Get information about a specific REPL session
|
|
393
|
-
*/
|
|
394
|
-
getSessionInfo(pid) {
|
|
395
|
-
const session = this.sessions.get(pid);
|
|
396
|
-
if (!session) {
|
|
397
|
-
return null;
|
|
398
|
-
}
|
|
399
|
-
return {
|
|
400
|
-
pid: session.pid,
|
|
401
|
-
language: session.language,
|
|
402
|
-
runtime: Date.now() - session.startTime
|
|
403
|
-
};
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
// Export singleton instance
|
|
407
|
-
export const replManager = new REPLManager();
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration file showing how to integrate REPL functionality
|
|
3
|
-
* with the Claude Server Commander
|
|
4
|
-
*/
|
|
5
|
-
interface ServerInterface {
|
|
6
|
-
registerCommands: (commands: Record<string, Function>) => void;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Integrates REPL functionality with the server
|
|
10
|
-
* @param server - Server instance
|
|
11
|
-
* @param terminalManager - Terminal manager instance
|
|
12
|
-
*/
|
|
13
|
-
export declare function integrateREPL(server: ServerInterface, terminalManager: any): void;
|
|
14
|
-
export {};
|
package/dist/replIntegration.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration file showing how to integrate REPL functionality
|
|
3
|
-
* with the Claude Server Commander
|
|
4
|
-
*/
|
|
5
|
-
import { initializeREPLManager, replCommandHandler } from './handlers/replCommandHandler.js';
|
|
6
|
-
/**
|
|
7
|
-
* Integrates REPL functionality with the server
|
|
8
|
-
* @param server - Server instance
|
|
9
|
-
* @param terminalManager - Terminal manager instance
|
|
10
|
-
*/
|
|
11
|
-
export function integrateREPL(server, terminalManager) {
|
|
12
|
-
// Initialize the REPL manager with the terminal manager
|
|
13
|
-
initializeREPLManager(terminalManager);
|
|
14
|
-
// Register REPL commands with the server
|
|
15
|
-
server.registerCommands({
|
|
16
|
-
// REPL language sessions (Python, Node.js, Bash)
|
|
17
|
-
'repl.create': replCommandHandler.createREPLSession,
|
|
18
|
-
'repl.execute': replCommandHandler.executeREPLCode,
|
|
19
|
-
'repl.list': replCommandHandler.listREPLSessions,
|
|
20
|
-
'repl.close': replCommandHandler.closeREPLSession,
|
|
21
|
-
'repl.closeIdle': replCommandHandler.closeIdleREPLSessions,
|
|
22
|
-
// SSH specific commands
|
|
23
|
-
'ssh.create': replCommandHandler.createSSHSession,
|
|
24
|
-
'ssh.execute': replCommandHandler.executeSSHCommand
|
|
25
|
-
});
|
|
26
|
-
console.log('REPL and SSH functionality integrated successfully');
|
|
27
|
-
}
|
package/dist/sandbox/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { CommandExecutionResult } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Platform detection and sandbox execution router
|
|
4
|
-
*/
|
|
5
|
-
export declare function executeSandboxedCommand(command: string, timeoutMs?: number, shell?: string): Promise<CommandExecutionResult>;
|
|
6
|
-
/**
|
|
7
|
-
* Check if sandboxed execution is available for the current platform
|
|
8
|
-
*/
|
|
9
|
-
export declare function isSandboxAvailable(): boolean;
|
package/dist/sandbox/index.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import os from 'os';
|
|
2
|
-
import { executeSandboxedCommand as macExecuteSandboxedCommand } from './mac-sandbox.js';
|
|
3
|
-
import { configManager } from '../config-manager.js';
|
|
4
|
-
/**
|
|
5
|
-
* Platform detection and sandbox execution router
|
|
6
|
-
*/
|
|
7
|
-
export async function executeSandboxedCommand(command, timeoutMs = 30000, shell) {
|
|
8
|
-
// Get the allowed directories from config
|
|
9
|
-
const config = await configManager.getConfig();
|
|
10
|
-
const allowedDirectories = config.allowedDirectories || [os.homedir()];
|
|
11
|
-
const platform = os.platform();
|
|
12
|
-
// Platform-specific sandbox execution
|
|
13
|
-
switch (platform) {
|
|
14
|
-
case 'darwin': // macOS
|
|
15
|
-
try {
|
|
16
|
-
const result = await macExecuteSandboxedCommand(command, allowedDirectories, timeoutMs);
|
|
17
|
-
return {
|
|
18
|
-
pid: result.pid,
|
|
19
|
-
output: result.output,
|
|
20
|
-
isBlocked: result.isBlocked
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
console.error('Mac sandbox execution error:', error);
|
|
25
|
-
return {
|
|
26
|
-
pid: -1,
|
|
27
|
-
output: `Sandbox execution error: ${error instanceof Error ? error.message : String(error)}`,
|
|
28
|
-
isBlocked: false
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
// Add cases for other platforms when implemented
|
|
32
|
-
// case 'linux':
|
|
33
|
-
// case 'win32':
|
|
34
|
-
default:
|
|
35
|
-
// For unsupported platforms, return an error
|
|
36
|
-
return {
|
|
37
|
-
pid: -1,
|
|
38
|
-
output: `Sandbox execution not supported on ${platform}. Command was not executed: ${command}`,
|
|
39
|
-
isBlocked: false
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Check if sandboxed execution is available for the current platform
|
|
45
|
-
*/
|
|
46
|
-
export function isSandboxAvailable() {
|
|
47
|
-
const platform = os.platform();
|
|
48
|
-
// Currently only implemented for macOS
|
|
49
|
-
return platform === 'darwin';
|
|
50
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate a temporary sandbox profile for macOS that restricts access to allowed directories
|
|
3
|
-
* @param allowedDirectories Array of directories that should be accessible
|
|
4
|
-
* @returns Path to the generated sandbox profile file
|
|
5
|
-
*/
|
|
6
|
-
export declare function generateSandboxProfile(allowedDirectories: string[]): Promise<string>;
|
|
7
|
-
/**
|
|
8
|
-
* Execute a command in a macOS sandbox with access restricted to allowed directories
|
|
9
|
-
* @param command Command to execute
|
|
10
|
-
* @param allowedDirectories Array of allowed directory paths
|
|
11
|
-
* @param options Additional execution options
|
|
12
|
-
* @returns Promise resolving to the execution result
|
|
13
|
-
*/
|
|
14
|
-
export declare function executeSandboxedCommand(command: string, allowedDirectories: string[], timeoutMs?: number): Promise<{
|
|
15
|
-
output: string;
|
|
16
|
-
exitCode: number | null;
|
|
17
|
-
isBlocked: boolean;
|
|
18
|
-
pid: number;
|
|
19
|
-
}>;
|