@wonderwhy-er/desktop-commander 0.1.33 → 0.1.35
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 +105 -36
- package/dist/command-manager.d.ts +1 -7
- package/dist/command-manager.js +31 -50
- package/dist/config-manager.d.ts +27 -16
- package/dist/config-manager.js +109 -191
- package/dist/config.js +8 -4
- package/dist/error-handlers.d.ts +7 -0
- package/dist/error-handlers.js +15 -0
- package/dist/handlers/command-handlers.d.ts +4 -18
- package/dist/handlers/command-handlers.js +15 -3
- package/dist/handlers/edit-search-handlers.d.ts +3 -12
- package/dist/handlers/edit-search-handlers.js +10 -7
- package/dist/handlers/filesystem-handlers.d.ts +9 -66
- package/dist/handlers/filesystem-handlers.js +106 -65
- package/dist/handlers/index.d.ts +0 -1
- package/dist/handlers/index.js +0 -1
- package/dist/handlers/process-handlers.d.ts +3 -12
- package/dist/handlers/terminal-handlers.d.ts +5 -24
- package/dist/index.js +18 -3
- package/dist/sandbox/index.d.ts +9 -0
- package/dist/sandbox/index.js +50 -0
- package/dist/sandbox/mac-sandbox.d.ts +19 -0
- package/dist/sandbox/mac-sandbox.js +174 -0
- package/dist/server.js +156 -176
- package/dist/setup-claude-server.js +98 -49
- package/dist/terminal-manager.d.ts +1 -1
- package/dist/terminal-manager.js +26 -4
- package/dist/tools/config.d.ts +0 -58
- package/dist/tools/config.js +44 -107
- package/dist/tools/debug-path.d.ts +1 -0
- package/dist/tools/debug-path.js +44 -0
- package/dist/tools/edit.d.ts +3 -1
- package/dist/tools/edit.js +19 -7
- package/dist/tools/execute.d.ts +4 -18
- package/dist/tools/execute.js +27 -8
- package/dist/tools/filesystem-fixed.d.ts +22 -0
- package/dist/tools/filesystem-fixed.js +176 -0
- package/dist/tools/filesystem.d.ts +4 -6
- package/dist/tools/filesystem.js +106 -75
- package/dist/tools/process.d.ts +3 -12
- package/dist/tools/process.js +12 -3
- package/dist/tools/schemas.d.ts +15 -14
- package/dist/tools/schemas.js +10 -6
- package/dist/tools/search.js +3 -3
- package/dist/types.d.ts +12 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +92 -32
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -2
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @param requestedPath The path to validate
|
|
7
7
|
* @returns Promise<string> The validated path
|
|
8
|
-
* @throws Error if the path or its parent directories don't exist
|
|
8
|
+
* @throws Error if the path or its parent directories don't exist or if the path is not allowed
|
|
9
9
|
*/
|
|
10
10
|
export declare function validatePath(requestedPath: string): Promise<string>;
|
|
11
11
|
export interface FileResult {
|
|
@@ -16,17 +16,16 @@ export interface FileResult {
|
|
|
16
16
|
/**
|
|
17
17
|
* Read file content from a URL
|
|
18
18
|
* @param url URL to fetch content from
|
|
19
|
-
* @param returnMetadata Whether to return metadata with the content
|
|
20
19
|
* @returns File content or file result with metadata
|
|
21
20
|
*/
|
|
22
|
-
export declare function readFileFromUrl(url: string
|
|
21
|
+
export declare function readFileFromUrl(url: string): Promise<FileResult>;
|
|
23
22
|
/**
|
|
24
23
|
* Read file content from the local filesystem
|
|
25
24
|
* @param filePath Path to the file
|
|
26
25
|
* @param returnMetadata Whether to return metadata with the content
|
|
27
26
|
* @returns File content or file result with metadata
|
|
28
27
|
*/
|
|
29
|
-
export declare function readFileFromDisk(filePath: string
|
|
28
|
+
export declare function readFileFromDisk(filePath: string): Promise<FileResult>;
|
|
30
29
|
/**
|
|
31
30
|
* Read a file from either the local filesystem or a URL
|
|
32
31
|
* @param filePath Path to the file or URL
|
|
@@ -34,7 +33,7 @@ export declare function readFileFromDisk(filePath: string, returnMetadata?: bool
|
|
|
34
33
|
* @param isUrl Whether the path is a URL
|
|
35
34
|
* @returns File content or file result with metadata
|
|
36
35
|
*/
|
|
37
|
-
export declare function readFile(filePath: string,
|
|
36
|
+
export declare function readFile(filePath: string, isUrl?: boolean): Promise<FileResult>;
|
|
38
37
|
export declare function writeFile(filePath: string, content: string): Promise<void>;
|
|
39
38
|
export interface MultiFileResult {
|
|
40
39
|
path: string;
|
|
@@ -49,4 +48,3 @@ export declare function listDirectory(dirPath: string): Promise<string[]>;
|
|
|
49
48
|
export declare function moveFile(sourcePath: string, destinationPath: string): Promise<void>;
|
|
50
49
|
export declare function searchFiles(rootPath: string, pattern: string): Promise<string[]>;
|
|
51
50
|
export declare function getFileInfo(filePath: string): Promise<Record<string, any>>;
|
|
52
|
-
export declare function listAllowedDirectories(): string[];
|
package/dist/tools/filesystem.js
CHANGED
|
@@ -2,22 +2,35 @@ import fs from "fs/promises";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import fetch from 'cross-fetch';
|
|
5
|
-
import { withTimeout } from '../utils.js';
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
import { capture, withTimeout } from '../utils.js';
|
|
6
|
+
import { configManager } from '../config-manager.js';
|
|
7
|
+
// Initialize allowed directories from configuration
|
|
8
|
+
async function getAllowedDirs() {
|
|
9
|
+
try {
|
|
10
|
+
let allowedDirectories;
|
|
11
|
+
const config = await configManager.getConfig();
|
|
12
|
+
if (config.allowedDirectories && Array.isArray(config.allowedDirectories)) {
|
|
13
|
+
allowedDirectories = config.allowedDirectories;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
// Fall back to default directories if not configured
|
|
17
|
+
allowedDirectories = [
|
|
18
|
+
os.homedir() // User's home directory
|
|
19
|
+
];
|
|
20
|
+
// Update config with default
|
|
21
|
+
await configManager.setValue('allowedDirectories', allowedDirectories);
|
|
22
|
+
}
|
|
23
|
+
return allowedDirectories;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
console.error('Failed to initialize allowed directories:', error);
|
|
27
|
+
// Keep the default permissive path
|
|
28
|
+
}
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
18
31
|
// Normalize all paths consistently
|
|
19
32
|
function normalizePath(p) {
|
|
20
|
-
return path.normalize(p).toLowerCase();
|
|
33
|
+
return path.normalize(expandHome(p)).toLowerCase();
|
|
21
34
|
}
|
|
22
35
|
function expandHome(filepath) {
|
|
23
36
|
if (filepath.startsWith('~/') || filepath === '~') {
|
|
@@ -49,6 +62,47 @@ async function validateParentDirectories(directoryPath) {
|
|
|
49
62
|
return validateParentDirectories(parentDir);
|
|
50
63
|
}
|
|
51
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Checks if a path is within any of the allowed directories
|
|
67
|
+
*
|
|
68
|
+
* @param pathToCheck Path to check
|
|
69
|
+
* @returns boolean True if path is allowed
|
|
70
|
+
*/
|
|
71
|
+
async function isPathAllowed(pathToCheck) {
|
|
72
|
+
// If root directory is allowed, all paths are allowed
|
|
73
|
+
const allowedDirectories = await getAllowedDirs();
|
|
74
|
+
if (allowedDirectories.includes('/') || allowedDirectories.length === 0) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
let normalizedPathToCheck = normalizePath(pathToCheck);
|
|
78
|
+
if (normalizedPathToCheck.slice(-1) === path.sep) {
|
|
79
|
+
normalizedPathToCheck = normalizedPathToCheck.slice(0, -1);
|
|
80
|
+
}
|
|
81
|
+
// Check if the path is within any allowed directory
|
|
82
|
+
const isAllowed = allowedDirectories.some(allowedDir => {
|
|
83
|
+
let normalizedAllowedDir = normalizePath(allowedDir);
|
|
84
|
+
if (normalizedAllowedDir.slice(-1) === path.sep) {
|
|
85
|
+
normalizedAllowedDir = normalizedAllowedDir.slice(0, -1);
|
|
86
|
+
}
|
|
87
|
+
// Check if path is exactly the allowed directory
|
|
88
|
+
if (normalizedPathToCheck === normalizedAllowedDir) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
// Check if path is a subdirectory of the allowed directory
|
|
92
|
+
// Make sure to add a separator to prevent partial directory name matches
|
|
93
|
+
// e.g. /home/user vs /home/username
|
|
94
|
+
const subdirCheck = normalizedPathToCheck.startsWith(normalizedAllowedDir + path.sep);
|
|
95
|
+
if (subdirCheck) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
// If allowed directory is the root (C:\ on Windows), allow access to the entire drive
|
|
99
|
+
if (normalizedAllowedDir === 'c:' && process.platform === 'win32') {
|
|
100
|
+
return normalizedPathToCheck.startsWith('c:');
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
});
|
|
104
|
+
return isAllowed;
|
|
105
|
+
}
|
|
52
106
|
/**
|
|
53
107
|
* Validates a path to ensure it can be accessed or created.
|
|
54
108
|
* For existing paths, returns the real path (resolving symlinks).
|
|
@@ -56,7 +110,7 @@ async function validateParentDirectories(directoryPath) {
|
|
|
56
110
|
*
|
|
57
111
|
* @param requestedPath The path to validate
|
|
58
112
|
* @returns Promise<string> The validated path
|
|
59
|
-
* @throws Error if the path or its parent directories don't exist
|
|
113
|
+
* @throws Error if the path or its parent directories don't exist or if the path is not allowed
|
|
60
114
|
*/
|
|
61
115
|
export async function validatePath(requestedPath) {
|
|
62
116
|
const PATH_VALIDATION_TIMEOUT = 10000; // 10 seconds timeout
|
|
@@ -67,6 +121,10 @@ export async function validatePath(requestedPath) {
|
|
|
67
121
|
const absolute = path.isAbsolute(expandedPath)
|
|
68
122
|
? path.resolve(expandedPath)
|
|
69
123
|
: path.resolve(process.cwd(), expandedPath);
|
|
124
|
+
// Check if path is allowed
|
|
125
|
+
if (!(await isPathAllowed(absolute))) {
|
|
126
|
+
throw (`Path not allowed: ${requestedPath}. Must be within one of these directories: ${(await getAllowedDirs()).join(', ')}`);
|
|
127
|
+
}
|
|
70
128
|
// Check if path exists
|
|
71
129
|
try {
|
|
72
130
|
const stats = await fs.stat(absolute);
|
|
@@ -87,17 +145,17 @@ export async function validatePath(requestedPath) {
|
|
|
87
145
|
// Execute with timeout
|
|
88
146
|
const result = await withTimeout(validationOperation(), PATH_VALIDATION_TIMEOUT, `Path validation for ${requestedPath}`, null);
|
|
89
147
|
if (result === null) {
|
|
90
|
-
|
|
148
|
+
// Return a path with an error indicator instead of throwing
|
|
149
|
+
throw new Error(`Path validation failed for path: ${requestedPath}`);
|
|
91
150
|
}
|
|
92
151
|
return result;
|
|
93
152
|
}
|
|
94
153
|
/**
|
|
95
154
|
* Read file content from a URL
|
|
96
155
|
* @param url URL to fetch content from
|
|
97
|
-
* @param returnMetadata Whether to return metadata with the content
|
|
98
156
|
* @returns File content or file result with metadata
|
|
99
157
|
*/
|
|
100
|
-
export async function readFileFromUrl(url
|
|
158
|
+
export async function readFileFromUrl(url) {
|
|
101
159
|
// Import the MIME type utilities
|
|
102
160
|
const { isImageFile } = await import('./mime-types.js');
|
|
103
161
|
// Set up fetch with timeout
|
|
@@ -120,32 +178,22 @@ export async function readFileFromUrl(url, returnMetadata) {
|
|
|
120
178
|
// For images, convert to base64
|
|
121
179
|
const buffer = await response.arrayBuffer();
|
|
122
180
|
const content = Buffer.from(buffer).toString('base64');
|
|
123
|
-
|
|
124
|
-
return { content, mimeType: contentType, isImage };
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
return content;
|
|
128
|
-
}
|
|
181
|
+
return { content, mimeType: contentType, isImage };
|
|
129
182
|
}
|
|
130
183
|
else {
|
|
131
184
|
// For text content
|
|
132
185
|
const content = await response.text();
|
|
133
|
-
|
|
134
|
-
return { content, mimeType: contentType, isImage };
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
return content;
|
|
138
|
-
}
|
|
186
|
+
return { content, mimeType: contentType, isImage };
|
|
139
187
|
}
|
|
140
188
|
}
|
|
141
189
|
catch (error) {
|
|
142
190
|
// Clear the timeout to prevent memory leaks
|
|
143
191
|
clearTimeout(timeoutId);
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
throw new Error(
|
|
192
|
+
// Return error information instead of throwing
|
|
193
|
+
const errorMessage = error instanceof DOMException && error.name === 'AbortError'
|
|
194
|
+
? `URL fetch timed out after ${FETCH_TIMEOUT_MS}ms: ${url}`
|
|
195
|
+
: `Failed to fetch URL: ${error instanceof Error ? error.message : String(error)}`;
|
|
196
|
+
throw new Error(errorMessage);
|
|
149
197
|
}
|
|
150
198
|
}
|
|
151
199
|
/**
|
|
@@ -154,7 +202,7 @@ export async function readFileFromUrl(url, returnMetadata) {
|
|
|
154
202
|
* @param returnMetadata Whether to return metadata with the content
|
|
155
203
|
* @returns File content or file result with metadata
|
|
156
204
|
*/
|
|
157
|
-
export async function readFileFromDisk(filePath
|
|
205
|
+
export async function readFileFromDisk(filePath) {
|
|
158
206
|
// Import the MIME type utilities
|
|
159
207
|
const { getMimeType, isImageFile } = await import('./mime-types.js');
|
|
160
208
|
const validPath = await validatePath(filePath);
|
|
@@ -164,21 +212,18 @@ export async function readFileFromDisk(filePath, returnMetadata) {
|
|
|
164
212
|
const MAX_SIZE = 100 * 1024; // 100KB limit
|
|
165
213
|
if (stats.size > MAX_SIZE) {
|
|
166
214
|
const message = `File too large (${(stats.size / 1024).toFixed(2)}KB > ${MAX_SIZE / 1024}KB limit)`;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
return message;
|
|
176
|
-
}
|
|
215
|
+
return {
|
|
216
|
+
content: message,
|
|
217
|
+
mimeType: 'text/plain',
|
|
218
|
+
isImage: false
|
|
219
|
+
};
|
|
177
220
|
}
|
|
178
221
|
}
|
|
179
222
|
catch (error) {
|
|
223
|
+
console.error('error catch ' + error);
|
|
224
|
+
capture('server_read_file_error', { error: error });
|
|
180
225
|
// If we can't stat the file, continue anyway and let the read operation handle errors
|
|
181
|
-
console.error(`Failed to stat file ${validPath}:`, error);
|
|
226
|
+
//console.error(`Failed to stat file ${validPath}:`, error);
|
|
182
227
|
}
|
|
183
228
|
// Detect the MIME type based on file extension
|
|
184
229
|
const mimeType = getMimeType(validPath);
|
|
@@ -190,41 +235,28 @@ export async function readFileFromDisk(filePath, returnMetadata) {
|
|
|
190
235
|
// For image files, read as Buffer and convert to base64
|
|
191
236
|
const buffer = await fs.readFile(validPath);
|
|
192
237
|
const content = buffer.toString('base64');
|
|
193
|
-
|
|
194
|
-
return { content, mimeType, isImage };
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
return content;
|
|
198
|
-
}
|
|
238
|
+
return { content, mimeType, isImage };
|
|
199
239
|
}
|
|
200
240
|
else {
|
|
201
241
|
// For all other files, try to read as UTF-8 text
|
|
202
242
|
try {
|
|
203
243
|
const content = await fs.readFile(validPath, "utf-8");
|
|
204
|
-
|
|
205
|
-
return { content, mimeType, isImage };
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
return content;
|
|
209
|
-
}
|
|
244
|
+
return { content, mimeType, isImage };
|
|
210
245
|
}
|
|
211
246
|
catch (error) {
|
|
212
247
|
// If UTF-8 reading fails, treat as binary and return base64 but still as text
|
|
213
248
|
const buffer = await fs.readFile(validPath);
|
|
214
249
|
const content = `Binary file content (base64 encoded):\n${buffer.toString('base64')}`;
|
|
215
|
-
|
|
216
|
-
return { content, mimeType: 'text/plain', isImage: false };
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
return content;
|
|
220
|
-
}
|
|
250
|
+
return { content, mimeType: 'text/plain', isImage: false };
|
|
221
251
|
}
|
|
222
252
|
}
|
|
223
253
|
};
|
|
224
254
|
// Execute with timeout
|
|
225
|
-
const result = await withTimeout(readOperation(), FILE_READ_TIMEOUT, `Read file operation for ${filePath}`,
|
|
226
|
-
|
|
227
|
-
|
|
255
|
+
const result = await withTimeout(readOperation(), FILE_READ_TIMEOUT, `Read file operation for ${filePath}`, null);
|
|
256
|
+
if (result == null) {
|
|
257
|
+
// Handles the impossible case where withTimeout resolves to null instead of throwing
|
|
258
|
+
throw new Error('Failed to read the file');
|
|
259
|
+
}
|
|
228
260
|
return result;
|
|
229
261
|
}
|
|
230
262
|
/**
|
|
@@ -234,10 +266,10 @@ export async function readFileFromDisk(filePath, returnMetadata) {
|
|
|
234
266
|
* @param isUrl Whether the path is a URL
|
|
235
267
|
* @returns File content or file result with metadata
|
|
236
268
|
*/
|
|
237
|
-
export async function readFile(filePath,
|
|
269
|
+
export async function readFile(filePath, isUrl) {
|
|
238
270
|
return isUrl
|
|
239
|
-
? readFileFromUrl(filePath
|
|
240
|
-
: readFileFromDisk(filePath
|
|
271
|
+
? readFileFromUrl(filePath)
|
|
272
|
+
: readFileFromDisk(filePath);
|
|
241
273
|
}
|
|
242
274
|
export async function writeFile(filePath, content) {
|
|
243
275
|
const validPath = await validatePath(filePath);
|
|
@@ -247,7 +279,7 @@ export async function readMultipleFiles(paths) {
|
|
|
247
279
|
return Promise.all(paths.map(async (filePath) => {
|
|
248
280
|
try {
|
|
249
281
|
const validPath = await validatePath(filePath);
|
|
250
|
-
const fileResult = await readFile(validPath
|
|
282
|
+
const fileResult = await readFile(validPath);
|
|
251
283
|
return {
|
|
252
284
|
path: filePath,
|
|
253
285
|
content: typeof fileResult === 'string' ? fileResult : fileResult.content,
|
|
@@ -316,6 +348,5 @@ export async function getFileInfo(filePath) {
|
|
|
316
348
|
permissions: stats.mode.toString(8).slice(-3),
|
|
317
349
|
};
|
|
318
350
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
351
|
+
// This function has been replaced with configManager.getConfig()
|
|
352
|
+
// Use get_config tool to retrieve allowedDirectories
|
package/dist/tools/process.d.ts
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
text: string;
|
|
5
|
-
}>;
|
|
6
|
-
}>;
|
|
7
|
-
export declare function killProcess(args: unknown): Promise<{
|
|
8
|
-
content: {
|
|
9
|
-
type: string;
|
|
10
|
-
text: string;
|
|
11
|
-
}[];
|
|
12
|
-
}>;
|
|
1
|
+
import { ServerResult } from '../types.js';
|
|
2
|
+
export declare function listProcesses(): Promise<ServerResult>;
|
|
3
|
+
export declare function killProcess(args: unknown): Promise<ServerResult>;
|
package/dist/tools/process.js
CHANGED
|
@@ -27,13 +27,19 @@ export async function listProcesses() {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
catch (error) {
|
|
30
|
-
|
|
30
|
+
return {
|
|
31
|
+
content: [{ type: "text", text: `Error: Failed to list processes: ${error instanceof Error ? error.message : String(error)}` }],
|
|
32
|
+
isError: true,
|
|
33
|
+
};
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
36
|
export async function killProcess(args) {
|
|
34
37
|
const parsed = KillProcessArgsSchema.safeParse(args);
|
|
35
38
|
if (!parsed.success) {
|
|
36
|
-
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: "text", text: `Error: Invalid arguments for kill_process: ${parsed.error}` }],
|
|
41
|
+
isError: true,
|
|
42
|
+
};
|
|
37
43
|
}
|
|
38
44
|
try {
|
|
39
45
|
process.kill(parsed.data.pid);
|
|
@@ -42,6 +48,9 @@ export async function killProcess(args) {
|
|
|
42
48
|
};
|
|
43
49
|
}
|
|
44
50
|
catch (error) {
|
|
45
|
-
|
|
51
|
+
return {
|
|
52
|
+
content: [{ type: "text", text: `Error: Failed to kill process: ${error instanceof Error ? error.message : String(error)}` }],
|
|
53
|
+
isError: true,
|
|
54
|
+
};
|
|
46
55
|
}
|
|
47
56
|
}
|
package/dist/tools/schemas.d.ts
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
export declare const GetConfigArgsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
3
|
+
export declare const SetConfigValueArgsSchema: z.ZodObject<{
|
|
4
|
+
key: z.ZodString;
|
|
5
|
+
value: z.ZodAny;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
key: string;
|
|
8
|
+
value?: any;
|
|
9
|
+
}, {
|
|
10
|
+
key: string;
|
|
11
|
+
value?: any;
|
|
12
|
+
}>;
|
|
13
|
+
export declare const ListProcessesArgsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
2
14
|
export declare const ExecuteCommandArgsSchema: z.ZodObject<{
|
|
3
15
|
command: z.ZodString;
|
|
4
16
|
timeout_ms: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
shell: z.ZodOptional<z.ZodString>;
|
|
5
18
|
}, "strip", z.ZodTypeAny, {
|
|
6
19
|
command: string;
|
|
7
20
|
timeout_ms?: number | undefined;
|
|
21
|
+
shell?: string | undefined;
|
|
8
22
|
}, {
|
|
9
23
|
command: string;
|
|
10
24
|
timeout_ms?: number | undefined;
|
|
25
|
+
shell?: string | undefined;
|
|
11
26
|
}>;
|
|
12
27
|
export declare const ReadOutputArgsSchema: z.ZodObject<{
|
|
13
28
|
pid: z.ZodNumber;
|
|
@@ -31,20 +46,6 @@ export declare const KillProcessArgsSchema: z.ZodObject<{
|
|
|
31
46
|
}, {
|
|
32
47
|
pid: number;
|
|
33
48
|
}>;
|
|
34
|
-
export declare const BlockCommandArgsSchema: z.ZodObject<{
|
|
35
|
-
command: z.ZodString;
|
|
36
|
-
}, "strip", z.ZodTypeAny, {
|
|
37
|
-
command: string;
|
|
38
|
-
}, {
|
|
39
|
-
command: string;
|
|
40
|
-
}>;
|
|
41
|
-
export declare const UnblockCommandArgsSchema: z.ZodObject<{
|
|
42
|
-
command: z.ZodString;
|
|
43
|
-
}, "strip", z.ZodTypeAny, {
|
|
44
|
-
command: string;
|
|
45
|
-
}, {
|
|
46
|
-
command: string;
|
|
47
|
-
}>;
|
|
48
49
|
export declare const ReadFileArgsSchema: z.ZodObject<{
|
|
49
50
|
path: z.ZodString;
|
|
50
51
|
isUrl: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
package/dist/tools/schemas.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
console.error("Loading schemas.ts");
|
|
3
|
+
// Config tools schemas
|
|
4
|
+
export const GetConfigArgsSchema = z.object({});
|
|
5
|
+
export const SetConfigValueArgsSchema = z.object({
|
|
6
|
+
key: z.string(),
|
|
7
|
+
value: z.any(),
|
|
8
|
+
});
|
|
9
|
+
// Empty schemas
|
|
10
|
+
export const ListProcessesArgsSchema = z.object({});
|
|
2
11
|
// Terminal tools schemas
|
|
3
12
|
export const ExecuteCommandArgsSchema = z.object({
|
|
4
13
|
command: z.string(),
|
|
5
14
|
timeout_ms: z.number().optional(),
|
|
15
|
+
shell: z.string().optional(),
|
|
6
16
|
});
|
|
7
17
|
export const ReadOutputArgsSchema = z.object({
|
|
8
18
|
pid: z.number(),
|
|
@@ -14,12 +24,6 @@ export const ListSessionsArgsSchema = z.object({});
|
|
|
14
24
|
export const KillProcessArgsSchema = z.object({
|
|
15
25
|
pid: z.number(),
|
|
16
26
|
});
|
|
17
|
-
export const BlockCommandArgsSchema = z.object({
|
|
18
|
-
command: z.string(),
|
|
19
|
-
});
|
|
20
|
-
export const UnblockCommandArgsSchema = z.object({
|
|
21
|
-
command: z.string(),
|
|
22
|
-
});
|
|
23
27
|
// Filesystem tools schemas
|
|
24
28
|
export const ReadFileArgsSchema = z.object({
|
|
25
29
|
path: z.string(),
|
package/dist/tools/search.js
CHANGED
|
@@ -3,6 +3,7 @@ import path from 'path';
|
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
4
|
import { validatePath } from './filesystem.js';
|
|
5
5
|
import { rgPath } from '@vscode/ripgrep';
|
|
6
|
+
import { capture } from "../utils.js";
|
|
6
7
|
// Function to search file contents using ripgrep
|
|
7
8
|
export async function searchCode(options) {
|
|
8
9
|
const { rootPath, pattern, filePattern, ignoreCase = true, maxResults = 1000, includeHidden = false, contextLines = 0 } = options;
|
|
@@ -77,8 +78,8 @@ export async function searchCode(options) {
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
catch (e) {
|
|
80
|
-
|
|
81
|
-
console.error(
|
|
81
|
+
capture('server_request_error', { error: 'Error parsing ripgrep output:' + e });
|
|
82
|
+
console.error();
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
resolve(results);
|
|
@@ -164,7 +165,6 @@ export async function searchTextInFiles(options) {
|
|
|
164
165
|
return await searchCode(options);
|
|
165
166
|
}
|
|
166
167
|
catch (error) {
|
|
167
|
-
console.error('Ripgrep search failed, falling back to native implementation:', error);
|
|
168
168
|
return searchCodeFallback({
|
|
169
169
|
...options,
|
|
170
170
|
excludeDirs: ['node_modules', '.git', 'dist']
|
package/dist/types.d.ts
CHANGED
|
@@ -29,3 +29,15 @@ export interface CompletedSession {
|
|
|
29
29
|
startTime: Date;
|
|
30
30
|
endTime: Date;
|
|
31
31
|
}
|
|
32
|
+
export interface ServerResponseContent {
|
|
33
|
+
type: string;
|
|
34
|
+
text?: string;
|
|
35
|
+
data?: string;
|
|
36
|
+
mimeType?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface ServerResult {
|
|
39
|
+
content: ServerResponseContent[];
|
|
40
|
+
isError?: boolean;
|
|
41
|
+
_meta?: Record<string, unknown>;
|
|
42
|
+
}
|
|
43
|
+
export type ToolHandler<T = unknown> = (args: T) => Promise<ServerResult>;
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send an event to Google Analytics
|
|
3
|
+
* @param event Event name
|
|
4
|
+
* @param properties Optional event properties
|
|
5
|
+
*/
|
|
1
6
|
export declare const capture: (event: string, properties?: any) => void;
|
|
2
7
|
/**
|
|
3
8
|
* Executes a promise with a timeout. If the promise doesn't resolve or reject within
|