skydeckai-code 0.1.35__tar.gz → 0.1.36__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/PKG-INFO +18 -13
  2. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/README.md +17 -12
  3. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/pyproject.toml +1 -1
  4. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/__init__.py +0 -4
  5. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/file_tools.py +54 -66
  6. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/.gitignore +0 -0
  7. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/Dockerfile +0 -0
  8. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/LICENSE +0 -0
  9. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/screenshots/skydeck_ai_helper.png +0 -0
  10. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/smithery.yaml +0 -0
  11. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/__init__.py +0 -0
  12. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/__init__.py +0 -0
  13. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/cli.py +0 -0
  14. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/server.py +0 -0
  15. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/base.py +0 -0
  16. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/code_analysis.py +0 -0
  17. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/code_execution.py +0 -0
  18. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/code_tools.py +0 -0
  19. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/directory_tools.py +0 -0
  20. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/get_active_apps_tool.py +0 -0
  21. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/get_available_windows_tool.py +0 -0
  22. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/image_tools.py +0 -0
  23. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/other_tools.py +0 -0
  24. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/path_tools.py +0 -0
  25. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/screenshot_tool.py +0 -0
  26. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/state.py +0 -0
  27. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/system_tools.py +0 -0
  28. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/src/aidd/tools/web_tools.py +0 -0
  29. {skydeckai_code-0.1.35 → skydeckai_code-0.1.36}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skydeckai-code
3
- Version: 0.1.35
3
+ Version: 0.1.36
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
@@ -90,27 +90,32 @@ If you're using SkyDeck AI Helper app, you can search for "SkyDeckAI Code" and i
90
90
 
91
91
  ### Basic File Operations
92
92
 
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) |
93
+ | Tool | Parameters | Returns |
94
+ | ------------- | ---------------------------------------------------------- | --------------------------------------------- |
95
+ | read_file | files: [{path: string, offset?: integer, limit?: integer}] | File content (single or multiple files) |
96
+ | write_file | path: string, content: string | Success confirmation |
97
+ | move_file | source: string, destination: string | Success confirmation |
98
+ | copy_file | source: string, destination: string, recursive?: boolean | Success confirmation |
99
+ | delete_file | path: string | Success confirmation |
100
+ | get_file_info | path: string | File metadata (size, timestamps, permissions) |
102
101
 
103
102
  Common usage:
104
103
 
105
104
  ```bash
106
105
  # Read entire file
107
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py"}'
106
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py"}]}'
108
107
 
109
108
  # Read 10 lines starting from line 20
110
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py", "offset": 20, "limit": 10}'
109
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py", "offset": 20, "limit": 10}]}'
111
110
 
112
111
  # Read from line 50 to the end of the file
113
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py", "offset": 50}'
112
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py", "offset": 50}]}'
113
+
114
+ # Read multiple files with different line ranges
115
+ skydeckai-code-cli --tool read_file --args '{"files": [
116
+ {"path": "src/main.py", "offset": 1, "limit": 10},
117
+ {"path": "README.md"}
118
+ ]}'
114
119
 
115
120
  # Write file
116
121
  skydeckai-code-cli --tool write_file --args '{"path": "output.txt", "content": "Hello World"}'
@@ -55,27 +55,32 @@ If you're using SkyDeck AI Helper app, you can search for "SkyDeckAI Code" and i
55
55
 
56
56
  ### Basic File Operations
57
57
 
58
- | Tool | Parameters | Returns |
59
- | ------------------- | -------------------------------------------------------- | --------------------------------------------- |
60
- | read_file | path: string, offset?: integer, limit?: integer | File content (whole or partial) |
61
- | read_multiple_files | paths: string[] | Multiple file contents with headers |
62
- | write_file | path: string, content: string | Success confirmation |
63
- | move_file | source: string, destination: string | Success confirmation |
64
- | copy_file | source: string, destination: string, recursive?: boolean | Success confirmation |
65
- | delete_file | path: string | Success confirmation |
66
- | get_file_info | path: string | File metadata (size, timestamps, permissions) |
58
+ | Tool | Parameters | Returns |
59
+ | ------------- | ---------------------------------------------------------- | --------------------------------------------- |
60
+ | read_file | files: [{path: string, offset?: integer, limit?: integer}] | File content (single or multiple files) |
61
+ | write_file | path: string, content: string | Success confirmation |
62
+ | move_file | source: string, destination: string | Success confirmation |
63
+ | copy_file | source: string, destination: string, recursive?: boolean | Success confirmation |
64
+ | delete_file | path: string | Success confirmation |
65
+ | get_file_info | path: string | File metadata (size, timestamps, permissions) |
67
66
 
68
67
  Common usage:
69
68
 
70
69
  ```bash
71
70
  # Read entire file
72
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py"}'
71
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py"}]}'
73
72
 
74
73
  # Read 10 lines starting from line 20
75
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py", "offset": 20, "limit": 10}'
74
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py", "offset": 20, "limit": 10}]}'
76
75
 
77
76
  # Read from line 50 to the end of the file
78
- skydeckai-code-cli --tool read_file --args '{"path": "src/main.py", "offset": 50}'
77
+ skydeckai-code-cli --tool read_file --args '{"files": [{"path": "src/main.py", "offset": 50}]}'
78
+
79
+ # Read multiple files with different line ranges
80
+ skydeckai-code-cli --tool read_file --args '{"files": [
81
+ {"path": "src/main.py", "offset": 1, "limit": 10},
82
+ {"path": "README.md"}
83
+ ]}'
79
84
 
80
85
  # Write file
81
86
  skydeckai-code-cli --tool write_file --args '{"path": "output.txt", "content": "Hello World"}'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "skydeckai-code"
3
- version = "0.1.35"
3
+ version = "0.1.36"
4
4
  description = "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
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -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):
File without changes
File without changes