mofox-plugin-dev-toolkit 0.2.7__tar.gz → 0.3.1__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 (55) hide show
  1. {mofox_plugin_dev_toolkit-0.2.7/mofox_plugin_dev_toolkit.egg-info → mofox_plugin_dev_toolkit-0.3.1}/PKG-INFO +3 -3
  2. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/README.md +2 -2
  3. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1/mofox_plugin_dev_toolkit.egg-info}/PKG-INFO +3 -3
  4. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mofox_plugin_dev_toolkit.egg-info/SOURCES.txt +2 -1
  5. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/__init__.py +1 -1
  6. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/cli.py +8 -9
  7. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/commands/check.py +120 -16
  8. mofox_plugin_dev_toolkit-0.3.1/mpdt/commands/dev.py +451 -0
  9. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/commands/init.py +6 -0
  10. mofox_plugin_dev_toolkit-0.3.1/mpdt/dev/bridge_plugin/__init__.py +17 -0
  11. mofox_plugin_dev_toolkit-0.3.1/mpdt/dev/bridge_plugin/dev_config.py +24 -0
  12. mofox_plugin_dev_toolkit-0.3.1/mpdt/dev/bridge_plugin/file_watcher.py +162 -0
  13. mofox_plugin_dev_toolkit-0.3.1/mpdt/dev/bridge_plugin/plugin.py +119 -0
  14. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/code_parser.py +1 -2
  15. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/config_manager.py +42 -42
  16. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/file_ops.py +4 -0
  17. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/auto_fix_validator.py +229 -251
  18. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/component_validator.py +15 -13
  19. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/config_validator.py +1 -1
  20. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/metadata_validator.py +11 -14
  21. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/structure_validator.py +5 -3
  22. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/style_validator.py +5 -8
  23. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/type_validator.py +10 -25
  24. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/pyproject.toml +1 -1
  25. mofox_plugin_dev_toolkit-0.2.7/mpdt/commands/dev.py +0 -546
  26. mofox_plugin_dev_toolkit-0.2.7/mpdt/dev/bridge_plugin/__init__.py +0 -17
  27. mofox_plugin_dev_toolkit-0.2.7/mpdt/dev/bridge_plugin/discovery_server.py +0 -124
  28. mofox_plugin_dev_toolkit-0.2.7/mpdt/dev/bridge_plugin/plugin.py +0 -256
  29. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/LICENSE +0 -0
  30. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/MANIFEST.in +0 -0
  31. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mofox_plugin_dev_toolkit.egg-info/dependency_links.txt +0 -0
  32. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mofox_plugin_dev_toolkit.egg-info/entry_points.txt +0 -0
  33. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mofox_plugin_dev_toolkit.egg-info/requires.txt +0 -0
  34. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mofox_plugin_dev_toolkit.egg-info/top_level.txt +0 -0
  35. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/__main__.py +0 -0
  36. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/commands/__init__.py +0 -0
  37. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/commands/generate.py +1 -1
  38. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/__init__.py +0 -0
  39. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/action_template.py +0 -0
  40. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/adapter_template.py +0 -0
  41. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/chatter_template.py +0 -0
  42. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/event_template.py +0 -0
  43. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/plus_command_template.py +0 -0
  44. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/prompt_template.py +0 -0
  45. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/router_template.py +0 -0
  46. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/templates/tool_template.py +0 -0
  47. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/__init__.py +0 -0
  48. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/color_printer.py +0 -0
  49. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/config_loader.py +0 -0
  50. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/license_generator.py +0 -0
  51. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/plugin_parser.py +0 -0
  52. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/utils/template_engine.py +0 -0
  53. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/__init__.py +0 -0
  54. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/mpdt/validators/base.py +0 -0
  55. {mofox_plugin_dev_toolkit-0.2.7 → mofox_plugin_dev_toolkit-0.3.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mofox-plugin-dev-toolkit
3
- Version: 0.2.7
3
+ Version: 0.3.1
4
4
  Summary: 开发工具集,用于快速创建、开发和测试 MoFox-Bot 插件
5
5
  Author-email: MoFox-Studio <mofox.studio@example.com>
6
6
  License: GPL-3.0-or-later
@@ -54,7 +54,7 @@ Dynamic: license-file
54
54
 
55
55
  [![Python Version](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
56
56
  [![License](https://img.shields.io/badge/license-GPL--3.0-green.svg)](LICENSE)
57
- [![Version](https://img.shields.io/badge/version-0.2.1-orange.svg)](https://github.com/MoFox-Studio/mofox-plugin-toolkit)
57
+ [![Version](https://img.shields.io/badge/version-0.3.1-orange.svg)](https://github.com/MoFox-Studio/mofox-plugin-toolkit)
58
58
 
59
59
  一个类似于 Vite 的 Python 开发工具,专门为 MoFox-Bot 插件系统设计,提供快速创建、开发、检查和热重载的完整工具链。
60
60
 
@@ -517,7 +517,7 @@ dependencies = [
517
517
  ## 💡 常见问题
518
518
 
519
519
  ### Q: 如何配置开发模式?
520
- A: 首次运行 `mpdt dev` 时会提示输入 MMC 主程序路径,配置会保存到 `~/.mpdt/config.toml`。
520
+ A: 首次运行 `mpdt dev` 时会提示输入 MoFox 主程序路径,配置会保存到 `~/.mpdt/config.toml`。
521
521
 
522
522
  ### Q: 检查器报错怎么办?
523
523
  A: 首先尝试使用 `mpdt check --fix` 自动修复。如果仍有问题,查看具体错误信息和建议。
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![Python Version](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
4
4
  [![License](https://img.shields.io/badge/license-GPL--3.0-green.svg)](LICENSE)
5
- [![Version](https://img.shields.io/badge/version-0.2.1-orange.svg)](https://github.com/MoFox-Studio/mofox-plugin-toolkit)
5
+ [![Version](https://img.shields.io/badge/version-0.3.1-orange.svg)](https://github.com/MoFox-Studio/mofox-plugin-toolkit)
6
6
 
7
7
  一个类似于 Vite 的 Python 开发工具,专门为 MoFox-Bot 插件系统设计,提供快速创建、开发、检查和热重载的完整工具链。
8
8
 
@@ -465,7 +465,7 @@ dependencies = [
465
465
  ## 💡 常见问题
466
466
 
467
467
  ### Q: 如何配置开发模式?
468
- A: 首次运行 `mpdt dev` 时会提示输入 MMC 主程序路径,配置会保存到 `~/.mpdt/config.toml`。
468
+ A: 首次运行 `mpdt dev` 时会提示输入 MoFox 主程序路径,配置会保存到 `~/.mpdt/config.toml`。
469
469
 
470
470
  ### Q: 检查器报错怎么办?
471
471
  A: 首先尝试使用 `mpdt check --fix` 自动修复。如果仍有问题,查看具体错误信息和建议。
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mofox-plugin-dev-toolkit
3
- Version: 0.2.7
3
+ Version: 0.3.1
4
4
  Summary: 开发工具集,用于快速创建、开发和测试 MoFox-Bot 插件
5
5
  Author-email: MoFox-Studio <mofox.studio@example.com>
6
6
  License: GPL-3.0-or-later
@@ -54,7 +54,7 @@ Dynamic: license-file
54
54
 
55
55
  [![Python Version](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
56
56
  [![License](https://img.shields.io/badge/license-GPL--3.0-green.svg)](LICENSE)
57
- [![Version](https://img.shields.io/badge/version-0.2.1-orange.svg)](https://github.com/MoFox-Studio/mofox-plugin-toolkit)
57
+ [![Version](https://img.shields.io/badge/version-0.3.1-orange.svg)](https://github.com/MoFox-Studio/mofox-plugin-toolkit)
58
58
 
59
59
  一个类似于 Vite 的 Python 开发工具,专门为 MoFox-Bot 插件系统设计,提供快速创建、开发、检查和热重载的完整工具链。
60
60
 
@@ -517,7 +517,7 @@ dependencies = [
517
517
  ## 💡 常见问题
518
518
 
519
519
  ### Q: 如何配置开发模式?
520
- A: 首次运行 `mpdt dev` 时会提示输入 MMC 主程序路径,配置会保存到 `~/.mpdt/config.toml`。
520
+ A: 首次运行 `mpdt dev` 时会提示输入 MoFox 主程序路径,配置会保存到 `~/.mpdt/config.toml`。
521
521
 
522
522
  ### Q: 检查器报错怎么办?
523
523
  A: 首先尝试使用 `mpdt check --fix` 自动修复。如果仍有问题,查看具体错误信息和建议。
@@ -17,7 +17,8 @@ mpdt/commands/dev.py
17
17
  mpdt/commands/generate.py
18
18
  mpdt/commands/init.py
19
19
  mpdt/dev/bridge_plugin/__init__.py
20
- mpdt/dev/bridge_plugin/discovery_server.py
20
+ mpdt/dev/bridge_plugin/dev_config.py
21
+ mpdt/dev/bridge_plugin/file_watcher.py
21
22
  mpdt/dev/bridge_plugin/plugin.py
22
23
  mpdt/templates/__init__.py
23
24
  mpdt/templates/action_template.py
@@ -4,7 +4,7 @@ MoFox Plugin Dev Toolkit
4
4
  一个用于 MoFox-Bot 插件开发的工具集
5
5
  """
6
6
 
7
- __version__ = "0.2.7"
7
+ __version__ = "0.3.1"
8
8
  __author__ = "MoFox-Studio"
9
9
  __license__ = "GPL-3.0-or-later"
10
10
 
@@ -102,8 +102,8 @@ def generate(ctx: click.Context, component_type: str | None, component_name: str
102
102
  @click.option("--level", "-l", type=click.Choice(["error", "warning", "info"]), default="warning",
103
103
  help="显示的最低级别")
104
104
  @click.option("--fix", is_flag=True, help="自动修复可修复的问题")
105
- @click.option("--report", type=click.Choice(["console","markdown"]), default="console",
106
- help="报告格式")
105
+ @click.option("--report", type=click.Choice(["console","markdown","json"]), default="console",
106
+ help="输出报告的格式")
107
107
  @click.option("--output", "-o", type=click.Path(), help="报告输出路径")
108
108
  @click.option("--no-structure", is_flag=True, help="跳过结构检查")
109
109
  @click.option("--no-metadata", is_flag=True, help="跳过元数据检查")
@@ -153,16 +153,15 @@ def build(ctx: click.Context, output: str, with_docs: bool, format: str, bump: s
153
153
  @click.pass_context
154
154
  def dev(ctx: click.Context, mmc_path: str | None, plugin_path: str | None) -> None:
155
155
  """启动开发模式,支持热重载"""
156
- import asyncio
157
156
  from pathlib import Path
158
157
 
159
158
  from mpdt.commands.dev import dev_command
160
159
 
161
160
  try:
162
- asyncio.run(dev_command(
161
+ dev_command(
163
162
  plugin_path=Path(plugin_path) if plugin_path else None,
164
- mmc_path=Path(mmc_path) if mmc_path else None
165
- ))
163
+ mofox_path=Path(mmc_path) if mmc_path else None
164
+ )
166
165
  except Exception as e:
167
166
  console.print(f"[bold red]❌ 启动失败: {e}[/bold red]")
168
167
  if ctx.obj.get("verbose"):
@@ -209,7 +208,7 @@ def config_show() -> None:
209
208
  table.add_column("值", style="green")
210
209
 
211
210
  table.add_row("配置文件", str(config.config_path))
212
- table.add_row("MoFox-Bot 路径", str(config.mmc_path) if config.mmc_path else "[red]未配置[/red]")
211
+ table.add_row("MoFox-Bot 路径", str(config.mofox_path) if config.mofox_path else "[red]未配置[/red]")
213
212
  table.add_row("虚拟环境类型", config.venv_type)
214
213
  table.add_row("虚拟环境路径", str(config.venv_path) if config.venv_path else "[dim]无[/dim]")
215
214
  table.add_row("自动重载", "是" if config.auto_reload else "否")
@@ -245,7 +244,7 @@ def config_test() -> None:
245
244
 
246
245
  if valid:
247
246
  console.print("[bold green]✓ 配置有效![/bold green]")
248
- console.print(f"\nmmc 路径: {config.mmc_path}")
247
+ console.print(f"\nmmc 路径: {config.mofox_path}")
249
248
  console.print(f"Python 命令: {' '.join(config.get_python_command())}")
250
249
  else:
251
250
  console.print("[bold red]✗ 配置验证失败:[/bold red]")
@@ -268,7 +267,7 @@ def config_set_mmc(path: str) -> None:
268
267
 
269
268
  try:
270
269
  config = MPDTConfig()
271
- config.mmc_path = Path(path)
270
+ config.mofox_path = Path(path)
272
271
  config.save()
273
272
 
274
273
  console.print(f"[green]✓ mmc 路径已设置: {path}[/green]")
@@ -108,7 +108,7 @@ def check_plugin(
108
108
  # 代码风格检查
109
109
  if not skip_style:
110
110
  print_info("正在检查代码风格...")
111
- validator = StyleValidator(path, auto_fix=auto_fix)
111
+ validator = StyleValidator(path)
112
112
  result = validator.validate()
113
113
  all_results.append(result)
114
114
  _print_validation_summary(result, verbose)
@@ -119,27 +119,45 @@ def check_plugin(
119
119
  print_info("正在应用自动修复...")
120
120
  auto_fixer = AutoFixValidator(path)
121
121
  fix_result = auto_fixer.fix_issues(all_results)
122
-
122
+
123
123
  # 从原始结果中移除已修复的问题(使用对象 id 比较)
124
124
  fixed_issue_ids = {id(issue) for issue in auto_fixer.fixed_issues}
125
125
  for result in all_results:
126
126
  result.issues = [issue for issue in result.issues if id(issue) not in fixed_issue_ids]
127
127
  # 更新计数
128
128
  result._update_counts()
129
-
129
+
130
+ # 如果应用了 ruff 修复,移除所有可以被 ruff 修复的问题
131
+ if any("ruff" in fix for fix in auto_fixer.fixes_applied):
132
+ import re
133
+ ruff_fixed_count = 0
134
+ for result in all_results:
135
+ original_count = len(result.issues)
136
+ # 移除所有 ruff 错误格式的问题(如果建议包含"可自动修复"或问题本身就是 ruff 格式)
137
+ result.issues = [
138
+ issue for issue in result.issues
139
+ if not (
140
+ re.match(r'^[A-Z]\d+:', issue.message) and
141
+ (issue.suggestion is None or "可自动修复" in issue.suggestion or "--fix" in issue.suggestion)
142
+ )
143
+ ]
144
+ ruff_fixed_count += original_count - len(result.issues)
145
+ # 更新计数
146
+ result._update_counts()
147
+
130
148
  # 显示修复摘要
131
149
  if auto_fixer.fixes_applied:
132
150
  print_success(f" ✓ 成功修复 {len(auto_fixer.fixes_applied)} 个问题")
133
151
  if verbose:
134
152
  for fix in auto_fixer.fixes_applied:
135
153
  console.print(f" [green]✓[/green] {fix}")
136
-
154
+
137
155
  if auto_fixer.fixes_failed:
138
156
  print_warning(f" ⚠ {len(auto_fixer.fixes_failed)} 个问题修复失败")
139
157
  if verbose:
140
158
  for fail in auto_fixer.fixes_failed:
141
159
  console.print(f" [yellow]✗[/yellow] {fail}")
142
-
160
+
143
161
  if not auto_fixer.fixes_applied and not auto_fixer.fixes_failed:
144
162
  print_info(" ℹ 未发现可自动修复的问题")
145
163
 
@@ -203,7 +221,9 @@ def _print_issue(issue) -> None:
203
221
  console.print(f" [dim]💡 {issue.suggestion}[/dim]")
204
222
 
205
223
 
206
- def _print_overall_report(results: list[ValidationResult], level: str, auto_fixer: AutoFixValidator | None = None) -> None:
224
+ def _print_overall_report(
225
+ results: list[ValidationResult], level: str, auto_fixer: AutoFixValidator | None = None
226
+ ) -> None:
207
227
  """打印总体报告
208
228
 
209
229
  Args:
@@ -248,7 +268,10 @@ def _print_overall_report(results: list[ValidationResult], level: str, auto_fixe
248
268
  issue
249
269
  for issue in result.issues
250
270
  if (issue.level == ValidationLevel.ERROR)
251
- or (issue.level == ValidationLevel.WARNING and level_filter in [ValidationLevel.WARNING, ValidationLevel.INFO])
271
+ or (
272
+ issue.level == ValidationLevel.WARNING
273
+ and level_filter in [ValidationLevel.WARNING, ValidationLevel.INFO]
274
+ )
252
275
  or (issue.level == ValidationLevel.INFO and level_filter == ValidationLevel.INFO)
253
276
  ]
254
277
 
@@ -262,23 +285,23 @@ def _print_overall_report(results: list[ValidationResult], level: str, auto_fixe
262
285
  if auto_fixer:
263
286
  console.print("[bold cyan]═══ 修复统计 ═══[/bold cyan]")
264
287
  console.print()
265
-
288
+
266
289
  if auto_fixer.fixes_applied:
267
290
  console.print(f"[green]✓ 成功修复: {len(auto_fixer.fixes_applied)} 个[/green]")
268
291
  for fix in auto_fixer.fixes_applied:
269
292
  console.print(f" [green]•[/green] {fix}")
270
293
  console.print()
271
-
294
+
272
295
  if auto_fixer.fixes_failed:
273
296
  console.print(f"[yellow]✗ 修复失败: {len(auto_fixer.fixes_failed)} 个[/yellow]")
274
297
  for fail in auto_fixer.fixes_failed:
275
298
  console.print(f" [yellow]•[/yellow] {fail}")
276
299
  console.print()
277
-
300
+
278
301
  if not auto_fixer.fixes_applied and not auto_fixer.fixes_failed:
279
302
  console.print("[blue]ℹ 未发现可自动修复的问题[/blue]")
280
303
  console.print()
281
-
304
+
282
305
  console.print("[bold cyan]═══ 最终结果 ═══[/bold cyan]")
283
306
  console.print()
284
307
  if total_errors > 0:
@@ -289,7 +312,9 @@ def _print_overall_report(results: list[ValidationResult], level: str, auto_fixe
289
312
  print_success("所有检查通过!")
290
313
 
291
314
 
292
- def _save_report(results: list[ValidationResult], output_path: str, report_format: str, auto_fixer: AutoFixValidator | None = None) -> None:
315
+ def _save_report(
316
+ results: list[ValidationResult], output_path: str, report_format: str, auto_fixer: AutoFixValidator | None = None
317
+ ) -> None:
293
318
  """保存检查报告
294
319
 
295
320
  Args:
@@ -300,11 +325,15 @@ def _save_report(results: list[ValidationResult], output_path: str, report_forma
300
325
  """
301
326
  if report_format == "markdown":
302
327
  _save_markdown_report(results, output_path, auto_fixer)
328
+ elif report_format == "json":
329
+ _save_json_report(results, output_path, auto_fixer)
303
330
  else:
304
331
  print_warning(f"不支持的报告格式: {report_format}")
305
332
 
306
333
 
307
- def _save_markdown_report(results: list[ValidationResult], output_path: str, auto_fixer: AutoFixValidator | None = None) -> None:
334
+ def _save_markdown_report(
335
+ results: list[ValidationResult], output_path: str, auto_fixer: AutoFixValidator | None = None
336
+ ) -> None:
308
337
  """保存 Markdown 格式的报告
309
338
 
310
339
  Args:
@@ -323,7 +352,7 @@ def _save_markdown_report(results: list[ValidationResult], output_path: str, aut
323
352
  lines.append(f"- 错误: {total_errors}\n")
324
353
  lines.append(f"- 警告: {total_warnings}\n")
325
354
  lines.append(f"- 信息: {total_info}\n")
326
-
355
+
327
356
  # 修复统计
328
357
  if auto_fixer:
329
358
  lines.append("\n### 自动修复统计\n\n")
@@ -337,7 +366,7 @@ def _save_markdown_report(results: list[ValidationResult], output_path: str, aut
337
366
  lines.append(f" - {fail}\n")
338
367
  if not auto_fixer.fixes_applied and not auto_fixer.fixes_failed:
339
368
  lines.append("- ℹ️ 未发现可自动修复的问题\n")
340
-
369
+
341
370
  lines.append("\n")
342
371
 
343
372
  # 详细结果
@@ -377,7 +406,7 @@ def _save_markdown_report(results: list[ValidationResult], output_path: str, aut
377
406
  lines.append(f"✅ 成功修复 {len(auto_fixer.fixes_applied)} 个问题\n\n")
378
407
  if auto_fixer.fixes_failed:
379
408
  lines.append(f"⚠️ {len(auto_fixer.fixes_failed)} 个问题修复失败\n\n")
380
-
409
+
381
410
  if total_errors > 0:
382
411
  lines.append(f"❌ 剩余 {total_errors} 个错误,{total_warnings} 个警告\n")
383
412
  elif total_warnings > 0:
@@ -392,3 +421,78 @@ def _save_markdown_report(results: list[ValidationResult], output_path: str, aut
392
421
  print_success(f"报告已保存到: {output_path}")
393
422
  except Exception as e:
394
423
  print_error(f"保存报告失败: {e}")
424
+
425
+
426
+ def _save_json_report(
427
+ results: list[ValidationResult], output_path: str, auto_fixer: AutoFixValidator | None = None
428
+ ) -> None:
429
+ """保存 JSON 格式的报告
430
+
431
+ Args:
432
+ results: 验证结果列表
433
+ output_path: 输出路径
434
+ auto_fixer: 自动修复器对象(如果启用了自动修复)
435
+ """
436
+ import json
437
+ from datetime import datetime
438
+
439
+ # 统计总数
440
+ total_errors = sum(r.error_count for r in results)
441
+ total_warnings = sum(r.warning_count for r in results)
442
+ total_info = sum(r.info_count for r in results)
443
+
444
+ # 构建报告数据结构
445
+ report = {
446
+ "timestamp": datetime.now().isoformat(),
447
+ "summary": {
448
+ "total_errors": total_errors,
449
+ "total_warnings": total_warnings,
450
+ "total_info": total_info,
451
+ "success": total_errors == 0,
452
+ },
453
+ "validators": [],
454
+ "issues": [],
455
+ }
456
+
457
+ # 添加自动修复统计
458
+ if auto_fixer:
459
+ report["auto_fix"] = {
460
+ "enabled": True,
461
+ "fixes_applied": len(auto_fixer.fixes_applied),
462
+ "fixes_failed": len(auto_fixer.fixes_failed),
463
+ "applied_fixes": auto_fixer.fixes_applied,
464
+ "failed_fixes": auto_fixer.fixes_failed,
465
+ }
466
+ else:
467
+ report["auto_fix"] = {"enabled": False}
468
+
469
+ # 添加每个验证器的结果
470
+ for result in results:
471
+ validator_data = {
472
+ "name": result.validator_name,
473
+ "success": result.success,
474
+ "error_count": result.error_count,
475
+ "warning_count": result.warning_count,
476
+ "info_count": result.info_count,
477
+ }
478
+ report["validators"].append(validator_data)
479
+
480
+ # 添加问题详情
481
+ for issue in result.issues:
482
+ issue_data = {
483
+ "validator": result.validator_name,
484
+ "level": issue.level.value,
485
+ "message": issue.message,
486
+ "file_path": issue.file_path,
487
+ "line_number": issue.line_number,
488
+ "suggestion": issue.suggestion,
489
+ }
490
+ report["issues"].append(issue_data)
491
+
492
+ # 写入文件
493
+ try:
494
+ with open(output_path, "w", encoding="utf-8") as f:
495
+ json.dump(report, f, ensure_ascii=False, indent=2)
496
+ print_success(f"报告已保存到: {output_path}")
497
+ except Exception as e:
498
+ print_error(f"保存报告失败: {e}")