skydeckai-code 0.1.30__py3-none-any.whl → 0.1.31__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.
aidd/tools/lint_tools.py CHANGED
@@ -18,12 +18,13 @@ def check_lint_tool():
18
18
  "when you need detailed code analysis with custom rules, or for compiled languages where linting may not apply. "
19
19
  "RETURNS: A detailed report of linting issues found in the codebase, including file paths, line numbers, "
20
20
  "issue descriptions, and severity levels. Issues are grouped by file and sorted by severity. "
21
- "Note: Respects config files like .pylintrc, .flake8, and .eslintrc if present.\n\n"
21
+ "Note: Respects config files like .pylintrc, .flake8, .eslintrc, and analysis_options.yaml if present.\n\n"
22
22
  "EXAMPLES:\n"
23
23
  "- Basic usage: {\"path\": \"src\"}\n"
24
24
  "- Python with custom line length: {\"path\": \"src\", \"linters\": {\"flake8\": \"--max-line-length=120 --ignore=E501,E302\"}}\n"
25
25
  "- Disable specific pylint checks: {\"linters\": {\"pylint\": \"--disable=missing-docstring,invalid-name\"}}\n"
26
26
  "- TypeScript only: {\"path\": \"src\", \"languages\": [\"typescript\"], \"linters\": {\"eslint\": \"--no-eslintrc --config .eslintrc.custom.js\"}}\n"
27
+ "- Dart only: {\"path\": \"lib\", \"languages\": [\"dart\"], \"linters\": {\"dart_analyze\": \"--fatal-infos\"}}\n"
27
28
  "- Disable a linter: {\"linters\": {\"flake8\": false}, \"max_issues\": 50}\n"
28
29
  "- Single file check: {\"path\": \"src/main.py\"}",
29
30
  "inputSchema": {
@@ -41,12 +42,12 @@ def check_lint_tool():
41
42
  "type": "string"
42
43
  },
43
44
  "description": "List of languages to lint. If empty, will auto-detect based on file extensions. "
44
- "Supported languages include: 'python', 'javascript', 'typescript'.",
45
+ "Supported languages include: 'python', 'javascript', 'typescript', 'dart'.",
45
46
  "default": []
46
47
  },
47
48
  "linters": {
48
49
  "type": "object",
49
- "description": "Configuration for specific linters. Each key is a linter name ('pylint', 'flake8', 'eslint') "
50
+ "description": "Configuration for specific linters. Each key is a linter name ('pylint', 'flake8', 'eslint', 'dart_analyze') "
50
51
  "and the value is either a boolean to enable/disable or a string with CLI arguments.",
51
52
  "properties": {
52
53
  "pylint": {
@@ -60,16 +61,21 @@ def check_lint_tool():
60
61
  "eslint": {
61
62
  "type": ["boolean", "string"],
62
63
  "description": "Whether to use eslint or custom eslint arguments."
64
+ },
65
+ "dart_analyze": {
66
+ "type": ["boolean", "string"],
67
+ "description": "Whether to use 'dart analyze' or custom dart analyze arguments."
63
68
  }
64
69
  },
65
70
  "default": {}
66
71
  },
67
72
  "max_issues": {
68
73
  "type": "integer",
69
- "description": "Maximum number of linting issues to return. Set to 0 for unlimited.",
74
+ "description": "Maximum number of issues to return. Set to 0 for unlimited.",
70
75
  "default": 100
71
76
  }
72
- }
77
+ },
78
+ "required": []
73
79
  }
74
80
  }
75
81
 
@@ -108,8 +114,15 @@ async def handle_check_lint(arguments: dict) -> List[TextContent]:
108
114
  language = _detect_language_from_file(full_path)
109
115
  if language:
110
116
  languages = [language]
117
+ else:
118
+ # If we can't detect a supported language for the file
119
+ _, ext = os.path.splitext(full_path)
120
+ return [TextContent(
121
+ type="text",
122
+ text=f"Unsupported file type: {ext}\nThe check_lint tool only supports: .py, .js, .jsx, .ts, .tsx, .dart files.\nSupported languages are: python, javascript, typescript, dart."
123
+ )]
111
124
  else:
112
- languages = ["python", "javascript", "typescript"] # Default to common languages
125
+ languages = ["python", "javascript", "typescript", "dart"] # Default to common languages
113
126
 
114
127
  # Prepare linter configurations with defaults
115
128
  linter_defaults = {
@@ -122,9 +135,41 @@ async def handle_check_lint(arguments: dict) -> List[TextContent]:
122
135
  },
123
136
  "typescript": {
124
137
  "eslint": True
138
+ },
139
+ "dart": {
140
+ "dart_analyze": True
125
141
  }
126
142
  }
127
143
 
144
+ # Validate languages if explicitly specified
145
+ if languages and os.path.isfile(full_path):
146
+ _, ext = os.path.splitext(full_path)
147
+ ext_language_map = {
148
+ '.py': 'python',
149
+ '.js': 'javascript',
150
+ '.jsx': 'javascript',
151
+ '.ts': 'typescript',
152
+ '.tsx': 'typescript',
153
+ '.dart': 'dart',
154
+ '.flutter': 'dart'
155
+ }
156
+ detected_language = ext_language_map.get(ext.lower())
157
+
158
+ # If we have a mismatch between specified language and file extension
159
+ if detected_language and not any(lang == detected_language for lang in languages):
160
+ return [TextContent(
161
+ type="text",
162
+ text=f"Language mismatch: File has {ext} extension but you specified {languages}.\n"
163
+ f"For this file extension, please use: {detected_language}"
164
+ )]
165
+
166
+ # If file type is not supported at all
167
+ if not detected_language:
168
+ return [TextContent(
169
+ type="text",
170
+ text=f"Unsupported file type: {ext}\nThe check_lint tool only supports: .py, .js, .jsx, .ts, .tsx, .dart files.\nSupported languages are: python, javascript, typescript, dart."
171
+ )]
172
+
128
173
  # Process each language
129
174
  all_issues = []
130
175
 
@@ -378,18 +423,105 @@ async def _run_linter(linter_name: str, path: str, custom_args: str = None) -> L
378
423
  # Silently fail if eslint is not installed
379
424
  pass
380
425
 
426
+ elif linter_name == "dart_analyze":
427
+ try:
428
+ # Build the command
429
+ cmd = ["dart", "analyze", "--format=json"]
430
+
431
+ if custom_args:
432
+ cmd.extend(custom_args.split())
433
+
434
+ # Add target path
435
+ cmd.append(path)
436
+
437
+ # Run dart analyze
438
+ result = subprocess.run(cmd, capture_output=True, text=True)
439
+
440
+ if result.stdout.strip():
441
+ # Parse Dart Analyze JSON output
442
+ try:
443
+ dart_results = json.loads(result.stdout)
444
+ for file_result in dart_results.get("issues", []):
445
+ # Get file path and ensure it's absolute
446
+ file_path = file_result.get("path", "")
447
+ if not os.path.isabs(file_path):
448
+ file_path = os.path.abspath(os.path.join(os.path.dirname(path), file_path))
449
+
450
+ # Security check for file path and exclude system directories
451
+ if not file_path.startswith(state.allowed_directory) or _is_excluded_system_directory(file_path):
452
+ continue
453
+
454
+ issues.append({
455
+ "file": os.path.relpath(file_path, state.allowed_directory),
456
+ "line": file_result.get("location", {}).get("startLine", 0),
457
+ "column": file_result.get("location", {}).get("startColumn", 0),
458
+ "message": file_result.get("message", ""),
459
+ "severity": _map_dart_severity(file_result.get("severity", "")),
460
+ "source": "dart",
461
+ "code": file_result.get("code", "")
462
+ })
463
+ except json.JSONDecodeError:
464
+ # Try parsing Flutter-specific error format (from compilation errors)
465
+ try:
466
+ # For flutter/dart compilation errors which might not be in JSON format
467
+ dart_issues = []
468
+ for line in result.stdout.splitlines() + result.stderr.splitlines():
469
+ # Check if line contains a compilation error pattern
470
+ error_match = re.search(r'(.*?):(\d+):(\d+):\s+(error|warning|info):\s+(.*)', line)
471
+ if error_match:
472
+ file_path, line_num, col, severity, message = error_match.groups()
473
+
474
+ # Ensure path is absolute for security check
475
+ if not os.path.isabs(file_path):
476
+ file_path = os.path.abspath(os.path.join(os.path.dirname(path), file_path))
477
+
478
+ # Security check for file path
479
+ if not file_path.startswith(state.allowed_directory) or _is_excluded_system_directory(file_path):
480
+ continue
481
+
482
+ dart_issues.append({
483
+ "file": os.path.relpath(file_path, state.allowed_directory),
484
+ "line": int(line_num),
485
+ "column": int(col),
486
+ "message": message,
487
+ "severity": severity,
488
+ "source": "dart",
489
+ "code": "compilation-error"
490
+ })
491
+
492
+ # If we found compilation errors, add them
493
+ issues.extend(dart_issues)
494
+ except Exception:
495
+ # Handle any parsing errors
496
+ if result.stderr:
497
+ issues.append({
498
+ "file": path if os.path.isfile(path) else "",
499
+ "line": 1,
500
+ "column": 1,
501
+ "message": f"Error running dart analyze: {result.stderr}",
502
+ "severity": "error",
503
+ "source": "dart",
504
+ "code": "tool-error"
505
+ })
506
+ except (subprocess.SubprocessError, FileNotFoundError):
507
+ # Silently fail if dart is not installed
508
+ pass
509
+
381
510
  return issues
382
511
 
383
512
  def _detect_language_from_file(file_path: str) -> Optional[str]:
384
- """Detect programming language based on file extension."""
385
- ext = os.path.splitext(file_path)[1].lower()
513
+ """Detect the programming language based on file extension."""
514
+ _, ext = os.path.splitext(file_path)
515
+ ext = ext.lower()
386
516
 
387
517
  language_map = {
388
518
  '.py': 'python',
389
519
  '.js': 'javascript',
390
- '.ts': 'typescript',
391
520
  '.jsx': 'javascript',
521
+ '.ts': 'typescript',
392
522
  '.tsx': 'typescript',
523
+ '.dart': 'dart',
524
+ '.flutter': 'dart'
393
525
  }
394
526
 
395
527
  return language_map.get(ext)
@@ -414,6 +546,15 @@ def _map_eslint_severity(severity: int) -> str:
414
546
  else:
415
547
  return "info"
416
548
 
549
+ def _map_dart_severity(severity_type: str) -> str:
550
+ """Map dart severity levels to standard severity levels."""
551
+ severity_map = {
552
+ "info": "info",
553
+ "warning": "warning",
554
+ "error": "error",
555
+ }
556
+ return severity_map.get(severity_type.lower(), "info")
557
+
417
558
  def _format_lint_results(issues: List[Dict[str, Any]]) -> str:
418
559
  """Format linting issues into a readable text output."""
419
560
  if not issues:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skydeckai-code
3
- Version: 0.1.30
3
+ Version: 0.1.31
4
4
  Summary: This MCP server provides a comprehensive set of tools for AI-driven Development workflows including file operations, code analysis, code linting, multi-language execution, Git operations, 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
@@ -312,6 +312,7 @@ A detailed report of linting issues found in the codebase, including file paths,
312
312
 
313
313
  - Python: pylint, flake8 (automatically uses what's available)
314
314
  - JavaScript/TypeScript: ESLint
315
+ - Dart/Flutter: dart_analyze (also reports compilation errors)
315
316
 
316
317
  **Example Usage:**
317
318
 
@@ -335,6 +336,15 @@ skydeckai-code-cli --tool check_lint --args '{
335
336
  "flake8": false
336
337
  }
337
338
  }'
339
+
340
+ # Check Dart/Flutter files for linting and compilation errors
341
+ skydeckai-code-cli --tool check_lint --args '{
342
+ "path": "lib",
343
+ "languages": ["dart"],
344
+ "linters": {
345
+ "dart_analyze": "--fatal-infos"
346
+ }
347
+ }'
338
348
  ```
339
349
 
340
350
  #### search_code
@@ -12,15 +12,15 @@ aidd/tools/get_active_apps_tool.py,sha256=BjLF7iXSDgyAmm_gfFgAul2Gn3iX-CNVYHM7Sh
12
12
  aidd/tools/get_available_windows_tool.py,sha256=OVIYhItTn9u_DftOr3vPCT-R0DOFvMEEJXA6tD6gqWQ,15952
13
13
  aidd/tools/git_tools.py,sha256=AgolgrZnpN2NALV7SfIwc6D7U7tdPrPTSFmU2WjPfVE,39846
14
14
  aidd/tools/image_tools.py,sha256=wT3EcJAfZWcM0IsXdDfbTNjgFhKZM9nu2wHN6Mk_TTQ,5970
15
- aidd/tools/lint_tools.py,sha256=ZV9zFb2ugFkO4PFWZk0q7GGVpRapETFBClJgUOiDkn8,18894
15
+ aidd/tools/lint_tools.py,sha256=0RYE-cXSbfw1VV_03GiFgYhC9ElhdWc4ecEjfMd9Els,25831
16
16
  aidd/tools/other_tools.py,sha256=iG3Sd2FP0M0pRv5esPBAUMvlwxTyAMDUdS77IqA_f5s,10822
17
17
  aidd/tools/path_tools.py,sha256=RGoOhqP69eHJzM8tEgn_5-GRaR0gp25fd0XZIJ_RnQE,4045
18
18
  aidd/tools/screenshot_tool.py,sha256=NMO5B4UG8qfMEOMRd2YoOjtwz_oQ2y1UAGU22jV1yGU,46337
19
19
  aidd/tools/state.py,sha256=RWSw0Jfsui8FqC0xsI7Ik07tAg35hRwLHa5xGBVbiI4,1493
20
20
  aidd/tools/system_tools.py,sha256=H4_qveKC2HA7SIbi-j4vxA0W4jYh2wfu9A6ni5wkZyA,7249
21
21
  aidd/tools/web_tools.py,sha256=gdsj2DEVYb_oYChItK5I1ugt2w25U7IAa5kEw9q6MVg,35534
22
- skydeckai_code-0.1.30.dist-info/METADATA,sha256=tR4BXAlWVy99YxudlZSogxl_SnfHKbzmcuCFgTNR780,32563
23
- skydeckai_code-0.1.30.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
24
- skydeckai_code-0.1.30.dist-info/entry_points.txt,sha256=cT-IHh3_ioGLk3kwIeqj1X6Li1dnJinX9qKWUl7nOLg,80
25
- skydeckai_code-0.1.30.dist-info/licenses/LICENSE,sha256=uHse04vmI6ZjW7TblegFl30X-sDyyF0-QvH8ItPca3c,10865
26
- skydeckai_code-0.1.30.dist-info/RECORD,,
22
+ skydeckai_code-0.1.31.dist-info/METADATA,sha256=117gd_kdJubtWEyNNMXBiUpsj-puKOspg9UeIWeMGVo,32850
23
+ skydeckai_code-0.1.31.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
24
+ skydeckai_code-0.1.31.dist-info/entry_points.txt,sha256=cT-IHh3_ioGLk3kwIeqj1X6Li1dnJinX9qKWUl7nOLg,80
25
+ skydeckai_code-0.1.31.dist-info/licenses/LICENSE,sha256=uHse04vmI6ZjW7TblegFl30X-sDyyF0-QvH8ItPca3c,10865
26
+ skydeckai_code-0.1.31.dist-info/RECORD,,