建立日期:2026-11-13 状态:装配完成(10 个测试通过),SnowLuma 侧已加
onAppCreated钩子
把 unified 的两个扩展装进 SnowLuma:
| 扩展 | 作用 |
|---|---|
@unified/plugin |
插件系统(加载、事件分发、action 回退) |
@unified/native-offsets |
签名扫描(Windows 封包 hook 用) |
SnowLuma 已经提供了两个接缝:
| 接缝 | 位置 | 用途 |
|---|---|---|
OneBotManager.setPluginBridge() |
onebot/src/manager.ts |
事件分发 + action 回退 |
initWebUI(..., { plugins }) |
core/src/webui/server.ts |
插件管理 API |
所以 unified 不需要 fork SnowLuma 的 main(),只要在它启动后拿到实例、把桥接装上去。
这样做的代价是:需要能在启动流程里插一脚。
import { createUnifiedRuntime } from '@unified/runtime';
// 时机:OneBotManager 与 Hono app 都已创建、WebUI 开始监听之前
const unified = await createUnifiedRuntime(
{
dataDir: 'data',
pluginAllowList: ['my-plugin'], // 白名单,空数组 = 不加载
builtinActionNames: new Set(ACTION_NAMES),
logger: appLogger,
},
honoApp,
);
// 1. 接到 OneBot
oneBotManager.setPluginBridge(unified.bridge);
// 2. 接到 WebUI
initWebUI(port, oneBotManager, hookManager, notificationManager, {
plugins: unified.webuiHooks,
});
// 3. 退出时
await unified.dispose();
UnifiedRuntime| 字段 | 用途 |
|---|---|
plugins |
PluginManager 实例 |
actions |
插件 action 注册表 |
bridge |
交给 setPluginBridge() |
webuiHooks |
交给 initWebUI(..., { plugins }) |
dispose() |
卸载全部插件 |
2026-11-13 完成:SnowLuma 的 initWebUI 加了 onAppCreated 钩子。
initWebUI(port, oneBotManager, hookManager, notificationManager, {
onAppCreated: async (app) => {
const unified = await createUnifiedRuntime(
{
dataDir: 'data',
pluginAllowList: config.plugins.enabled,
builtinActionNames: new Set(ACTION_NAMES),
logger: appLogger,
},
app,
);
// 接到 OneBot(事件分发 + action 回退)
oneBotManager.setPluginBridge(unified.bridge);
// 返回值被 initWebUI 当作 plugins 钩子,注册管理 API
return unified.webuiHooks;
},
});
honoApp 在 initWebUI 内部创建,外面拿不到。而插件需要在 app 上注册自己的路由(/api/plugin/<id>/...)。
onAppCreated 在 app 创建后、路由注册前调用,正好解决这个问题。返回值直接当 plugins 用,省掉宿主再传一遍。
initWebUI()
├─ const app = new Hono()
├─ 安全中间件
├─ onAppCreated(app) ← unified 在这里装配
│ ├─ createUnifiedRuntime({...}, app)
│ │ ├─ 创建 plugins 目录
│ │ ├─ PluginLoader 扫描 + 白名单
│ │ ├─ PluginManager.loadAll()
│ │ │ └─ 每个插件的 plugin_init(ctx)
│ │ │ └─ ctx.router.get(...) → 注册到 app
│ │ └─ 返回 bridge + webuiHooks
│ └─ oneBotManager.setPluginBridge(bridge)
├─ 注册 /api/plugins(管理 API)
└─ 其余路由...
---
## 六、测试覆盖
10 个测试,覆盖:
- 插件目录自动创建
- 白名单过滤
- 插件加载
- action 通过桥接暴露
- 内置 action 保护(插件不能覆盖)
- 事件转发
- WebUI 钩子
- 插件路由注册到 Hono
- dispose 卸载
```bash
cd unified
pnpm --filter @unified/runtime test
| 路径 | 角色 |
|---|---|
packages/runtime/src/index.ts |
createUnifiedRuntime() 装配逻辑 |
packages/runtime/tests/ |
10 个测试 |
packages/plugin/src/snowluma-bridge.ts |
桥接适配器 |
packages/plugin/src/hono-router.ts |
Hono 路由适配 |