feat(v0.5.2): 插件索引仓库 + install 命令

PluginIndex 服务:
- 从远程 JSON 索引获取可用插件列表
- 支持 zip 包和单文件 .py 两种格式安装
- 自动解压/移动到 plugins/ 目录
- 默认索引地址: GitHub Pages

install 内置命令:
- install --list → 列出远程可用插件
- install <name> → 下载并安装
- 自动缓存索引,避免重复请求

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
qinglong
2026-06-13 11:08:47 +08:00
parent 7ce495de2a
commit fca2aa5a05
2 changed files with 144 additions and 3 deletions
+36 -3
View File
@@ -281,15 +281,48 @@ class CommandService:
permissions=["framework.tui.control"],
source="internal"
)
# 插件安装命令
self.register_command(
name="install",
handler=self._cmd_install,
description="从在线索引安装插件: install <name> 或 install --list",
permissions=["framework.plugin.install"],
source="internal",
)
logger.info(f"内置命令注册完成,共注册 {len(self.commands)} 个命令")
except Exception as e:
logger.error(f"注册内置命令时出错: {str(e)}", exc_info=True)
raise
async def _cmd_install(self, *args) -> str:
"""插件安装命令"""
try:
from services.plugin_index import PluginIndex
index = PluginIndex()
if not args or args[0] == "--list":
plugins = await index.fetch_index()
if not plugins:
return "📭 插件索引为空或无法连接"
lines = [f"📦 可用插件 ({len(plugins)}):", "=" * 40]
for p in plugins:
lines.append(
f" 🔹 {p.get('name','?')} v{p.get('version','?')}"
f"{p.get('description','?')[:50]}"
)
lines.append("\n💡 install <name> 安装插件")
return "\n".join(lines)
name = args[0]
ok = await index.install(name)
if ok:
return f"✅ 插件安装完成: {name}\n💡 重启框架或使用热重载加载新插件"
return f"❌ 安装失败: {name}"
except ImportError:
return "❌ 缺少 aiohttp,无法使用插件安装功能"
async def _cmd_netdiag(self, *args) -> str:
"""网络诊断命令"""
try: