mofox-plugin-dev-toolkit 0.4.1__tar.gz → 0.4.3__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 (59) hide show
  1. {mofox_plugin_dev_toolkit-0.4.1/mofox_plugin_dev_toolkit.egg-info → mofox_plugin_dev_toolkit-0.4.3}/PKG-INFO +1 -1
  2. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3/mofox_plugin_dev_toolkit.egg-info}/PKG-INFO +1 -1
  3. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mofox_plugin_dev_toolkit.egg-info/SOURCES.txt +2 -0
  4. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/__init__.py +1 -1
  5. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/cli.py +21 -4
  6. mofox_plugin_dev_toolkit-0.4.3/mpdt/commands/__init__.py +3 -0
  7. mofox_plugin_dev_toolkit-0.4.3/mpdt/commands/build.py +300 -0
  8. mofox_plugin_dev_toolkit-0.4.3/mpdt/dev/bridge_plugin/__init__.py +7 -0
  9. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/dev/bridge_plugin/cleanup_handler.py +6 -7
  10. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/dev/bridge_plugin/file_watcher.py +1 -1
  11. mofox_plugin_dev_toolkit-0.4.3/mpdt/dev/bridge_plugin/manifest.json +16 -0
  12. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/dev/bridge_plugin/plugin.py +29 -59
  13. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/pyproject.toml +1 -1
  14. mofox_plugin_dev_toolkit-0.4.1/mpdt/commands/__init__.py +0 -9
  15. mofox_plugin_dev_toolkit-0.4.1/mpdt/dev/bridge_plugin/__init__.py +0 -17
  16. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/LICENSE +0 -0
  17. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/MANIFEST.in +0 -0
  18. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/README.md +0 -0
  19. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mofox_plugin_dev_toolkit.egg-info/dependency_links.txt +0 -0
  20. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mofox_plugin_dev_toolkit.egg-info/entry_points.txt +0 -0
  21. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mofox_plugin_dev_toolkit.egg-info/requires.txt +0 -0
  22. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mofox_plugin_dev_toolkit.egg-info/top_level.txt +0 -0
  23. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/__main__.py +0 -0
  24. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/commands/check.py +0 -0
  25. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/commands/dev.py +0 -0
  26. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/commands/generate.py +0 -0
  27. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/commands/init.py +0 -0
  28. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/dev/bridge_plugin/dev_config.py +0 -0
  29. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/__init__.py +0 -0
  30. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/action_template.py +0 -0
  31. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/adapter_template.py +0 -0
  32. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/chatter_template.py +0 -0
  33. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/collection_template.py +0 -0
  34. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/config_template.py +0 -0
  35. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/event_template.py +0 -0
  36. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/plus_command_template.py +0 -0
  37. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/prompt_template.py +0 -0
  38. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/router_template.py +0 -0
  39. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/service_template.py +0 -0
  40. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/templates/tool_template.py +0 -0
  41. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/__init__.py +0 -0
  42. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/code_parser.py +0 -0
  43. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/color_printer.py +0 -0
  44. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/config_loader.py +0 -0
  45. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/config_manager.py +0 -0
  46. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/file_ops.py +0 -0
  47. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/license_generator.py +0 -0
  48. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/plugin_parser.py +0 -0
  49. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/utils/template_engine.py +0 -0
  50. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/__init__.py +0 -0
  51. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/auto_fix_validator.py +0 -0
  52. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/base.py +0 -0
  53. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/component_validator.py +0 -0
  54. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/config_validator.py +0 -0
  55. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/metadata_validator.py +0 -0
  56. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/structure_validator.py +0 -0
  57. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/style_validator.py +0 -0
  58. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/mpdt/validators/type_validator.py +0 -0
  59. {mofox_plugin_dev_toolkit-0.4.1 → mofox_plugin_dev_toolkit-0.4.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mofox-plugin-dev-toolkit
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: 开发工具集,用于快速创建、开发和测试 MoFox-Bot 插件
5
5
  Author-email: MoFox-Studio <wwwww95915@qq.com>
6
6
  License: GPL-3.0-or-later
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mofox-plugin-dev-toolkit
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: 开发工具集,用于快速创建、开发和测试 MoFox-Bot 插件
5
5
  Author-email: MoFox-Studio <wwwww95915@qq.com>
6
6
  License: GPL-3.0-or-later
@@ -12,6 +12,7 @@ mpdt/__init__.py
12
12
  mpdt/__main__.py
13
13
  mpdt/cli.py
14
14
  mpdt/commands/__init__.py
15
+ mpdt/commands/build.py
15
16
  mpdt/commands/check.py
16
17
  mpdt/commands/dev.py
17
18
  mpdt/commands/generate.py
@@ -20,6 +21,7 @@ mpdt/dev/bridge_plugin/__init__.py
20
21
  mpdt/dev/bridge_plugin/cleanup_handler.py
21
22
  mpdt/dev/bridge_plugin/dev_config.py
22
23
  mpdt/dev/bridge_plugin/file_watcher.py
24
+ mpdt/dev/bridge_plugin/manifest.json
23
25
  mpdt/dev/bridge_plugin/plugin.py
24
26
  mpdt/templates/__init__.py
25
27
  mpdt/templates/action_template.py
@@ -4,7 +4,7 @@ MoFox Plugin Dev Toolkit
4
4
  一个用于 MoFox-Bot 插件开发的工具集
5
5
  """
6
6
 
7
- __version__ = "0.4.1"
7
+ __version__ = "0.4.3"
8
8
  __author__ = "MoFox-Studio"
9
9
  __license__ = "GPL-3.0-or-later"
10
10
 
@@ -135,14 +135,31 @@ def check(ctx: click.Context, path: str, level: str, fix: bool, report: str, out
135
135
 
136
136
 
137
137
  @cli.command()
138
+ @click.argument("plugin_path", type=click.Path(), required=False, default=".")
138
139
  @click.option("--output", "-o", type=click.Path(), default="dist", help="输出目录")
139
140
  @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("--format", "fmt", type=click.Choice(["mfp", "zip"]), default="mfp", help="构建格式(mfp 为推荐格式)")
141
142
  @click.option("--bump", type=click.Choice(["major", "minor", "patch"]), help="自动升级版本号")
142
143
  @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]")
144
+ def build(ctx: click.Context, plugin_path: str, output: str, with_docs: bool, fmt: str, bump: str | None) -> None:
145
+ """构建并打包插件为 .mfp 文件
146
+
147
+ PLUGIN_PATH 为插件根目录(含 manifest.json),默认为当前目录。
148
+ """
149
+ from mpdt.commands.build import build_plugin
150
+
151
+ try:
152
+ build_plugin(
153
+ plugin_path=plugin_path,
154
+ output_dir=output,
155
+ with_docs=with_docs,
156
+ fmt=fmt,
157
+ bump=bump,
158
+ verbose=ctx.obj["verbose"],
159
+ )
160
+ except Exception as e:
161
+ console.print(f"[bold red]❌ 构建失败: {e}[/bold red]")
162
+ raise click.Abort()
146
163
 
147
164
 
148
165
  @cli.command()
@@ -0,0 +1,3 @@
1
+ """
2
+ 命令模块
3
+ """
@@ -0,0 +1,300 @@
1
+ """
2
+ 构建命令实现
3
+
4
+ 将插件目录打包为 .mfp 文件(本质为 ZIP 压缩包)。
5
+ loader.py 支持从 .mfp 直接加载插件,与文件夹加载行为一致。
6
+
7
+ 流程:
8
+ 1. 验证插件目录及 manifest.json
9
+ 2. 可选地自动升级版本号(major / minor / patch)
10
+ 3. 收集需打包的文件(排除缓存、版本控制等)
11
+ 4. 写入 .mfp(ZIP)或 .zip 文件
12
+ 5. 打印构建摘要
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import json
18
+ import re
19
+ import zipfile
20
+ from pathlib import Path
21
+
22
+ from rich.panel import Panel
23
+ from rich.table import Table
24
+
25
+ from mpdt.utils.color_printer import (
26
+ console,
27
+ print_error,
28
+ print_step,
29
+ print_success,
30
+ print_warning,
31
+ )
32
+
33
+ # 构建时默认排除的文件/目录名称(精确匹配)
34
+ _EXCLUDE_NAMES: set[str] = {
35
+ "__pycache__",
36
+ ".git",
37
+ ".gitignore",
38
+ ".gitattributes",
39
+ ".github",
40
+ ".mypy_cache",
41
+ ".ruff_cache",
42
+ ".pytest_cache",
43
+ ".venv",
44
+ "venv",
45
+ ".env",
46
+ "node_modules",
47
+ "dist",
48
+ ".DS_Store",
49
+ "Thumbs.db",
50
+ }
51
+
52
+ # 排除的文件扩展名
53
+ _EXCLUDE_EXTS: set[str] = {
54
+ ".pyc",
55
+ ".pyo",
56
+ ".pyd",
57
+ ".egg-info",
58
+ }
59
+
60
+ # 文档相关目录/文件名
61
+ _DOC_NAMES: set[str] = {
62
+ "docs",
63
+ "doc",
64
+ "README.md",
65
+ "README.rst",
66
+ "CHANGELOG.md",
67
+ "CHANGELOG.rst",
68
+ }
69
+
70
+
71
+ def _is_excluded(path: Path, with_docs: bool) -> bool:
72
+ """判断路径是否应被排除。"""
73
+ name = path.name
74
+ if name in _EXCLUDE_NAMES:
75
+ return True
76
+ if path.suffix in _EXCLUDE_EXTS:
77
+ return True
78
+ # 以 . 开头的隐藏文件/目录
79
+ if name.startswith("."):
80
+ return True
81
+ # 文档文件(若不包含文档)
82
+ if not with_docs and name in _DOC_NAMES:
83
+ return True
84
+ return False
85
+
86
+
87
+ def _collect_files(plugin_dir: Path, with_docs: bool) -> list[Path]:
88
+ """递归收集插件目录中需要打包的文件列表(相对路径)。"""
89
+ files: list[Path] = []
90
+
91
+ for item in sorted(plugin_dir.rglob("*")):
92
+ # 检查路径上的每个部分是否被排除
93
+ relative = item.relative_to(plugin_dir)
94
+ parts = relative.parts
95
+
96
+ excluded = False
97
+ for part in parts:
98
+ part_path = Path(part)
99
+ if _is_excluded(part_path, with_docs):
100
+ excluded = True
101
+ break
102
+
103
+ if excluded:
104
+ continue
105
+
106
+ if item.is_file():
107
+ files.append(item)
108
+
109
+ return files
110
+
111
+
112
+ def _bump_version(version: str, bump: str) -> str:
113
+ """按规则升级版本号(语义化版本 major.minor.patch)。
114
+
115
+ Args:
116
+ version: 当前版本字符串,例如 "1.2.3"
117
+ bump: 升级类型,"major" / "minor" / "patch"
118
+
119
+ Returns:
120
+ 升级后的版本字符串
121
+
122
+ Raises:
123
+ ValueError: 版本格式不合法
124
+ """
125
+ match = re.fullmatch(r"(\d+)\.(\d+)\.(\d+)(.*)", version.strip())
126
+ if not match:
127
+ raise ValueError(f"版本号格式不合法: '{version}',应为 major.minor.patch")
128
+
129
+ major, minor, patch, suffix = int(match.group(1)), int(match.group(2)), int(match.group(3)), match.group(4)
130
+
131
+ if bump == "major":
132
+ major += 1
133
+ minor = 0
134
+ patch = 0
135
+ elif bump == "minor":
136
+ minor += 1
137
+ patch = 0
138
+ elif bump == "patch":
139
+ patch += 1
140
+
141
+ return f"{major}.{minor}.{patch}{suffix}"
142
+
143
+
144
+ def _load_manifest(plugin_dir: Path) -> dict | None:
145
+ """读取并解析 manifest.json,返回字典;失败返回 None。"""
146
+ manifest_path = plugin_dir / "manifest.json"
147
+ if not manifest_path.exists():
148
+ print_error(f"manifest.json 不存在: {manifest_path}")
149
+ return None
150
+ try:
151
+ with open(manifest_path, encoding="utf-8") as f:
152
+ return json.load(f)
153
+ except json.JSONDecodeError as e:
154
+ print_error(f"manifest.json 解析失败: {e}")
155
+ return None
156
+
157
+
158
+ def _save_manifest(plugin_dir: Path, manifest: dict) -> None:
159
+ """将 manifest 字典写回 manifest.json。"""
160
+ manifest_path = plugin_dir / "manifest.json"
161
+ with open(manifest_path, "w", encoding="utf-8") as f:
162
+ json.dump(manifest, f, ensure_ascii=False, indent=4)
163
+
164
+
165
+ def build_plugin(
166
+ plugin_path: str = ".",
167
+ output_dir: str = "dist",
168
+ with_docs: bool = False,
169
+ fmt: str = "mfp",
170
+ bump: str | None = None,
171
+ verbose: bool = False,
172
+ ) -> None:
173
+ """构建并打包插件为 .mfp / .zip 文件。
174
+
175
+ Args:
176
+ plugin_path: 插件根目录(包含 manifest.json)
177
+ output_dir: 输出目录,默认 dist/
178
+ with_docs: 是否将文档文件打入包中
179
+ fmt: 输出格式,"mfp"(推荐) 或 "zip"
180
+ bump: 自动升级版本,"major" / "minor" / "patch" / None
181
+ verbose: 是否显示详细信息
182
+ """
183
+ plugin_dir = Path(plugin_path).resolve()
184
+
185
+ # ── 1. 基本验证 ──────────────────────────────────────────────────────────
186
+ if not plugin_dir.exists():
187
+ print_error(f"插件路径不存在: {plugin_dir}")
188
+ return
189
+ if not plugin_dir.is_dir():
190
+ print_error(f"插件路径不是目录: {plugin_dir}")
191
+ return
192
+
193
+ console.print(Panel.fit(f"📦 构建插件: [cyan]{plugin_dir.name}[/cyan]", border_style="blue"))
194
+
195
+ manifest = _load_manifest(plugin_dir)
196
+ if manifest is None:
197
+ return
198
+
199
+ required = ["name", "version", "description", "author", "entry_point"]
200
+ for field in required:
201
+ if field not in manifest:
202
+ print_error(f"manifest.json 缺少必需字段: '{field}'")
203
+ return
204
+
205
+ plugin_name: str = manifest["name"]
206
+ plugin_version: str = manifest["version"]
207
+
208
+ # ── 2. 版本升级 ──────────────────────────────────────────────────────────
209
+ if bump:
210
+ try:
211
+ new_version = _bump_version(plugin_version, bump)
212
+ except ValueError as e:
213
+ print_error(str(e))
214
+ return
215
+ print_step(f"版本升级: [yellow]{plugin_version}[/yellow] → [green]{new_version}[/green]")
216
+ manifest["version"] = new_version
217
+ _save_manifest(plugin_dir, manifest)
218
+ plugin_version = new_version
219
+
220
+ # ── 3. 验证入口文件 ───────────────────────────────────────────────────────
221
+ entry_point = manifest.get("entry_point", "plugin.py")
222
+ entry_file = plugin_dir / entry_point
223
+ if not entry_file.exists():
224
+ print_warning(f"入口文件不存在: {entry_point}(仍将继续构建)")
225
+
226
+ # ── 4. 收集文件 ───────────────────────────────────────────────────────────
227
+ print_step("收集文件...")
228
+ files = _collect_files(plugin_dir, with_docs)
229
+
230
+ if not files:
231
+ print_warning("未找到任何需要打包的文件")
232
+ return
233
+
234
+ if verbose:
235
+ for f in files:
236
+ rel = f.relative_to(plugin_dir)
237
+ console.print(f" [dim]+ {rel}[/dim]")
238
+
239
+ # ── 5. 确定输出路径 ───────────────────────────────────────────────────────
240
+ # output_dir 可以是绝对路径或相对于插件目录
241
+ out_path = Path(output_dir)
242
+ if not out_path.is_absolute():
243
+ out_path = plugin_dir / output_dir
244
+
245
+ out_path.mkdir(parents=True, exist_ok=True)
246
+
247
+ suffix = ".mfp" if fmt == "mfp" else ".zip"
248
+ archive_name = f"{plugin_name}-{plugin_version}{suffix}"
249
+ archive_path = out_path / archive_name
250
+
251
+ if archive_path.exists():
252
+ print_warning(f"目标文件已存在,将覆盖: {archive_path}")
253
+
254
+ # ── 6. 压缩打包 ───────────────────────────────────────────────────────────
255
+ print_step(f"正在写入 {suffix} 包...")
256
+ total_bytes = 0
257
+
258
+ try:
259
+ with zipfile.ZipFile(archive_path, "w", compression=zipfile.ZIP_DEFLATED) as zf:
260
+ for file_path in files:
261
+ arcname = file_path.relative_to(plugin_dir)
262
+ zf.write(file_path, arcname)
263
+ total_bytes += file_path.stat().st_size
264
+ if verbose:
265
+ console.print(f" [dim] → {arcname}[/dim]")
266
+ except Exception as e:
267
+ print_error(f"打包失败: {e}")
268
+ # 清理不完整的文件
269
+ if archive_path.exists():
270
+ archive_path.unlink()
271
+ return
272
+
273
+ # ── 7. 摘要 ──────────────────────────────────────────────────────────────
274
+ archive_size = archive_path.stat().st_size
275
+
276
+ table = Table(show_header=False, box=None, padding=(0, 2))
277
+ table.add_column(style="cyan")
278
+ table.add_column(style="white")
279
+ table.add_row("插件名称", plugin_name)
280
+ table.add_row("版本", plugin_version)
281
+ table.add_row("作者", manifest.get("author", "-"))
282
+ table.add_row("入口文件", entry_point)
283
+ table.add_row("打包文件数", str(len(files)))
284
+ table.add_row("原始大小", _format_size(total_bytes))
285
+ table.add_row("包大小", _format_size(archive_size))
286
+ table.add_row("输出路径", str(archive_path))
287
+
288
+ console.print()
289
+ console.print(table)
290
+ console.print()
291
+ print_success(f"构建完成: {archive_path.name}")
292
+
293
+
294
+ def _format_size(size: int) -> str:
295
+ """将字节数格式化为人类可读字符串。"""
296
+ for unit in ("B", "KB", "MB", "GB"):
297
+ if size < 1024:
298
+ return f"{size:.1f} {unit}"
299
+ size //= 1024
300
+ return f"{size:.1f} TB"
@@ -0,0 +1,7 @@
1
+ """开发模式桥接插件
2
+
3
+ 这是一个特殊的插件,在开发模式下临时注入到主程序。
4
+ 负责文件监控和插件热重载,配置由 mpdt dev 在注入时写入 dev_config.py。
5
+
6
+ Neo-MoFox 版本:使用 manifest.json 代替 PluginMetadata,符合新版插件系统规范。
7
+ """
@@ -5,11 +5,10 @@ DevBridge 清理事件处理器
5
5
 
6
6
  import shutil
7
7
  from pathlib import Path
8
- from typing import ClassVar
9
8
 
10
- from src.common.logger import get_logger
11
- from src.plugin_system.base import BaseEventHandler
12
- from src.plugin_system.base.component_types import EventType
9
+ from src.core.components.base.event_handler import BaseEventHandler
10
+ from src.core.components.types import EventType
11
+ from src.kernel.logger import get_logger
13
12
 
14
13
  from .dev_config import TARGET_PLUGIN_NAME, TARGET_PLUGIN_PATH
15
14
 
@@ -22,10 +21,10 @@ class CleanupHandler(BaseEventHandler):
22
21
  handler_name = "dev_bridge_cleanup"
23
22
  handler_description = "DevBridge 清理处理器"
24
23
  weight = -100 # 负权重,确保最后执行
25
- init_subscribe: ClassVar[list[EventType | str]] = [EventType.ON_STOP]
24
+ init_subscribe: list[EventType | str] = [EventType.ON_STOP]
26
25
 
27
- def __init__(self):
28
- super().__init__()
26
+ def __init__(self, plugin=None):
27
+ super().__init__(plugin)
29
28
  self._target_plugin_name = TARGET_PLUGIN_NAME
30
29
  self._target_plugin_path = TARGET_PLUGIN_PATH
31
30
 
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
16
16
  pass
17
17
 
18
18
  try:
19
- from src.common.logger import get_logger
19
+ from src.kernel.logger import get_logger
20
20
  logger = get_logger("dev_watcher")
21
21
  except ImportError:
22
22
  import logging
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "dev_bridge",
3
+ "version": "1.0.0",
4
+ "description": "开发模式桥接插件,提供文件监控和热重载功能",
5
+ "author": "MoFox Team",
6
+ "license": "GPL-3.0",
7
+ "min_core_version": "0.1.0",
8
+ "entry_point": "plugin.py",
9
+ "keywords": ["dev", "watcher", "reload", "bridge"],
10
+ "categories": ["utility"],
11
+ "dependencies": {
12
+ "plugins": [],
13
+ "components": []
14
+ },
15
+ "include": []
16
+ }
@@ -2,17 +2,16 @@
2
2
  DevBridge 插件 - 完整的开发模式插件
3
3
  负责文件监控、插件重载等所有开发操作
4
4
  配置通过 dev_config.py 中的常量传递(mpdt dev 注入时动态修改)
5
+
6
+ Neo-MoFox 版本:适配新版插件系统 API。
5
7
  """
6
8
 
7
9
  import asyncio
8
10
  from pathlib import Path
9
- from typing import ClassVar
10
11
 
11
- from src.common.logger import get_logger
12
- from src.plugin_system import (
13
- BasePlugin,
14
- register_plugin,
15
- )
12
+ from src.core.components.base.plugin import BasePlugin
13
+ from src.core.components.loader import register_plugin
14
+ from src.kernel.logger import get_logger
16
15
 
17
16
  # 导入配置(由 mpdt dev 注入时修改)
18
17
  from .dev_config import (
@@ -37,22 +36,23 @@ class DevBridgePlugin(BasePlugin):
37
36
  """
38
37
 
39
38
  plugin_name = "dev_bridge"
40
- enable_plugin = True
41
- config_file_name = "config.toml"
42
- dependencies: ClassVar = []
43
- python_dependencies: ClassVar = []
39
+ plugin_description = "开发模式桥接插件,提供文件监控和热重载功能"
40
+ plugin_version = "1.0.0"
44
41
 
45
- def __init__(self, *args, **kwargs):
46
- super().__init__(*args, **kwargs)
42
+ configs: list = []
43
+ dependent_components: list[str] = []
44
+
45
+ def __init__(self, config=None):
46
+ super().__init__(config)
47
47
  self._file_watcher = None
48
48
  self._target_plugin_name = TARGET_PLUGIN_NAME
49
49
  self._target_plugin_path = TARGET_PLUGIN_PATH
50
50
 
51
- def get_plugin_components(self) -> list:
51
+ def get_components(self) -> list[type]:
52
52
  """注册清理事件处理器"""
53
53
  from .cleanup_handler import CleanupHandler
54
54
 
55
- return [(CleanupHandler.get_handler_info(), CleanupHandler)]
55
+ return [CleanupHandler]
56
56
 
57
57
  async def on_plugin_loaded(self):
58
58
  """插件加载完成后启动文件监控"""
@@ -92,30 +92,20 @@ class DevBridgePlugin(BasePlugin):
92
92
  return
93
93
 
94
94
  try:
95
- from src.plugin_system.apis import plugin_manage_api
95
+ from src.core.managers.plugin_manager import get_plugin_manager
96
96
 
97
- is_loaded = plugin_manage_api.is_plugin_loaded(self._target_plugin_name)
98
- is_enabled = plugin_manage_api.is_plugin_enabled(self._target_plugin_name)
97
+ plugin_manager = get_plugin_manager()
98
+ is_loaded = plugin_manager.is_plugin_loaded(self._target_plugin_name)
99
99
 
100
100
  if not is_loaded:
101
101
  logger.error("=" * 60)
102
102
  logger.error(f"❌ 目标插件 {self._target_plugin_name} 未加载!")
103
103
  logger.error("")
104
- if not is_enabled:
105
- logger.error("📋 原因: 插件已被禁用")
106
- logger.error("")
107
- logger.error("🔧 解决方案:")
108
- logger.error(" 1. 检查插件的 config.toml 中 [plugin] enabled = true")
109
- logger.error(" 2. 或在 plugin.py 中设置 enable_plugin = True")
110
- logger.error(" 3. 或直接删除 enable_plugin 行(默认启用)")
111
- else:
112
- logger.error("📋 原因: 插件加载失败,请检查插件代码是否有错误")
104
+ logger.error("📋 原因: 插件加载失败,请检查插件代码是否有错误")
113
105
  logger.error("=" * 60)
114
106
  else:
115
107
  logger.info(f"✅ 目标插件 {self._target_plugin_name} 已成功加载")
116
108
 
117
- except ValueError:
118
- logger.error(f"❌ 目标插件 {self._target_plugin_name} 未注册")
119
109
  except Exception as e:
120
110
  logger.error(f"❌ 检查目标插件状态时出错: {e}")
121
111
 
@@ -136,49 +126,29 @@ class DevBridgePlugin(BasePlugin):
136
126
  return
137
127
 
138
128
  try:
139
- from src.plugin_system.apis import plugin_manage_api
129
+ from src.core.managers.plugin_manager import get_plugin_manager
140
130
 
131
+ plugin_manager = get_plugin_manager()
141
132
  plugin_name = self._target_plugin_name
142
- is_loaded = plugin_manage_api.is_plugin_loaded(plugin_name)
143
- is_enabled = plugin_manage_api.is_plugin_enabled(plugin_name)
133
+ is_loaded = plugin_manager.is_plugin_loaded(plugin_name)
144
134
 
145
135
  if is_loaded:
146
- # 插件已加载,检查是否被禁用
147
- if not is_enabled:
148
- logger.info(f"🔓 插件 {plugin_name} 已禁用,正在启用...")
149
- await plugin_manage_api.enable_plugin(plugin_name)
150
-
151
- # 重载插件
136
+ # 插件已加载,直接重载
152
137
  logger.info(f"🔄 正在重载插件: {plugin_name}...")
153
- success = await plugin_manage_api.reload_plugin(plugin_name)
138
+ success = await plugin_manager.reload_plugin(plugin_name)
154
139
  if success:
155
140
  logger.info(f"✅ 插件 {plugin_name} 重载成功")
156
141
  else:
157
142
  logger.error(f"❌ 插件 {plugin_name} 重载失败")
158
143
  else:
159
- # 插件未加载,使用 enable_plugin 来加载并启用
160
- # enable_plugin 会同时处理加载和启用,即使插件之前被禁用
161
- logger.info(f"📦 插件 {plugin_name} 未加载,正在启用并加载...")
162
- success = await plugin_manage_api.enable_plugin(plugin_name)
144
+ # 插件未加载,通过路径直接加载
145
+ logger.info(f"📦 插件 {plugin_name} 未加载,正在从路径加载...")
146
+ success = await plugin_manager.load_plugin(self._target_plugin_path)
163
147
  if success:
164
- logger.info(f"✅ 插件 {plugin_name} 启用并加载成功")
165
- else:
166
- logger.error(f"❌ 插件 {plugin_name} 启用/加载失败")
167
-
168
- except ValueError as e:
169
- # 插件未注册,尝试扫描并加载
170
- logger.warning(f"⚠️ 插件未注册: {e}")
171
- logger.info("🔍 正在扫描插件目录...")
172
- try:
173
- from src.plugin_system.apis import plugin_manage_api
174
-
175
- plugin_manage_api.rescan_and_register_plugins(load_after_register=True)
176
- if plugin_manage_api.is_plugin_loaded(self._target_plugin_name):
177
- logger.info(f"✅ 插件 {self._target_plugin_name} 扫描并加载成功")
148
+ logger.info(f"✅ 插件 {plugin_name} 加载成功")
178
149
  else:
179
- logger.error(f"❌ 插件 {self._target_plugin_name} 扫描后仍未加载")
180
- except Exception as scan_e:
181
- logger.error(f"❌ 扫描插件目录失败: {scan_e}")
150
+ logger.error(f"❌ 插件 {plugin_name} 加载失败")
151
+
182
152
  except Exception as e:
183
153
  logger.error(f"❌ 操作插件时出错: {e}")
184
154
  import traceback
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mofox-plugin-dev-toolkit"
7
- version = "0.4.1"
7
+ version = "0.4.3"
8
8
  description = "开发工具集,用于快速创建、开发和测试 MoFox-Bot 插件"
9
9
  authors = [
10
10
  {name = "MoFox-Studio", email = "wwwww95915@qq.com"}
@@ -1,9 +0,0 @@
1
- """
2
- 命令模块
3
- """
4
-
5
- __all__ = [
6
- "init",
7
- "generate",
8
- "check",
9
- ]
@@ -1,17 +0,0 @@
1
- """开发模式桥接插件
2
-
3
- 这是一个特殊的插件,在开发模式下临时注入到主程序。
4
- 负责文件监控和插件热重载,配置由 mpdt dev 在注入时写入 dev_config.py。
5
- """
6
-
7
- from src.plugin_system.base.plugin_metadata import PluginMetadata
8
-
9
- __plugin_meta__ = PluginMetadata(
10
- name="dev_bridge",
11
- description="开发模式桥接插件,提供文件监控和热重载功能",
12
- usage="在开发模式下临时注入,监控目标插件文件变化并自动重载。",
13
- version="1.0.0",
14
- author="MoFox Team",
15
- dependencies=[],
16
- python_dependencies=["watchdog"],
17
- )