skydeckai-code 0.1.35__py3-none-any.whl → 0.1.37__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skydeckai-code
3
- Version: 0.1.35
3
+ Version: 0.1.37
4
4
  Summary: This MCP server provides a comprehensive set of tools for AI-driven Development workflows including file operations, code analysis, multi-language execution, web content fetching with HTML-to-markdown conversion, multi-engine web search, code content searching, and system information retrieval.
5
5
  Project-URL: Homepage, https://github.com/skydeckai/skydeckai-code
6
6
  Project-URL: Repository, https://github.com/skydeckai/skydeckai-code
@@ -16,8 +16,6 @@ Requires-Dist: mcp>=1.6.0
16
16
  Requires-Dist: mss>=10.0.0
17
17
  Requires-Dist: pillow>=11.1.0
18
18
  Requires-Dist: psutil>=7.0.0
19
- Requires-Dist: pygetwindow>=0.0.9
20
- Requires-Dist: pyobjc-framework-quartz>=11.0
21
19
  Requires-Dist: requests>=2.32.3
22
20
  Requires-Dist: tree-sitter-c-sharp>=0.23.1
23
21
  Requires-Dist: tree-sitter-cpp>=0.23.4
@@ -31,6 +29,10 @@ Requires-Dist: tree-sitter-ruby>=0.23.1
31
29
  Requires-Dist: tree-sitter-rust==0.23.2
32
30
  Requires-Dist: tree-sitter-typescript>=0.23.2
33
31
  Requires-Dist: tree-sitter>=0.24.0
32
+ Provides-Extra: macos
33
+ Requires-Dist: pyobjc-framework-quartz>=11.0; extra == 'macos'
34
+ Provides-Extra: windows
35
+ Requires-Dist: pygetwindow>=0.0.9; extra == 'windows'
34
36
  Description-Content-Type: text/markdown
35
37
 
36
38
  # SkyDeckAI Code
@@ -76,7 +78,6 @@ If you're using SkyDeck AI Helper app, you can search for "SkyDeckAI Code" and i
76
78
  - File system operations (read, write, edit, move, copy, delete)
77
79
  - Directory management and traversal
78
80
  - Multi-language code analysis using tree-sitter
79
- - Code linting and issue detection for Python and JavaScript/TypeScript
80
81
  - Code content searching with regex pattern matching
81
82
  - Multi-language code execution with safety measures
82
83
  - Web content fetching from APIs and websites with HTML-to-markdown conversion
@@ -86,31 +87,67 @@ If you're using SkyDeck AI Helper app, you can search for "SkyDeckAI Code" and i
86
87
  - Screenshot and screen context tools
87
88
  - Image handling tools
88
89
 
89
- ## Available Tools
90
+ ## Available Tools (26)
91
+
92
+ | Category | Tool Name | Description |
93
+ | ---------------- | -------------------------- | -------------------------------------------- |
94
+ | **File System** | `get_allowed_directory` | Get the current working directory path |
95
+ | | `update_allowed_directory` | Change the working directory |
96
+ | | `create_directory` | Create a new directory or nested directories |
97
+ | | `write_file` | Create or overwrite a file with new content |
98
+ | | `edit_file` | Make line-based edits to a text file |
99
+ | | `read_file` | Read the contents of one or more files |
100
+ | | `list_directory` | Get listing of files and directories |
101
+ | | `move_file` | Move or rename a file or directory |
102
+ | | `copy_file` | Copy a file or directory to a new location |
103
+ | | `search_files` | Search for files matching a name pattern |
104
+ | | `delete_file` | Delete a file or empty directory |
105
+ | | `get_file_info` | Get detailed file metadata |
106
+ | | `directory_tree` | Get a recursive tree view of directories |
107
+ | | `read_image_file` | Read an image file as base64 data |
108
+ | **Code Tools** | `codebase_mapper` | Analyze code structure across files |
109
+ | | `search_code` | Find text patterns in code files |
110
+ | | `execute_code` | Run code in various languages |
111
+ | | `execute_shell_script` | Run shell/bash scripts |
112
+ | **Web Tools** | `web_fetch` | Get content from a URL |
113
+ | | `web_search` | Perform a web search |
114
+ | **Screen Tools** | `capture_screenshot` | Take a screenshot of screen or window |
115
+ | | `get_active_apps` | List running applications |
116
+ | | `get_available_windows` | List all open windows |
117
+ | **System** | `get_system_info` | Get detailed system information |
118
+ | **Utility** | `batch_tools` | Run multiple tool operations together |
119
+ | | `think` | Document reasoning without making changes |
120
+
121
+ ## Detailed Tool Documentation
90
122
 
91
123
  ### Basic File Operations
92
124
 
93
- | Tool | Parameters | Returns |
94
- | ------------------- | -------------------------------------------------------- | --------------------------------------------- |
95
- | read_file | path: string, offset?: integer, limit?: integer | File content (whole or partial) |
96
- | read_multiple_files | paths: string[] | Multiple file contents with headers |
97
- | write_file | path: string, content: string | Success confirmation |
98
- | move_file | source: string, destination: string | Success confirmation |
99
- | copy_file | source: string, destination: string, recursive?: boolean | Success confirmation |
100
- | delete_file | path: string | Success confirmation |
101
- | get_file_info | path: string | File metadata (size, timestamps, permissions) |
125
+ | Tool | Parameters | Returns |
126
+ | ------------- | ---------------------------------------------------------- | --------------------------------------------- |
127
+ | read_file | files: [{path: string, offset?: integer, limit?: integer}] | File content (single or multiple files) |
128
+ | write_file | path: string, content: string | Success confirmation |
129
+ | move_file | source: string, destination: string | Success confirmation |
130
+ | copy_file | source: string, destination: string, recursive?: boolean | Success confirmation |
131
+ | delete_file | path: string | Success confirmation |
132
+ | get_file_info | path: string | File metadata (size, timestamps, permissions) |
102
133
 
103
- Common usage:
134
+ **CLI Usage:**
104
135
 
105
136
  ```bash
106
137
  # Read entire file
107
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py"}'
138
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py"}]}'
108
139
 
109
140
  # Read 10 lines starting from line 20
110
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py", "offset": 20, "limit": 10}'
141
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py", "offset": 20, "limit": 10}]}'
111
142
 
112
143
  # Read from line 50 to the end of the file
113
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py", "offset": 50}'
144
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py", "offset": 50}]}'
145
+
146
+ # Read multiple files with different line ranges
147
+ skydeckai-code-cli --tool read_file --args '{"files": [
148
+ {"path": "src/main.py", "offset": 1, "limit": 10},
149
+ {"path": "README.md"}
150
+ ]}'
114
151
 
115
152
  # Write file
116
153
  skydeckai-code-cli --tool write_file --args '{"path": "output.txt", "content": "Hello World"}'
@@ -171,7 +208,7 @@ Generates complete directory structure:
171
208
 
172
209
  Returns: JSON tree structure of directory contents.
173
210
 
174
- Common usage:
211
+ **CLI Usage:**
175
212
 
176
213
  ```bash
177
214
  # List directory
@@ -215,7 +252,7 @@ Supported Languages:
215
252
  - C# (.cs)
216
253
  - Kotlin (.kt, .kts)
217
254
 
218
- **Example Usage:**
255
+ **CLI Usage:**
219
256
 
220
257
  ```bash
221
258
  # Map the entire codebase structure
@@ -258,7 +295,7 @@ Matching lines grouped by file with line numbers, sorted by file modification ti
258
295
 
259
296
  This tool uses ripgrep when available for optimal performance, with a Python fallback implementation. It's ideal for finding specific code patterns like function declarations, imports, variable usages, or error handling.
260
297
 
261
- **Example Usage:**
298
+ **CLI Usage:**
262
299
 
263
300
  ```bash
264
301
  # Find function and class declarations in JavaScript files
@@ -311,6 +348,8 @@ Returns:
311
348
 
312
349
  Provides essential system information in a clean, readable format.
313
350
 
351
+ **CLI Usage:**
352
+
314
353
  ```bash
315
354
  # Get system information
316
355
  skydeckai-code-cli --tool get_system_info
@@ -479,7 +518,7 @@ Response content as text with HTTP status code and size information. For binary
479
518
 
480
519
  This tool can be used to access web APIs, fetch documentation, or download content from the web while respecting size limits (10MB max) and security constraints.
481
520
 
482
- **Example Usage:**
521
+ **CLI Usage:**
483
522
 
484
523
  ```bash
485
524
  # Fetch JSON from an API
@@ -527,7 +566,7 @@ A list of search results formatted in markdown, including titles, URLs, and snip
527
566
 
528
567
  This tool uses a multi-engine approach that tries different search engines with various parsing strategies to ensure reliable results. You can specify a preferred engine, but some engines may block automated access, in which case the tool will fall back to alternative engines when "auto" is selected.
529
568
 
530
- **Example Usage:**
569
+ **CLI Usage:**
531
570
 
532
571
  ```bash
533
572
  # Search with default settings (auto engine selection)
@@ -601,7 +640,7 @@ This tool provides efficient execution of multiple operations in a single reques
601
640
  1. Use paths relative to the current working directory (e.g., "project/src" rather than just "src"), or
602
641
  2. Include an explicit tool invocation to change directories using `update_allowed_directory`
603
642
 
604
- **Example Usage:**
643
+ **CLI Usage:**
605
644
 
606
645
  ```bash
607
646
  # Setup a new project with multiple steps in sequential order (using proper paths)
@@ -662,7 +701,7 @@ Your thoughts formatted as markdown, with a note indicating this was a thinking
662
701
 
663
702
  This tool is useful for thinking through complex problems, brainstorming solutions, or laying out implementation plans without making any actual changes. It's a great way to document your reasoning process, evaluate different approaches, or plan out a multi-step strategy before taking action.
664
703
 
665
- **Example Usage:**
704
+ **CLI Usage:**
666
705
 
667
706
  ```bash
668
707
  # Analyze a bug and plan a fix
@@ -706,7 +745,7 @@ Executes code in various programming languages with safety measures and restrict
706
745
  | code | string | Yes | Code to execute |
707
746
  | timeout | integer | No | Maximum execution time (default: 5s) |
708
747
 
709
- **Example Usage:**
748
+ **CLI Usage:**
710
749
 
711
750
  ```bash
712
751
  # Python example
@@ -766,7 +805,7 @@ Executes shell scripts (bash/sh) with safety measures and restrictions.
766
805
  | script | string | Yes | Shell script to execute |
767
806
  | timeout | integer | No | Maximum execution time (default: 300s, max: 600s) |
768
807
 
769
- **Example Usage:**
808
+ **CLI Usage:**
770
809
 
771
810
  ```bash
772
811
  # List directory contents with details
@@ -2,13 +2,13 @@ src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  src/aidd/__init__.py,sha256=c9HBWxWruCxoAqLCJqltylAwz_7xmaK3g8DKViJZs0Q,222
3
3
  src/aidd/cli.py,sha256=cLtaQJmMBfr7fHkd0dyJqpDrVTIwybL48PotniWGrFM,5031
4
4
  src/aidd/server.py,sha256=kPRyWeWkMCZjabelC65XTmzZG7yw8htMJKSfnUcKnb0,1575
5
- src/aidd/tools/__init__.py,sha256=MN4QEu4pvU8v45EtR63y0q5iIgt-kW0OW9soOxzjR88,3880
5
+ src/aidd/tools/__init__.py,sha256=j1uL7WVH3xS8JTGnpSIhaz7qkc3gcxuDyvZIYP9UztI,3731
6
6
  src/aidd/tools/base.py,sha256=wHSAaGGYWM8ECmoYd7KEcmjsZRWesNQFf3zMjCKGMcc,380
7
7
  src/aidd/tools/code_analysis.py,sha256=fDpm2o_If5PsngXzHN2-ezSkPVT0ZxivLuzmHrOAmVU,33188
8
8
  src/aidd/tools/code_execution.py,sha256=HRLUR1-q1PiCXKZV5QmTknDJKsfvPvFSWZbTpYFcv7I,13703
9
9
  src/aidd/tools/code_tools.py,sha256=DQ6N34Wbz5DwUPzt6RG7jk9HF2SsWFCFn99mencHK1c,14263
10
10
  src/aidd/tools/directory_tools.py,sha256=Hxzge_ziYw_FsjYb5yF0R0dHEdvuWRsg7WsdYDG0AUg,12971
11
- src/aidd/tools/file_tools.py,sha256=hcqQgkIIisjpcx1sL2rgxar9AFrKLmSATT9F50Y35RE,44276
11
+ src/aidd/tools/file_tools.py,sha256=GYzP6WxGbV1V42FlWNSuGIyiCtRp09kwF6lOZrFtq_U,43112
12
12
  src/aidd/tools/get_active_apps_tool.py,sha256=BjLF7iXSDgyAmm_gfFgAul2Gn3iX-CNVYHM7Sh4jTAI,19427
13
13
  src/aidd/tools/get_available_windows_tool.py,sha256=OVIYhItTn9u_DftOr3vPCT-R0DOFvMEEJXA6tD6gqWQ,15952
14
14
  src/aidd/tools/image_tools.py,sha256=wT3EcJAfZWcM0IsXdDfbTNjgFhKZM9nu2wHN6Mk_TTQ,5970
@@ -18,8 +18,8 @@ src/aidd/tools/screenshot_tool.py,sha256=NMO5B4UG8qfMEOMRd2YoOjtwz_oQ2y1UAGU22jV
18
18
  src/aidd/tools/state.py,sha256=RWSw0Jfsui8FqC0xsI7Ik07tAg35hRwLHa5xGBVbiI4,1493
19
19
  src/aidd/tools/system_tools.py,sha256=H4_qveKC2HA7SIbi-j4vxA0W4jYh2wfu9A6ni5wkZyA,7249
20
20
  src/aidd/tools/web_tools.py,sha256=gdsj2DEVYb_oYChItK5I1ugt2w25U7IAa5kEw9q6MVg,35534
21
- skydeckai_code-0.1.35.dist-info/METADATA,sha256=phlTiNYpNPCAX8oSmjaI6iuLYM_gjQbDSxQllwnayZI,29047
22
- skydeckai_code-0.1.35.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
- skydeckai_code-0.1.35.dist-info/entry_points.txt,sha256=ZkU1spOhLEnz5MpUn4dDihVcE0DMUC6ejzbsF-eNth4,88
24
- skydeckai_code-0.1.35.dist-info/licenses/LICENSE,sha256=uHse04vmI6ZjW7TblegFl30X-sDyyF0-QvH8ItPca3c,10865
25
- skydeckai_code-0.1.35.dist-info/RECORD,,
21
+ skydeckai_code-0.1.37.dist-info/METADATA,sha256=1YGhMWLG0ftxoyHwRaO64oi5mlSpRsXW5wh0quhcHdA,31860
22
+ skydeckai_code-0.1.37.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
+ skydeckai_code-0.1.37.dist-info/entry_points.txt,sha256=ZkU1spOhLEnz5MpUn4dDihVcE0DMUC6ejzbsF-eNth4,88
24
+ skydeckai_code-0.1.37.dist-info/licenses/LICENSE,sha256=uHse04vmI6ZjW7TblegFl30X-sDyyF0-QvH8ItPca3c,10865
25
+ skydeckai_code-0.1.37.dist-info/RECORD,,
@@ -25,12 +25,10 @@ from .file_tools import (
25
25
  handle_get_file_info,
26
26
  handle_move_file,
27
27
  handle_read_file,
28
- handle_read_multiple_files,
29
28
  handle_search_files,
30
29
  handle_write_file,
31
30
  move_file_tool,
32
31
  read_file_tool,
33
- read_multiple_files_tool,
34
32
  search_files_tool,
35
33
  write_file_tool,
36
34
  )
@@ -60,7 +58,6 @@ TOOL_DEFINITIONS = [
60
58
  edit_file_tool(),
61
59
  list_directory_tool(),
62
60
  read_file_tool(),
63
- read_multiple_files_tool(),
64
61
  move_file_tool(),
65
62
  copy_file_tool(),
66
63
  search_files_tool(),
@@ -96,7 +93,6 @@ TOOL_HANDLERS = {
96
93
  "read_file": handle_read_file,
97
94
  "write_file": handle_write_file,
98
95
  "edit_file": handle_edit_file,
99
- "read_multiple_files": handle_read_multiple_files,
100
96
  "move_file": handle_move_file,
101
97
  "copy_file": handle_copy_file,
102
98
  "search_files": handle_search_files,
@@ -17,32 +17,43 @@ from .state import state
17
17
  def read_file_tool():
18
18
  return {
19
19
  "name": "read_file",
20
- "description": "Read the contents of a file from the file system. "
21
- "WHEN TO USE: When you need to examine the actual content of a single file, view source code, check configuration files, or analyze text data. "
20
+ "description": "Read the contents of one or more files from the file system. "
21
+ "WHEN TO USE: When you need to examine the actual content of one or more files, view source code, check configuration files, or analyze text data. "
22
22
  "This is the primary tool for accessing file contents directly. "
23
23
  "WHEN NOT TO USE: When you only need file metadata like size or modification date (use get_file_info instead), when you need to list directory contents "
24
- "(use directory_listing instead), or when you need to read multiple files at once (use read_multiple_files instead). "
25
- "RETURNS: The complete text content of the specified file or the requested portion if offset/limit are specified. Binary files or files with unknown encodings will return an error message. "
26
- "Handles various text encodings and provides detailed error messages if the file cannot be read. Only works within the allowed directory. "
27
- "Example: Enter 'src/main.py' to read a Python file, or add offset/limit to read specific line ranges. "
28
- "TIP: When analyzing a codebase, it's more efficient to use read_multiple_files instead of reading files one by one.",
24
+ "(use directory_listing instead). "
25
+ "RETURNS: The complete text content of the specified file(s) or the requested portion if offset/limit are specified. Binary files or files with unknown encodings will return an error message. "
26
+ "Each file's content is preceded by a header showing the file path (==> path/to/file <==). "
27
+ "Handles various text encodings and provides detailed error messages if a file cannot be read. Only works within the allowed directory. "
28
+ "Example: Use 'files: [{\"path\": \"src/main.py\"}]' to read a Python file, or add offset/limit to read specific line ranges. "
29
+ "For multiple files, use 'files: [{\"path\": \"file1.txt\"}, {\"path\": \"file2.txt\"}]' with optional offset/limit for each file.",
29
30
  "inputSchema": {
30
31
  "type": "object",
31
32
  "properties": {
32
- "path": {
33
- "type": "string",
34
- "description": "Path to the file to read. This must be a path to a file, not a directory. Examples: 'README.md', 'src/main.py', 'config.json'. Both absolute and relative paths are supported, but must be within the allowed workspace."
35
- },
36
- "offset": {
37
- "type": "integer",
38
- "description": "Line number to start reading from (1-indexed). If specified, the file will be read starting from this line. Default is to start from the beginning of the file.",
39
- },
40
- "limit": {
41
- "type": "integer",
42
- "description": "Maximum number of lines to read after the offset. If specified along with offset, only this many lines will be read. Default is to read to the end of the file.",
33
+ "files": {
34
+ "type": "array",
35
+ "items": {
36
+ "type": "object",
37
+ "properties": {
38
+ "path": {
39
+ "type": "string",
40
+ "description": "Path to the file to read. This must be a path to a file, not a directory. Examples: 'README.md', 'src/main.py', 'config.json'. Both absolute and relative paths are supported, but must be within the allowed workspace."
41
+ },
42
+ "offset": {
43
+ "type": "integer",
44
+ "description": "Line number to start reading from (1-indexed). If specified, the file will be read starting from this line. Default is to start from the beginning of the file."
45
+ },
46
+ "limit": {
47
+ "type": "integer",
48
+ "description": "Maximum number of lines to read after the offset. If specified along with offset, only this many lines will be read. Default is to read to the end of the file."
49
+ }
50
+ },
51
+ "required": ["path"]
52
+ },
53
+ "description": "List of files to read with optional offset and limit for each file."
43
54
  }
44
55
  },
45
- "required": ["path"]
56
+ "required": ["files"]
46
57
  },
47
58
  }
48
59
 
@@ -215,31 +226,6 @@ def delete_file_tool():
215
226
  },
216
227
  }
217
228
 
218
- def read_multiple_files_tool():
219
- return {
220
- "name": "read_multiple_files",
221
- "description": "Read the contents of multiple files simultaneously. "
222
- "WHEN TO USE: When you need to examine or compare multiple files at once, analyze related files together, or gather content from several files efficiently. "
223
- "Useful for understanding code across multiple files, comparing configuration files, or collecting information from related documents. "
224
- "WHEN NOT TO USE: When you only need to read a single file (use read_file instead), when you need to read binary files or images (use read_image_file instead), "
225
- "or when you need metadata about files rather than their contents (use get_file_info instead). "
226
- "RETURNS: The contents of all specified files, with each file's content preceded by a header showing its path (==> path/to/file <==). "
227
- "If an individual file cannot be read, an error message is included in its place, but the operation continues for other files. "
228
- "Failed reads for individual files won't stop the entire operation. Only works within the allowed directory. "
229
- "Example: Enter ['src/main.py', 'README.md'] to read both files.",
230
- "inputSchema": {
231
- "type": "object",
232
- "properties": {
233
- "paths": {
234
- "type": "array",
235
- "items": {"type": "string"},
236
- "description": "List of file paths to read. Must contain at least one path. Each path should point to a text file. Examples: ['README.md', 'package.json'], ['src/main.py', 'src/utils.py', 'config.ini']. Both absolute and relative paths are supported, but must be within the allowed workspace.",
237
- }
238
- },
239
- "required": ["paths"]
240
- },
241
- }
242
-
243
229
  def edit_file_tool():
244
230
  return {
245
231
  "name": "edit_file",
@@ -396,41 +382,43 @@ async def handle_write_file(arguments: dict):
396
382
  raise ValueError(f"Error writing file: {str(e)}")
397
383
 
398
384
  async def handle_read_file(arguments: dict):
399
- path = arguments.get("path")
400
- if not path:
401
- raise ValueError("path must be provided")
402
-
403
- # Get the line range parameters
404
- offset = arguments.get("offset")
405
- limit = arguments.get("limit")
406
-
407
- return await _read_single_file(path, offset, limit)
408
-
409
- async def handle_read_multiple_files(arguments: dict):
410
- paths = arguments.get("paths", [])
411
- if not isinstance(paths, list):
412
- raise ValueError("paths must be a list of strings")
413
- if not all(isinstance(p, str) for p in paths):
414
- raise ValueError("all paths must be strings")
415
- if not paths:
416
- raise ValueError("paths list cannot be empty")
417
-
385
+ files = arguments.get("files")
386
+ if not files:
387
+ raise ValueError("files must be provided")
388
+ if not isinstance(files, list):
389
+ raise ValueError("files must be an array")
390
+ if not files:
391
+ raise ValueError("files array cannot be empty")
392
+
393
+ # Validate each file entry
394
+ for file_entry in files:
395
+ if not isinstance(file_entry, dict):
396
+ raise ValueError("each file entry must be an object")
397
+ if "path" not in file_entry:
398
+ raise ValueError("each file entry must have a path property")
399
+
400
+ # Read each file with its own offset/limit
418
401
  results = []
419
- for path in paths:
402
+ for file_entry in files:
403
+ path = file_entry.get("path")
404
+ offset = file_entry.get("offset")
405
+ limit = file_entry.get("limit")
406
+
420
407
  try:
421
408
  # Add file path header first
422
409
  results.append(TextContent(
423
410
  type="text",
424
411
  text=f"\n==> {path} <==\n"
425
412
  ))
426
- # Then add file contents
427
- file_contents = await _read_single_file(path)
413
+ # Then add file contents with specific offset/limit
414
+ file_contents = await _read_single_file(path, offset, limit)
428
415
  results.extend(file_contents)
429
416
  except Exception as e:
430
417
  results.append(TextContent(
431
418
  type="text",
432
419
  text=f"Error: {str(e)}\n"
433
420
  ))
421
+
434
422
  return results
435
423
 
436
424
  async def handle_move_file(arguments: dict):