mofox-plugin-dev-toolkit 0.3.3__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.
- mofox_plugin_dev_toolkit-0.3.3.dist-info/METADATA +730 -0
- mofox_plugin_dev_toolkit-0.3.3.dist-info/RECORD +46 -0
- mofox_plugin_dev_toolkit-0.3.3.dist-info/WHEEL +5 -0
- mofox_plugin_dev_toolkit-0.3.3.dist-info/entry_points.txt +2 -0
- mofox_plugin_dev_toolkit-0.3.3.dist-info/licenses/LICENSE +674 -0
- mofox_plugin_dev_toolkit-0.3.3.dist-info/top_level.txt +1 -0
- mpdt/__init__.py +15 -0
- mpdt/__main__.py +8 -0
- mpdt/cli.py +316 -0
- mpdt/commands/__init__.py +9 -0
- mpdt/commands/check.py +498 -0
- mpdt/commands/dev.py +318 -0
- mpdt/commands/generate.py +448 -0
- mpdt/commands/init.py +686 -0
- mpdt/dev/bridge_plugin/__init__.py +17 -0
- mpdt/dev/bridge_plugin/cleanup_handler.py +65 -0
- mpdt/dev/bridge_plugin/dev_config.py +24 -0
- mpdt/dev/bridge_plugin/file_watcher.py +169 -0
- mpdt/dev/bridge_plugin/plugin.py +219 -0
- mpdt/templates/__init__.py +165 -0
- mpdt/templates/action_template.py +102 -0
- mpdt/templates/adapter_template.py +129 -0
- mpdt/templates/chatter_template.py +103 -0
- mpdt/templates/event_template.py +116 -0
- mpdt/templates/plus_command_template.py +150 -0
- mpdt/templates/prompt_template.py +92 -0
- mpdt/templates/router_template.py +175 -0
- mpdt/templates/tool_template.py +98 -0
- mpdt/utils/__init__.py +10 -0
- mpdt/utils/code_parser.py +401 -0
- mpdt/utils/color_printer.py +99 -0
- mpdt/utils/config_loader.py +171 -0
- mpdt/utils/config_manager.py +297 -0
- mpdt/utils/file_ops.py +207 -0
- mpdt/utils/license_generator.py +980 -0
- mpdt/utils/plugin_parser.py +195 -0
- mpdt/utils/template_engine.py +112 -0
- mpdt/validators/__init__.py +26 -0
- mpdt/validators/auto_fix_validator.py +990 -0
- mpdt/validators/base.py +129 -0
- mpdt/validators/component_validator.py +842 -0
- mpdt/validators/config_validator.py +119 -0
- mpdt/validators/metadata_validator.py +107 -0
- mpdt/validators/structure_validator.py +72 -0
- mpdt/validators/style_validator.py +117 -0
- mpdt/validators/type_validator.py +206 -0
mpdt/__init__.py
ADDED
mpdt/__main__.py
ADDED
mpdt/cli.py
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI 主入口
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
from mpdt import __version__
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@click.group()
|
|
14
|
+
@click.version_option(version=__version__, prog_name="MPDT - MoFox-Bot 插件开发工具")
|
|
15
|
+
@click.option("--verbose", "-v", is_flag=True, help="详细输出模式")
|
|
16
|
+
@click.option("--no-color", is_flag=True, help="禁用彩色输出")
|
|
17
|
+
@click.pass_context
|
|
18
|
+
def cli(ctx: click.Context, verbose: bool, no_color: bool) -> None:
|
|
19
|
+
"""
|
|
20
|
+
MoFox Plugin Dev Toolkit - MoFox-Bot 插件开发工具
|
|
21
|
+
|
|
22
|
+
一个类似 Vite 的开发工具,用于快速创建、开发和测试 MoFox-Bot 插件。
|
|
23
|
+
"""
|
|
24
|
+
# 设置上下文对象
|
|
25
|
+
ctx.ensure_object(dict)
|
|
26
|
+
ctx.obj["verbose"] = verbose
|
|
27
|
+
ctx.obj["no_color"] = no_color
|
|
28
|
+
|
|
29
|
+
# 禁用彩色输出
|
|
30
|
+
if no_color:
|
|
31
|
+
console._color_system = None
|
|
32
|
+
|
|
33
|
+
if verbose:
|
|
34
|
+
console.print(f"[bold green]MPDT v{__version__}[/bold green]")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@cli.command()
|
|
38
|
+
@click.argument("plugin_name", required=False)
|
|
39
|
+
@click.option("--template", "-t", type=click.Choice(["basic", "action", "tool", "plus_command", "full", "adapter"]),
|
|
40
|
+
default="basic", help="插件模板类型")
|
|
41
|
+
@click.option("--author", "-a", help="作者名称")
|
|
42
|
+
@click.option("--license", "-l", type=click.Choice(["GPL-v3.0", "MIT", "Apache-2.0", "BSD-3-Clause"]),
|
|
43
|
+
default="GPL-v3.0", help="开源协议")
|
|
44
|
+
@click.option("--with-docs", is_flag=True, help="创建文档文件")
|
|
45
|
+
@click.option("--init-git/--no-init-git", default=None, help="是否初始化 Git 仓库")
|
|
46
|
+
@click.option("--output", "-o", type=click.Path(), help="输出目录")
|
|
47
|
+
@click.pass_context
|
|
48
|
+
def init(ctx: click.Context, plugin_name: str | None, template: str, author: str | None,
|
|
49
|
+
license: str, with_docs: bool, init_git: bool | None, output: str | None) -> None:
|
|
50
|
+
"""初始化新插件项目"""
|
|
51
|
+
from mpdt.commands.init import init_plugin
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
init_plugin(
|
|
55
|
+
plugin_name=plugin_name,
|
|
56
|
+
template=template,
|
|
57
|
+
author=author,
|
|
58
|
+
license_type=license,
|
|
59
|
+
with_docs=with_docs,
|
|
60
|
+
init_git=init_git,
|
|
61
|
+
output_dir=output,
|
|
62
|
+
verbose=ctx.obj["verbose"],
|
|
63
|
+
)
|
|
64
|
+
except Exception as e:
|
|
65
|
+
console.print(f"[bold red]❌ 初始化失败: {e}[/bold red]")
|
|
66
|
+
raise click.Abort()
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@cli.command()
|
|
70
|
+
@click.argument("component_type", type=click.Choice(["action", "tool", "event", "adapter", "prompt", "plus-command","router","chatter"]), required=False)
|
|
71
|
+
@click.argument("component_name", required=False)
|
|
72
|
+
@click.option("--description", "-d", help="组件描述")
|
|
73
|
+
@click.option("--output", "-o", type=click.Path(), help="输出目录")
|
|
74
|
+
@click.option("--force", "-f", is_flag=True, help="覆盖已存在的文件")
|
|
75
|
+
@click.pass_context
|
|
76
|
+
def generate(ctx: click.Context, component_type: str | None, component_name: str | None, description: str | None,
|
|
77
|
+
output: str | None, force: bool) -> None:
|
|
78
|
+
"""生成插件组件(始终生成异步方法)
|
|
79
|
+
|
|
80
|
+
如果不提供参数,将进入交互式问答模式
|
|
81
|
+
"""
|
|
82
|
+
from mpdt.commands.generate import generate_component
|
|
83
|
+
|
|
84
|
+
try:
|
|
85
|
+
generate_component(
|
|
86
|
+
component_type=component_type,
|
|
87
|
+
component_name=component_name,
|
|
88
|
+
description=description,
|
|
89
|
+
output_dir=output,
|
|
90
|
+
force=force,
|
|
91
|
+
verbose=ctx.obj["verbose"],
|
|
92
|
+
)
|
|
93
|
+
except Exception as e:
|
|
94
|
+
console.print(f"[bold red]❌ 生成失败: {e}[/bold red]")
|
|
95
|
+
raise click.Abort()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@cli.command()
|
|
99
|
+
@click.argument("path", type=click.Path(exists=True), required=False, default=".")
|
|
100
|
+
@click.option("--level", "-l", type=click.Choice(["error", "warning", "info"]), default="warning",
|
|
101
|
+
help="显示的最低级别")
|
|
102
|
+
@click.option("--fix", is_flag=True, help="自动修复可修复的问题")
|
|
103
|
+
@click.option("--report", type=click.Choice(["console","markdown","json"]), default="console",
|
|
104
|
+
help="输出报告的格式")
|
|
105
|
+
@click.option("--output", "-o", type=click.Path(), help="报告输出路径")
|
|
106
|
+
@click.option("--no-structure", is_flag=True, help="跳过结构检查")
|
|
107
|
+
@click.option("--no-metadata", is_flag=True, help="跳过元数据检查")
|
|
108
|
+
@click.option("--no-component", is_flag=True, help="跳过组件检查")
|
|
109
|
+
@click.option("--no-type", is_flag=True, help="跳过类型检查")
|
|
110
|
+
@click.option("--no-style", is_flag=True, help="跳过代码风格检查")
|
|
111
|
+
@click.pass_context
|
|
112
|
+
def check(ctx: click.Context, path: str, level: str, fix: bool, report: str, output: str | None,
|
|
113
|
+
no_structure: bool, no_metadata: bool, no_component: bool, no_type: bool,
|
|
114
|
+
no_style: bool) -> None:
|
|
115
|
+
"""对插件进行静态检查"""
|
|
116
|
+
from mpdt.commands.check import check_plugin
|
|
117
|
+
|
|
118
|
+
try:
|
|
119
|
+
check_plugin(
|
|
120
|
+
plugin_path=path,
|
|
121
|
+
level=level,
|
|
122
|
+
auto_fix=fix,
|
|
123
|
+
report_format=report,
|
|
124
|
+
output_path=output,
|
|
125
|
+
skip_structure=no_structure,
|
|
126
|
+
skip_metadata=no_metadata,
|
|
127
|
+
skip_component=no_component,
|
|
128
|
+
skip_type=no_type,
|
|
129
|
+
skip_style=no_style,
|
|
130
|
+
verbose=ctx.obj["verbose"],
|
|
131
|
+
)
|
|
132
|
+
except Exception as e:
|
|
133
|
+
console.print(f"[bold red]❌ 检查失败: {e}[/bold red]")
|
|
134
|
+
raise click.Abort()
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@cli.command()
|
|
138
|
+
@click.option("--output", "-o", type=click.Path(), default="dist", help="输出目录")
|
|
139
|
+
@click.option("--with-docs", is_flag=True, help="包含文档")
|
|
140
|
+
@click.option("--format", type=click.Choice(["zip", "tar.gz", "wheel"]), default="zip", help="构建格式")
|
|
141
|
+
@click.option("--bump", type=click.Choice(["major", "minor", "patch"]), help="自动升级版本号")
|
|
142
|
+
@click.pass_context
|
|
143
|
+
def build(ctx: click.Context, output: str, with_docs: bool, format: str, bump: str | None) -> None:
|
|
144
|
+
"""构建和打包插件"""
|
|
145
|
+
console.print("[yellow]⚠️ 构建命令尚未实现[/yellow]")
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@cli.command()
|
|
149
|
+
@click.option("--mmc-path", type=click.Path(exists=True), help="mmc 主程序路径")
|
|
150
|
+
@click.option("--plugin-path", type=click.Path(exists=True), help="插件路径(默认当前目录)")
|
|
151
|
+
@click.pass_context
|
|
152
|
+
def dev(ctx: click.Context, mmc_path: str | None, plugin_path: str | None) -> None:
|
|
153
|
+
"""启动开发模式,支持热重载"""
|
|
154
|
+
from pathlib import Path
|
|
155
|
+
|
|
156
|
+
from mpdt.commands.dev import dev_command
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
dev_command(
|
|
160
|
+
plugin_path=Path(plugin_path) if plugin_path else None,
|
|
161
|
+
mofox_path=Path(mmc_path) if mmc_path else None
|
|
162
|
+
)
|
|
163
|
+
except Exception as e:
|
|
164
|
+
console.print(f"[bold red]❌ 启动失败: {e}[/bold red]")
|
|
165
|
+
if ctx.obj.get("verbose"):
|
|
166
|
+
import traceback
|
|
167
|
+
traceback.print_exc()
|
|
168
|
+
raise click.Abort()
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@cli.group()
|
|
172
|
+
def config() -> None:
|
|
173
|
+
"""配置管理"""
|
|
174
|
+
pass
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@config.command("init")
|
|
178
|
+
def config_init() -> None:
|
|
179
|
+
"""交互式配置向导"""
|
|
180
|
+
from mpdt.utils.config_manager import interactive_config
|
|
181
|
+
|
|
182
|
+
try:
|
|
183
|
+
interactive_config()
|
|
184
|
+
except Exception as e:
|
|
185
|
+
console.print(f"[bold red]❌ 配置失败: {e}[/bold red]")
|
|
186
|
+
raise click.Abort()
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@config.command("show")
|
|
190
|
+
def config_show() -> None:
|
|
191
|
+
"""显示当前配置"""
|
|
192
|
+
from rich.table import Table
|
|
193
|
+
|
|
194
|
+
from mpdt.utils.config_manager import MPDTConfig
|
|
195
|
+
|
|
196
|
+
try:
|
|
197
|
+
config = MPDTConfig()
|
|
198
|
+
|
|
199
|
+
if not config.is_configured():
|
|
200
|
+
console.print("[yellow]⚠️ 未找到配置文件[/yellow]")
|
|
201
|
+
console.print("请运行 [cyan]mpdt config init[/cyan] 进行配置")
|
|
202
|
+
return
|
|
203
|
+
|
|
204
|
+
table = Table(title="MPDT 配置")
|
|
205
|
+
table.add_column("配置项", style="cyan")
|
|
206
|
+
table.add_column("值", style="green")
|
|
207
|
+
|
|
208
|
+
table.add_row("配置文件", str(config.config_path))
|
|
209
|
+
table.add_row("MoFox-Bot 路径", str(config.mofox_path) if config.mofox_path else "[red]未配置[/red]")
|
|
210
|
+
table.add_row("虚拟环境类型", config.venv_type)
|
|
211
|
+
table.add_row("虚拟环境路径", str(config.venv_path) if config.venv_path else "[dim]无[/dim]")
|
|
212
|
+
table.add_row("自动重载", "是" if config.auto_reload else "否")
|
|
213
|
+
table.add_row("重载延迟", f"{config.reload_delay}秒")
|
|
214
|
+
|
|
215
|
+
console.print(table)
|
|
216
|
+
|
|
217
|
+
# 显示 Python 命令
|
|
218
|
+
console.print("\n[bold]Python 命令:[/bold]")
|
|
219
|
+
console.print(f" {' '.join(config.get_python_command())}")
|
|
220
|
+
|
|
221
|
+
except Exception as e:
|
|
222
|
+
console.print(f"[bold red]❌ 读取配置失败: {e}[/bold red]")
|
|
223
|
+
raise click.Abort()
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@config.command("test")
|
|
227
|
+
def config_test() -> None:
|
|
228
|
+
"""测试配置是否有效"""
|
|
229
|
+
from mpdt.utils.config_manager import MPDTConfig
|
|
230
|
+
|
|
231
|
+
try:
|
|
232
|
+
config = MPDTConfig()
|
|
233
|
+
|
|
234
|
+
if not config.is_configured():
|
|
235
|
+
console.print("[yellow]⚠️ 未找到配置文件[/yellow]")
|
|
236
|
+
console.print("请运行 [cyan]mpdt config init[/cyan] 进行配置")
|
|
237
|
+
return
|
|
238
|
+
|
|
239
|
+
console.print("[cyan]正在验证配置...[/cyan]\n")
|
|
240
|
+
|
|
241
|
+
valid, errors = config.validate()
|
|
242
|
+
|
|
243
|
+
if valid:
|
|
244
|
+
console.print("[bold green]✓ 配置有效![/bold green]")
|
|
245
|
+
console.print(f"\nmmc 路径: {config.mofox_path}")
|
|
246
|
+
console.print(f"Python 命令: {' '.join(config.get_python_command())}")
|
|
247
|
+
else:
|
|
248
|
+
console.print("[bold red]✗ 配置验证失败:[/bold red]")
|
|
249
|
+
for error in errors:
|
|
250
|
+
console.print(f" - {error}")
|
|
251
|
+
console.print("\n请运行 [cyan]mpdt config init[/cyan] 重新配置")
|
|
252
|
+
|
|
253
|
+
except Exception as e:
|
|
254
|
+
console.print(f"[bold red]❌ 测试失败: {e}[/bold red]")
|
|
255
|
+
raise click.Abort()
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@config.command("set-mofox")
|
|
259
|
+
@click.argument("path", type=click.Path(exists=True))
|
|
260
|
+
def config_set_mmc(path: str) -> None:
|
|
261
|
+
"""设置 MoFox 主程序路径"""
|
|
262
|
+
from pathlib import Path
|
|
263
|
+
|
|
264
|
+
from mpdt.utils.config_manager import MPDTConfig
|
|
265
|
+
|
|
266
|
+
try:
|
|
267
|
+
config = MPDTConfig()
|
|
268
|
+
config.mofox_path = Path(path)
|
|
269
|
+
config.save()
|
|
270
|
+
|
|
271
|
+
console.print(f"[green]✓ MoFox 路径已设置: {path}[/green]")
|
|
272
|
+
|
|
273
|
+
except Exception as e:
|
|
274
|
+
console.print(f"[bold red]❌ 设置失败: {e}[/bold red]")
|
|
275
|
+
raise click.Abort()
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@config.command("set-venv")
|
|
279
|
+
@click.argument("path", type=click.Path(exists=True), required=False)
|
|
280
|
+
@click.option("--type", "venv_type", type=click.Choice(["venv", "uv", "conda", "poetry", "none"]),
|
|
281
|
+
default="venv", help="虚拟环境类型")
|
|
282
|
+
def config_set_venv(path: str | None, venv_type: str) -> None:
|
|
283
|
+
"""设置虚拟环境"""
|
|
284
|
+
from pathlib import Path
|
|
285
|
+
from typing import cast
|
|
286
|
+
|
|
287
|
+
from mpdt.utils.config_manager import MPDTConfig, VenvType
|
|
288
|
+
|
|
289
|
+
try:
|
|
290
|
+
config = MPDTConfig()
|
|
291
|
+
config.venv_type = cast(VenvType, venv_type)
|
|
292
|
+
|
|
293
|
+
if venv_type == "none":
|
|
294
|
+
config.venv_path = None
|
|
295
|
+
console.print("[green]✓ 已设置为使用系统 Python[/green]")
|
|
296
|
+
elif path:
|
|
297
|
+
config.venv_path = Path(path)
|
|
298
|
+
console.print(f"[green]✓ 虚拟环境已设置: {path} (类型: {venv_type})[/green]")
|
|
299
|
+
else:
|
|
300
|
+
console.print("[red]❌ 请提供虚拟环境路径[/red]")
|
|
301
|
+
raise click.Abort()
|
|
302
|
+
|
|
303
|
+
config.save()
|
|
304
|
+
|
|
305
|
+
except Exception as e:
|
|
306
|
+
console.print(f"[bold red]❌ 设置失败: {e}[/bold red]")
|
|
307
|
+
raise click.Abort()
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def main() -> None:
|
|
311
|
+
"""主入口函数"""
|
|
312
|
+
cli(obj={})
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
if __name__ == "__main__":
|
|
316
|
+
main()
|