mofox-plugin-dev-toolkit 0.2.1__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.
Files changed (43) hide show
  1. mofox_plugin_dev_toolkit-0.2.1.dist-info/METADATA +409 -0
  2. mofox_plugin_dev_toolkit-0.2.1.dist-info/RECORD +43 -0
  3. mofox_plugin_dev_toolkit-0.2.1.dist-info/WHEEL +5 -0
  4. mofox_plugin_dev_toolkit-0.2.1.dist-info/entry_points.txt +2 -0
  5. mofox_plugin_dev_toolkit-0.2.1.dist-info/licenses/LICENSE +674 -0
  6. mofox_plugin_dev_toolkit-0.2.1.dist-info/top_level.txt +1 -0
  7. mpdt/__init__.py +15 -0
  8. mpdt/__main__.py +8 -0
  9. mpdt/cli.py +314 -0
  10. mpdt/commands/__init__.py +9 -0
  11. mpdt/commands/check.py +316 -0
  12. mpdt/commands/dev.py +550 -0
  13. mpdt/commands/generate.py +366 -0
  14. mpdt/commands/init.py +487 -0
  15. mpdt/dev/bridge_plugin/__init__.py +17 -0
  16. mpdt/dev/bridge_plugin/discovery_server.py +126 -0
  17. mpdt/dev/bridge_plugin/plugin.py +258 -0
  18. mpdt/templates/__init__.py +165 -0
  19. mpdt/templates/action_template.py +102 -0
  20. mpdt/templates/adapter_template.py +129 -0
  21. mpdt/templates/chatter_template.py +103 -0
  22. mpdt/templates/event_template.py +116 -0
  23. mpdt/templates/plus_command_template.py +150 -0
  24. mpdt/templates/prompt_template.py +92 -0
  25. mpdt/templates/router_template.py +175 -0
  26. mpdt/templates/tool_template.py +98 -0
  27. mpdt/utils/__init__.py +10 -0
  28. mpdt/utils/color_printer.py +99 -0
  29. mpdt/utils/config_loader.py +171 -0
  30. mpdt/utils/config_manager.py +297 -0
  31. mpdt/utils/file_ops.py +203 -0
  32. mpdt/utils/license_generator.py +980 -0
  33. mpdt/utils/plugin_parser.py +196 -0
  34. mpdt/utils/template_engine.py +112 -0
  35. mpdt/validators/__init__.py +26 -0
  36. mpdt/validators/auto_fix_validator.py +182 -0
  37. mpdt/validators/base.py +121 -0
  38. mpdt/validators/component_validator.py +415 -0
  39. mpdt/validators/config_validator.py +173 -0
  40. mpdt/validators/metadata_validator.py +125 -0
  41. mpdt/validators/structure_validator.py +70 -0
  42. mpdt/validators/style_validator.py +125 -0
  43. mpdt/validators/type_validator.py +223 -0
mpdt/utils/file_ops.py ADDED
@@ -0,0 +1,203 @@
1
+ """
2
+ 文件操作工具
3
+ """
4
+
5
+ import shutil
6
+ from pathlib import Path
7
+
8
+
9
+ def ensure_dir(path: Path | str) -> Path:
10
+ """
11
+ 确保目录存在,如果不存在则创建
12
+
13
+ Args:
14
+ path: 目录路径
15
+
16
+ Returns:
17
+ Path 对象
18
+ """
19
+ path = Path(path)
20
+ path.mkdir(parents=True, exist_ok=True)
21
+ return path
22
+
23
+
24
+ def safe_write_file(path: Path | str, content: str, force: bool = False) -> bool:
25
+ """
26
+ 安全地写入文件
27
+
28
+ Args:
29
+ path: 文件路径
30
+ content: 文件内容
31
+ force: 是否覆盖已存在的文件
32
+
33
+ Returns:
34
+ 是否写入成功
35
+
36
+ Raises:
37
+ FileExistsError: 文件已存在且 force=False
38
+ """
39
+ path = Path(path)
40
+
41
+ if path.exists() and not force:
42
+ raise FileExistsError(f"文件已存在: {path}")
43
+
44
+ # 确保父目录存在
45
+ ensure_dir(path.parent)
46
+
47
+ # 写入文件
48
+ path.write_text(content, encoding="utf-8")
49
+ return True
50
+
51
+
52
+ def copy_directory(src: Path | str, dst: Path | str, force: bool = False) -> bool:
53
+ """
54
+ 复制整个目录
55
+
56
+ Args:
57
+ src: 源目录
58
+ dst: 目标目录
59
+ force: 是否覆盖已存在的目录
60
+
61
+ Returns:
62
+ 是否复制成功
63
+ """
64
+ src = Path(src)
65
+ dst = Path(dst)
66
+
67
+ if dst.exists() and not force:
68
+ raise FileExistsError(f"目标目录已存在: {dst}")
69
+
70
+ if dst.exists():
71
+ shutil.rmtree(dst)
72
+
73
+ shutil.copytree(src, dst)
74
+ return True
75
+
76
+
77
+ def list_python_files(path: Path | str, recursive: bool = True) -> list[Path]:
78
+ """
79
+ 列出目录中的所有 Python 文件
80
+
81
+ Args:
82
+ path: 目录路径
83
+ recursive: 是否递归搜索
84
+
85
+ Returns:
86
+ Python 文件路径列表
87
+ """
88
+ path = Path(path)
89
+
90
+ if recursive:
91
+ return list(path.rglob("*.py"))
92
+ else:
93
+ return list(path.glob("*.py"))
94
+
95
+
96
+ def validate_plugin_name(name: str) -> bool:
97
+ """
98
+ 验证插件名称是否符合规范
99
+
100
+ 规范: 使用小写字母、数字和下划线,以字母开头
101
+
102
+ Args:
103
+ name: 插件名称
104
+
105
+ Returns:
106
+ 是否符合规范
107
+ """
108
+ import re
109
+ return bool(re.match(r"^[a-z][a-z0-9_]*$", name))
110
+
111
+
112
+ def validate_component_name(name: str) -> bool:
113
+ """
114
+ 验证组件名称是否符合规范
115
+
116
+ 规范: 支持 snake_case 或 PascalCase
117
+
118
+ Args:
119
+ name: 组件名称
120
+
121
+ Returns:
122
+ 是否符合规范
123
+ """
124
+ import re
125
+ # 支持 snake_case 或 PascalCase
126
+ return bool(re.match(r"^[a-zA-Z][a-zA-Z0-9_]*$", name))
127
+
128
+
129
+ def get_git_user_info() -> dict[str, str]:
130
+ """
131
+ 从 git config 获取用户信息
132
+
133
+ Returns:
134
+ 包含 name 和 email 的字典
135
+ """
136
+ import subprocess
137
+
138
+ result = {"name": "", "email": ""}
139
+
140
+ try:
141
+ name = subprocess.run(
142
+ ["git", "config", "--get", "user.name"],
143
+ capture_output=True,
144
+ text=True,
145
+ check=False,
146
+ )
147
+ if name.returncode == 0:
148
+ result["name"] = name.stdout.strip()
149
+
150
+ email = subprocess.run(
151
+ ["git", "config", "--get", "user.email"],
152
+ capture_output=True,
153
+ text=True,
154
+ check=False,
155
+ )
156
+ if email.returncode == 0:
157
+ result["email"] = email.stdout.strip()
158
+ except Exception:
159
+ pass
160
+
161
+ return result
162
+
163
+
164
+ def to_pascal_case(snake_str: str) -> str:
165
+ """
166
+ 将 snake_case 转换为 PascalCase
167
+
168
+ Args:
169
+ snake_str: snake_case 字符串
170
+
171
+ Returns:
172
+ PascalCase 字符串
173
+
174
+ Examples:
175
+ >>> to_pascal_case("my_action")
176
+ 'MyAction'
177
+ >>> to_pascal_case("test_command_handler")
178
+ 'TestCommandHandler'
179
+ """
180
+ return "".join(word.capitalize() for word in snake_str.split("_"))
181
+
182
+
183
+ def to_snake_case(pascal_str: str) -> str:
184
+ """
185
+ 将 PascalCase 转换为 snake_case
186
+
187
+ Args:
188
+ pascal_str: PascalCase 字符串
189
+
190
+ Returns:
191
+ snake_case 字符串
192
+
193
+ Examples:
194
+ >>> to_snake_case("MyAction")
195
+ 'my_action'
196
+ >>> to_snake_case("TestCommandHandler")
197
+ 'test_command_handler'
198
+ """
199
+ import re
200
+ # 在大写字母前插入下划线
201
+ s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', pascal_str)
202
+ # 处理连续大写字母
203
+ return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()