Skip to content

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 中声明但尚未触发。

**计划:**一旦完整生命周期落地,钩子将按以下顺序触发:

  1. onInstall(一次,仅在成功安装后) 2.onEnable 3.onLoad 4.运行时事件 5.onUnload 6.onDisable 7.onUninstall

调用约束

  • Hooks 必须能够超时(默认 5 秒,可配置)
  • 钩子异常不得使主机崩溃
  • 如果onLoad失败,请输入load_error并自动回滚已注册的贡献点

3. 1 居民服务

contributes.services 中声明的服务由主机驱动,而不是由主机驱动 插件自己的钩子,因此它的窗口严格在插件的生命周期内:

  1. onLoad完成并注册贡献积分
  2. 对于每个声明的服务(每个插件最多 4 个,门控 background.service),broker 在插件进程中调用 service.start 预算为 5 秒。启动失败标志着一个服务 failed 并离开 加载插件的其余部分。
  3. 卸载/禁用/重新加载时,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:卸载默认删除插件数据)
  • 提供“保留数据”高级选项(可以推迟)

为本地优先开发而构建。