05. 插件生命周期
翻译说明: 本页是与 英文源规格 一一对应的机器辅助翻译。代码、协议字段和标识符保持原文;如翻译与英文源事实有歧义,以英文版本为准。
1. 目标
定义从发现到卸载的完整状态机,保证:
- 可预测的行为
- 可恢复的故障
- 可审计的 start/stop
- 与命令面板/AgentTool 注册保持一致
2. 状态机
text
discovered
→ validated
→ installed
→ enabled
→ loaded
→ running
→ load_error
→ disabled
→ install_error
→ invalid状态描述
| 状态 | 含义 |
|---|---|
| 发现了 | 扫描插件目录或包 |
| 已验证 | 清单/文件完整性已通过 |
| 已安装 | 写入安装目录并注册 |
| 已启用 | 由用户启用,允许加载 |
| 已加载 | 运行时加载,贡献点注册 |
| 跑步 | 具有活动面板/后台逻辑 |
| 残疾人 | 已安装但被用户关闭 |
| 加载错误 | 启用后加载失败 |
| 安装错误 | 安装失败 |
| 无效 | 验证失败,无法使用 |
3. 生命周期挂钩
**今天实现:**运行时(apps/desktop/electron/main/plugin-runtime.ts)调用onLoad(当在load/enable上加载插件时)和onUnload(在unload/disable/reload上调度到插件进程,预算5s,然后进程停止);卸载会删除插件注册的命令和工具。下面的其他挂钩在 API 中声明但尚未触发。
**计划:**一旦完整生命周期落地,钩子将按以下顺序触发:
onInstall(一次,仅在成功安装后) 2.onEnable3.onLoad4.运行时事件 5.onUnload6.onDisable7.onUninstall
调用约束
- Hooks 必须能够超时(默认 5 秒,可配置)
- 钩子异常不得使主机崩溃
- 如果
onLoad失败,请输入load_error并自动回滚已注册的贡献点
3. 1 居民服务
contributes.services 中声明的服务由主机驱动,而不是由主机驱动 插件自己的钩子,因此它的窗口严格在插件的生命周期内:
onLoad完成并注册贡献积分- 对于每个声明的服务(每个插件最多 4 个,门控
background.service),broker 在插件进程中调用service.start预算为 5 秒。启动失败标志着一个服务failed并离开 加载插件的其余部分。 - 卸载/禁用/重新加载时,
service.stop先于onUnload运行,因此 服务很安静,而插件仍然有其 API
每项服务的状态为 starting | running | stopped | failed 加一个 重新启动计数,可通过插件 IPC 表面读取并显示在插件上 页。
重启政策
该服务存在于插件的主机进程中,因此崩溃会导致它崩溃 过程。然后主管重新启动整个插件:
- 回退
1s, 2s, 4s, 8s, 16s,上限为 30 秒 - 最多重启5次;之后插件会在
failed中保持关闭状态,因此用户 看到失败而不是无声的崩溃循环 - 存活 60 秒的进程被认为是健康的,并且退避重置为 零
- 服务上的
autoRestart: false选择其插件完全不重新启动 - 当用户重新启用或删除插件时,将跳过重新启动 退避计时器待处理
手动启用/禁用始终赢得主管的青睐:明确的操作 清除挂起的计时器和尝试计数器。
4. 启用/禁用语义
启用
- 将状态设置为启用
- 尝试加载
- 成功:注册命令/工具/技能/主题/MCP服务器,然后启动 居民服务
- 失败:自动回退到禁用状态并向用户显示错误。这被 D017 冻结(启用→加载失败自动禁用插件)。
禁用
- 取消注册命令/工具
- 关闭面板
- 停止常驻服务并断开 MCP 服务器的连接
- 取消任何挂起的重启退避
- 致电
onUnload/onDisable - 继续作为残疾人
5. 启动恢复
在应用程序启动时:
1.扫描已安装的插件 2. 读取使能状态 3.仅加载已启用的插件 4. 跳过单个失败的插件而不影响其他插件或主应用程序
6. 开发者模式
dev-loaded 插件:
- 未复制到
installed - 直接引用本地路径
- 可以观看和热重载
- 重新加载流程:
unload → validate → load
热重载时:
- 尽可能保留插件设置
- 不保证保留面板内存中状态
7. 贡献点register/unregister交易
每个插件的加载过程应该大致是事务性的:
text
begin
register commands
register tools
register skills
register themes
register MCP servers (lazy connect)
commit
start resident services关于中途失败:
text
rollback all registrations from this plugin避免出现“命令存在但工具不存在”的半加载状态。
8. 审计事件
至少记录:
- 插件.安装
- 插件.卸载
- 插件.启用
- 插件.禁用
- 插件.加载.成功
- 插件加载错误
- 插件.卸载
- 插件崩溃
- 插件.服务.启动/插件.服务.停止
- 插件.服务.重新启动 / 插件.服务.重新启动.预定 -plugin.services.skipped(缺少权限或超过每个插件的上限)
领域:
- 插件ID
- 版本
- 源(
installed|dev|marketplace) - TS
- 错误代码?
- 尝试? / 延迟女士? (服务重新启动)
9. 卸载策略
卸载前: 1.禁用+卸载 2. 调用onUninstall 3.删除已安装的文件 4.清理插件私有数据(可能会询问用户是否保留)
默认推荐:
- 卸载时清理 settings/data(D016:卸载默认删除插件数据)
- 提供“保留数据”高级选项(可以推迟)