@wonderwhy-er/desktop-commander 0.1.30 → 0.1.32

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 CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  [![Discord](https://img.shields.io/badge/Join%20Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/kQ27sNnZr7)
9
9
 
10
- Short version. Two key things. Terminal commands and diff based file editing.
10
+ Short version. Four key things. Terminal commands, diff based file editing, ripgrep based text search in folders, ability to read files from urls
11
11
 
12
12
 
13
13
  ![Desktop Commander MCP](https://raw.githubusercontent.com/wonderwhy-er/ClaudeComputerCommander/main/header.png)
@@ -63,7 +63,14 @@ npx @wonderwhy-er/desktop-commander@latest setup --debug
63
63
  ```
64
64
  Restart Claude if running
65
65
 
66
- ### Option 2: Installing via Smithery
66
+ ### Option 2: Using bash script installer (macOS)
67
+ For macOS users, you can use our automated bash installer which will check your Node.js version, install it if needed, and automatically configure Desktop Commander:
68
+ ```
69
+ curl -fsSL https://raw.githubusercontent.com/wonderwhy-er/DesktopCommanderMCP/refs/heads/main/install.sh | bash
70
+ ```
71
+ This script handles all dependencies and configuration automatically for a seamless setup experience.
72
+
73
+ ### Option 3: Installing via Smithery
67
74
 
68
75
  To install Desktop Commander for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@wonderwhy-er/desktop-commander):
69
76
 
@@ -71,7 +78,7 @@ To install Desktop Commander for Claude Desktop automatically via [Smithery](htt
71
78
  npx -y @smithery/cli install @wonderwhy-er/desktop-commander --client claude
72
79
  ```
73
80
 
74
- ### Option 3: Add to claude_desktop_config by hand
81
+ ### Option 4: Add to claude_desktop_config by hand
75
82
  Add this entry to your claude_desktop_config.json:
76
83
 
77
84
  - On Mac: `~/Library/Application\ Support/Claude/claude_desktop_config.json`
@@ -93,7 +100,7 @@ Add this entry to your claude_desktop_config.json:
93
100
  ```
94
101
  Restart Claude if running
95
102
 
96
- ### Option 4: Checkout locally
103
+ ### Option 5: Checkout locally
97
104
  1. Clone and build:
98
105
  ```bash
99
106
  git clone https://github.com/wonderwhy-er/ClaudeComputerCommander.git
@@ -108,6 +115,12 @@ The setup command will:
108
115
  - Configure Claude's desktop app
109
116
  - Add MCP servers to Claude's config if needed
110
117
 
118
+ ### Updating Desktop Commander
119
+
120
+ When installed through npx (Option 1) or Smithery (Option 2), Desktop Commander will automatically update to the latest version whenever you restart Claude. No manual update process is needed.
121
+
122
+ For manual installations, you can update by running the setup command again.
123
+
111
124
  ## Usage
112
125
 
113
126
  The server provides these tool categories:
@@ -122,7 +135,7 @@ The server provides these tool categories:
122
135
  - `block_command`/`unblock_command`: Manage command blacklist
123
136
 
124
137
  ### Filesystem Tools
125
- - `read_file`/`write_file`: File operations
138
+ - `read_file`/`write_file`: Read files from local filesystem or URLs (supports viewing PNG, JPEG, GIF, and WebP images directly in Claude)
126
139
  - `create_directory`/`list_directory`: Directory management
127
140
  - `move_file`: Move/rename files
128
141
  - `search_files`: Pattern-based file search
@@ -153,6 +166,14 @@ console.log("new message");
153
166
  >>>>>>> REPLACE
154
167
  ```
155
168
 
169
+ ### URL Support
170
+ - `read_file` can now fetch content from both local files and URLs
171
+ - Example: `read_file` with `isUrl: true` parameter to read from web resources
172
+ - Handles both text and image content from remote sources
173
+ - Images (local or from URLs) are displayed visually in Claude's interface, not as text
174
+ - Claude can see and analyze the actual image content
175
+ - Default 30-second timeout for URL requests
176
+
156
177
  ## Handling Long-Running Commands
157
178
 
158
179
  For commands that may take a while:
@@ -208,6 +229,7 @@ This project extends the MCP Filesystem Server to enable:
208
229
  Created as part of exploring Claude MCPs: https://youtube.com/live/TlbjFDbl5Us
209
230
 
210
231
  ## DONE
232
+ - **07-04-2025 Added URL support** - `read_file` command can now fetch content from URLs
211
233
  - **28-03-2025 Fixed "Watching /" JSON error** - Implemented custom stdio transport to handle non-JSON messages and prevent server crashes
212
234
  - **25-03-2025 Better code search** ([merged](https://github.com/wonderwhy-er/ClaudeDesktopCommander/pull/17)) - Enhanced code exploration with context-aware results
213
235
 
@@ -252,7 +274,7 @@ Join our [Discord server](https://discord.gg/kQ27sNnZr7) to get help, share feed
252
274
  https://www.youtube.com/watch?v=ly3bed99Dy8&lc=UgztdHvDMqTb9jiqnf54AaABAg](https://www.youtube.com/watch?v=ly3bed99Dy8&lc=UgztdHvDMqTb9jiqnf54AaABAg
253
275
  )
254
276
 
255
- [![Great! I just used Windsurf, bought license a week ago, for upgrading old fullstack socket project and it works many times good or ok but also many times runs away in cascade and have to revert all changes loosing hundereds of cascade tokens. In just a week down to less than 100 tokens and do not want to buy only 300 tokens for 10$. This Claude MCP ,bought claude Pro finally needed but wanted very good reason to also have next to ChatGPT, and now can code as much as I want not worrying about token cost.
277
+ [![Great! I just used Windsurf, bought license a week ago, for upgrading old fullstack socket project and it works many times good or ok but also many times runs away in cascade and have to revert all changes losing hundereds of cascade tokens. In just a week down to less than 100 tokens and do not want to buy only 300 tokens for 10$. This Claude MCP ,bought claude Pro finally needed but wanted very good reason to also have next to ChatGPT, and now can code as much as I want not worrying about token cost.
256
278
  Also this is much more than code editing it is much more thank you for great video!](https://raw.githubusercontent.com/wonderwhy-er/ClaudeComputerCommander/main/testemonials/img_2.png)
257
279
  https://www.youtube.com/watch?v=ly3bed99Dy8&lc=UgyQFTmYLJ4VBwIlmql4AaABAg](https://www.youtube.com/watch?v=ly3bed99Dy8&lc=UgyQFTmYLJ4VBwIlmql4AaABAg)
258
280
 
@@ -293,6 +315,9 @@ Unlike IDE-focused tools, Claude Desktop Commander provides a solution-centric a
293
315
  ### Do I need to pay for API credits?
294
316
  No. This tool works with Claude Desktop's standard Pro subscription ($20/month), not with API calls, so you won't incur additional costs beyond the subscription fee.
295
317
 
318
+ ### Does Desktop Commander automatically update?
319
+ Yes, when installed through npx or Smithery, Desktop Commander automatically updates to the latest version when you restart Claude. No manual update process is needed.
320
+
296
321
  ### What are the most common use cases?
297
322
  - Exploring and understanding complex codebases
298
323
  - Generating diagrams and documentation
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Handle block_command command
3
+ */
4
+ export declare function handleBlockCommand(args: unknown): Promise<{
5
+ content: {
6
+ type: string;
7
+ text: boolean;
8
+ }[];
9
+ }>;
10
+ /**
11
+ * Handle unblock_command command
12
+ */
13
+ export declare function handleUnblockCommand(args: unknown): Promise<{
14
+ content: {
15
+ type: string;
16
+ text: boolean;
17
+ }[];
18
+ }>;
19
+ /**
20
+ * Handle list_blocked_commands command
21
+ */
22
+ export declare function handleListBlockedCommands(): {
23
+ content: {
24
+ type: string;
25
+ text: string;
26
+ }[];
27
+ };
@@ -0,0 +1,31 @@
1
+ import { commandManager } from '../command-manager.js';
2
+ import { BlockCommandArgsSchema, UnblockCommandArgsSchema } from '../tools/schemas.js';
3
+ /**
4
+ * Handle block_command command
5
+ */
6
+ export async function handleBlockCommand(args) {
7
+ const parsed = BlockCommandArgsSchema.parse(args);
8
+ const blockResult = await commandManager.blockCommand(parsed.command);
9
+ return {
10
+ content: [{ type: "text", text: blockResult }],
11
+ };
12
+ }
13
+ /**
14
+ * Handle unblock_command command
15
+ */
16
+ export async function handleUnblockCommand(args) {
17
+ const parsed = UnblockCommandArgsSchema.parse(args);
18
+ const unblockResult = await commandManager.unblockCommand(parsed.command);
19
+ return {
20
+ content: [{ type: "text", text: unblockResult }],
21
+ };
22
+ }
23
+ /**
24
+ * Handle list_blocked_commands command
25
+ */
26
+ export function handleListBlockedCommands() {
27
+ const blockedCommands = commandManager.listBlockedCommands();
28
+ return {
29
+ content: [{ type: "text", text: blockedCommands.join('\n') }],
30
+ };
31
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Handle edit_block command
3
+ */
4
+ export declare function handleEditBlock(args: unknown): Promise<{
5
+ content: {
6
+ type: string;
7
+ text: string;
8
+ }[];
9
+ }>;
10
+ /**
11
+ * Handle search_code command
12
+ */
13
+ export declare function handleSearchCode(args: unknown): Promise<{
14
+ content: {
15
+ type: string;
16
+ text: string;
17
+ }[];
18
+ }>;
@@ -0,0 +1,72 @@
1
+ import { parseEditBlock, performSearchReplace } from '../tools/edit.js';
2
+ import { searchTextInFiles } from '../tools/search.js';
3
+ import { EditBlockArgsSchema, SearchCodeArgsSchema } from '../tools/schemas.js';
4
+ import { withTimeout } from '../utils.js';
5
+ /**
6
+ * Handle edit_block command
7
+ */
8
+ export async function handleEditBlock(args) {
9
+ const parsed = EditBlockArgsSchema.parse(args);
10
+ const { filePath, searchReplace } = await parseEditBlock(parsed.blockContent);
11
+ await performSearchReplace(filePath, searchReplace);
12
+ return {
13
+ content: [{ type: "text", text: `Successfully applied edit to ${filePath}` }],
14
+ };
15
+ }
16
+ /**
17
+ * Handle search_code command
18
+ */
19
+ export async function handleSearchCode(args) {
20
+ const parsed = SearchCodeArgsSchema.parse(args);
21
+ const timeoutMs = parsed.timeoutMs || 30000; // 30 seconds default
22
+ // Apply timeout at the handler level
23
+ const searchOperation = async () => {
24
+ return await searchTextInFiles({
25
+ rootPath: parsed.path,
26
+ pattern: parsed.pattern,
27
+ filePattern: parsed.filePattern,
28
+ ignoreCase: parsed.ignoreCase,
29
+ maxResults: parsed.maxResults,
30
+ includeHidden: parsed.includeHidden,
31
+ contextLines: parsed.contextLines,
32
+ // Don't pass timeoutMs down to the implementation
33
+ });
34
+ };
35
+ // Use withTimeout at the handler level
36
+ const results = await withTimeout(searchOperation(), timeoutMs, 'Code search operation', [] // Empty array as default on timeout
37
+ );
38
+ // If timeout occurred, try to terminate the ripgrep process
39
+ if (results.length === 0 && globalThis.currentSearchProcess) {
40
+ try {
41
+ console.log(`Terminating timed out search process (PID: ${globalThis.currentSearchProcess.pid})`);
42
+ globalThis.currentSearchProcess.kill();
43
+ delete globalThis.currentSearchProcess;
44
+ }
45
+ catch (error) {
46
+ console.error('Error terminating search process:', error);
47
+ }
48
+ }
49
+ if (results.length === 0) {
50
+ if (timeoutMs > 0) {
51
+ return {
52
+ content: [{ type: "text", text: `No matches found or search timed out after ${timeoutMs}ms.` }],
53
+ };
54
+ }
55
+ return {
56
+ content: [{ type: "text", text: "No matches found" }],
57
+ };
58
+ }
59
+ // Format the results in a VS Code-like format
60
+ let currentFile = "";
61
+ let formattedResults = "";
62
+ results.forEach(result => {
63
+ if (result.file !== currentFile) {
64
+ formattedResults += `\n${result.file}:\n`;
65
+ currentFile = result.file;
66
+ }
67
+ formattedResults += ` ${result.line}: ${result.match}\n`;
68
+ });
69
+ return {
70
+ content: [{ type: "text", text: formattedResults.trim() }],
71
+ };
72
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Handle read_file command
3
+ */
4
+ export declare function handleReadFile(args: unknown): Promise<{
5
+ content: ({
6
+ type: string;
7
+ text: string;
8
+ data?: undefined;
9
+ mimeType?: undefined;
10
+ } | {
11
+ type: string;
12
+ data: string;
13
+ mimeType: string;
14
+ text?: undefined;
15
+ })[];
16
+ }>;
17
+ /**
18
+ * Handle read_multiple_files command
19
+ */
20
+ export declare function handleReadMultipleFiles(args: unknown): Promise<{
21
+ content: {
22
+ type: string;
23
+ text?: string;
24
+ data?: string;
25
+ mimeType?: string;
26
+ }[];
27
+ }>;
28
+ /**
29
+ * Handle write_file command
30
+ */
31
+ export declare function handleWriteFile(args: unknown): Promise<{
32
+ content: {
33
+ type: string;
34
+ text: string;
35
+ }[];
36
+ }>;
37
+ /**
38
+ * Handle create_directory command
39
+ */
40
+ export declare function handleCreateDirectory(args: unknown): Promise<{
41
+ content: {
42
+ type: string;
43
+ text: string;
44
+ }[];
45
+ }>;
46
+ /**
47
+ * Handle list_directory command
48
+ */
49
+ export declare function handleListDirectory(args: unknown): Promise<{
50
+ content: {
51
+ type: string;
52
+ text: string;
53
+ }[];
54
+ }>;
55
+ /**
56
+ * Handle move_file command
57
+ */
58
+ export declare function handleMoveFile(args: unknown): Promise<{
59
+ content: {
60
+ type: string;
61
+ text: string;
62
+ }[];
63
+ }>;
64
+ /**
65
+ * Handle search_files command
66
+ */
67
+ export declare function handleSearchFiles(args: unknown): Promise<{
68
+ content: {
69
+ type: string;
70
+ text: string;
71
+ }[];
72
+ }>;
73
+ /**
74
+ * Handle get_file_info command
75
+ */
76
+ export declare function handleGetFileInfo(args: unknown): Promise<{
77
+ content: {
78
+ type: string;
79
+ text: string;
80
+ }[];
81
+ }>;
82
+ /**
83
+ * Handle list_allowed_directories command
84
+ */
85
+ export declare function handleListAllowedDirectories(): {
86
+ content: {
87
+ type: string;
88
+ text: string;
89
+ }[];
90
+ };
@@ -0,0 +1,179 @@
1
+ import { readFile, readMultipleFiles, writeFile, createDirectory, listDirectory, moveFile, searchFiles, getFileInfo, listAllowedDirectories } from '../tools/filesystem.js';
2
+ import { withTimeout } from '../utils.js';
3
+ import { ReadFileArgsSchema, ReadMultipleFilesArgsSchema, WriteFileArgsSchema, CreateDirectoryArgsSchema, ListDirectoryArgsSchema, MoveFileArgsSchema, SearchFilesArgsSchema, GetFileInfoArgsSchema } from '../tools/schemas.js';
4
+ /**
5
+ * Handle read_file command
6
+ */
7
+ export async function handleReadFile(args) {
8
+ const HANDLER_TIMEOUT = 60000; // 60 seconds total operation timeout
9
+ const readFileOperation = async () => {
10
+ const parsed = ReadFileArgsSchema.parse(args);
11
+ // Explicitly cast the result to FileResult since we're passing true
12
+ const fileResult = await readFile(parsed.path, true, parsed.isUrl);
13
+ if (fileResult.isImage) {
14
+ // For image files, return as an image content type
15
+ return {
16
+ content: [
17
+ {
18
+ type: "text",
19
+ text: `Image file: ${parsed.path} (${fileResult.mimeType})\n`
20
+ },
21
+ {
22
+ type: "image",
23
+ data: fileResult.content,
24
+ mimeType: fileResult.mimeType
25
+ }
26
+ ],
27
+ };
28
+ }
29
+ else {
30
+ // For all other files, return as text
31
+ return {
32
+ content: [{ type: "text", text: fileResult.content }],
33
+ };
34
+ }
35
+ };
36
+ // Execute with timeout at the handler level
37
+ return await withTimeout(readFileOperation(), HANDLER_TIMEOUT, 'Read file handler operation', {
38
+ content: [{ type: "text", text: `Operation timed out after ${HANDLER_TIMEOUT / 1000} seconds. The file might be too large or on a slow/unresponsive storage device.` }],
39
+ });
40
+ }
41
+ /**
42
+ * Handle read_multiple_files command
43
+ */
44
+ export async function handleReadMultipleFiles(args) {
45
+ const parsed = ReadMultipleFilesArgsSchema.parse(args);
46
+ const fileResults = await readMultipleFiles(parsed.paths);
47
+ // Create a text summary of all files
48
+ const textSummary = fileResults.map(result => {
49
+ if (result.error) {
50
+ return `${result.path}: Error - ${result.error}`;
51
+ }
52
+ else if (result.mimeType) {
53
+ return `${result.path}: ${result.mimeType} ${result.isImage ? '(image)' : '(text)'}`;
54
+ }
55
+ else {
56
+ return `${result.path}: Unknown type`;
57
+ }
58
+ }).join("\n");
59
+ // Create content items for each file
60
+ const contentItems = [];
61
+ // Add the text summary
62
+ contentItems.push({ type: "text", text: textSummary });
63
+ // Add each file content
64
+ for (const result of fileResults) {
65
+ if (!result.error && result.content !== undefined) {
66
+ if (result.isImage && result.mimeType) {
67
+ // For image files, add an image content item
68
+ contentItems.push({
69
+ type: "image",
70
+ data: result.content,
71
+ mimeType: result.mimeType
72
+ });
73
+ }
74
+ else {
75
+ // For text files, add a text summary
76
+ contentItems.push({
77
+ type: "text",
78
+ text: `\n--- ${result.path} contents: ---\n${result.content}`
79
+ });
80
+ }
81
+ }
82
+ }
83
+ return { content: contentItems };
84
+ }
85
+ /**
86
+ * Handle write_file command
87
+ */
88
+ export async function handleWriteFile(args) {
89
+ const parsed = WriteFileArgsSchema.parse(args);
90
+ await writeFile(parsed.path, parsed.content);
91
+ return {
92
+ content: [{ type: "text", text: `Successfully wrote to ${parsed.path}` }],
93
+ };
94
+ }
95
+ /**
96
+ * Handle create_directory command
97
+ */
98
+ export async function handleCreateDirectory(args) {
99
+ const parsed = CreateDirectoryArgsSchema.parse(args);
100
+ await createDirectory(parsed.path);
101
+ return {
102
+ content: [{ type: "text", text: `Successfully created directory ${parsed.path}` }],
103
+ };
104
+ }
105
+ /**
106
+ * Handle list_directory command
107
+ */
108
+ export async function handleListDirectory(args) {
109
+ const parsed = ListDirectoryArgsSchema.parse(args);
110
+ const entries = await listDirectory(parsed.path);
111
+ return {
112
+ content: [{ type: "text", text: entries.join('\n') }],
113
+ };
114
+ }
115
+ /**
116
+ * Handle move_file command
117
+ */
118
+ export async function handleMoveFile(args) {
119
+ const parsed = MoveFileArgsSchema.parse(args);
120
+ await moveFile(parsed.source, parsed.destination);
121
+ return {
122
+ content: [{ type: "text", text: `Successfully moved ${parsed.source} to ${parsed.destination}` }],
123
+ };
124
+ }
125
+ /**
126
+ * Handle search_files command
127
+ */
128
+ export async function handleSearchFiles(args) {
129
+ const parsed = SearchFilesArgsSchema.parse(args);
130
+ const timeoutMs = parsed.timeoutMs || 30000; // 30 seconds default
131
+ // Apply timeout at the handler level
132
+ const searchOperation = async () => {
133
+ return await searchFiles(parsed.path, parsed.pattern);
134
+ };
135
+ // Use withTimeout at the handler level
136
+ const results = await withTimeout(searchOperation(), timeoutMs, 'File search operation', [] // Empty array as default on timeout
137
+ );
138
+ if (results.length === 0) {
139
+ // Similar approach as in handleSearchCode
140
+ if (timeoutMs > 0) {
141
+ return {
142
+ content: [{ type: "text", text: `No matches found or search timed out after ${timeoutMs}ms.` }],
143
+ };
144
+ }
145
+ return {
146
+ content: [{ type: "text", text: "No matches found" }],
147
+ };
148
+ }
149
+ return {
150
+ content: [{ type: "text", text: results.join('\n') }],
151
+ };
152
+ }
153
+ /**
154
+ * Handle get_file_info command
155
+ */
156
+ export async function handleGetFileInfo(args) {
157
+ const parsed = GetFileInfoArgsSchema.parse(args);
158
+ const info = await getFileInfo(parsed.path);
159
+ return {
160
+ content: [{
161
+ type: "text",
162
+ text: Object.entries(info)
163
+ .map(([key, value]) => `${key}: ${value}`)
164
+ .join('\n')
165
+ }],
166
+ };
167
+ }
168
+ /**
169
+ * Handle list_allowed_directories command
170
+ */
171
+ export function handleListAllowedDirectories() {
172
+ const directories = listAllowedDirectories();
173
+ return {
174
+ content: [{
175
+ type: "text",
176
+ text: `Allowed directories:\n${directories.join('\n')}`
177
+ }],
178
+ };
179
+ }
@@ -0,0 +1,5 @@
1
+ export * from './filesystem-handlers.js';
2
+ export * from './terminal-handlers.js';
3
+ export * from './process-handlers.js';
4
+ export * from './command-handlers.js';
5
+ export * from './edit-search-handlers.js';
@@ -0,0 +1,6 @@
1
+ // Export all handlers from their respective files
2
+ export * from './filesystem-handlers.js';
3
+ export * from './terminal-handlers.js';
4
+ export * from './process-handlers.js';
5
+ export * from './command-handlers.js';
6
+ export * from './edit-search-handlers.js';
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Handle list_processes command
3
+ */
4
+ export declare function handleListProcesses(): Promise<{
5
+ content: Array<{
6
+ type: string;
7
+ text: string;
8
+ }>;
9
+ }>;
10
+ /**
11
+ * Handle kill_process command
12
+ */
13
+ export declare function handleKillProcess(args: unknown): Promise<{
14
+ content: {
15
+ type: string;
16
+ text: string;
17
+ }[];
18
+ }>;
@@ -0,0 +1,15 @@
1
+ import { listProcesses, killProcess } from '../tools/process.js';
2
+ import { KillProcessArgsSchema } from '../tools/schemas.js';
3
+ /**
4
+ * Handle list_processes command
5
+ */
6
+ export async function handleListProcesses() {
7
+ return listProcesses();
8
+ }
9
+ /**
10
+ * Handle kill_process command
11
+ */
12
+ export async function handleKillProcess(args) {
13
+ const parsed = KillProcessArgsSchema.parse(args);
14
+ return killProcess(parsed);
15
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Handle execute_command command
3
+ */
4
+ export declare function handleExecuteCommand(args: unknown): Promise<{
5
+ content: {
6
+ type: string;
7
+ text: string;
8
+ }[];
9
+ }>;
10
+ /**
11
+ * Handle read_output command
12
+ */
13
+ export declare function handleReadOutput(args: unknown): Promise<{
14
+ content: {
15
+ type: string;
16
+ text: string;
17
+ }[];
18
+ }>;
19
+ /**
20
+ * Handle force_terminate command
21
+ */
22
+ export declare function handleForceTerminate(args: unknown): Promise<{
23
+ content: {
24
+ type: string;
25
+ text: string;
26
+ }[];
27
+ }>;
28
+ /**
29
+ * Handle list_sessions command
30
+ */
31
+ export declare function handleListSessions(): Promise<{
32
+ content: {
33
+ type: string;
34
+ text: string;
35
+ }[];
36
+ }>;
@@ -0,0 +1,29 @@
1
+ import { executeCommand, readOutput, forceTerminate, listSessions } from '../tools/execute.js';
2
+ import { ExecuteCommandArgsSchema, ReadOutputArgsSchema, ForceTerminateArgsSchema } from '../tools/schemas.js';
3
+ /**
4
+ * Handle execute_command command
5
+ */
6
+ export async function handleExecuteCommand(args) {
7
+ const parsed = ExecuteCommandArgsSchema.parse(args);
8
+ return executeCommand(parsed);
9
+ }
10
+ /**
11
+ * Handle read_output command
12
+ */
13
+ export async function handleReadOutput(args) {
14
+ const parsed = ReadOutputArgsSchema.parse(args);
15
+ return readOutput(parsed);
16
+ }
17
+ /**
18
+ * Handle force_terminate command
19
+ */
20
+ export async function handleForceTerminate(args) {
21
+ const parsed = ForceTerminateArgsSchema.parse(args);
22
+ return forceTerminate(parsed);
23
+ }
24
+ /**
25
+ * Handle list_sessions command
26
+ */
27
+ export async function handleListSessions() {
28
+ return listSessions();
29
+ }