跳到主要内容
路径文档

插件库存

实时看一下当前部署里装了哪些插件、它们处于什么状态。DSH 暴露一个只读的 pluginInventory 服务,通过 Remote 把当前 Cordis Loader 树投影给客户端;Web 设置里的「插件」标签页就是它的可视面。

只读投影:ctx.pluginInventory

packages/host/plugin-inventory(包名 @deepseek-ai/dsh-host-plugin-inventory)的 PluginInventoryGateway 注册 pluginInventory 服务,并发布一个由 Typert 生成的直接 Remote:pluginInventory/list

每次调用都直接读 ctx.loader.entries(),跳过结构性的 group 行,按 Loader 顺序返回其余条目——只带四个字段:

字段含义
entryIdLoader 树条目的稳定标识(branded PluginEntryId)
moduleName该条目 import 的精确模块标识
enabled有效启用状态(含被禁用的祖先 group)
fiberPhase当前根 Fiber 阶段,无根 fiber 时 null
// packages/host/plugin-inventory/src/index.ts —— 直接读 Loader,不建第二份缓存
@Remote('list')
list(): PluginInventorySnapshot {
const entries: PluginInventoryEntry[] = []
for (const entry of this.ctx.loader.entries()) {
if (entry.options.group) continue
entries.push({
entryId: pluginEntryId(entry.id),
moduleName: entry.options.name,
enabled: !entry.disabled,
fiberPhase: entry.fiber === undefined ? null : FIBER_PHASE[entry.fiber.state],
})
}
return { entries }
}

fiberPhase 取值

取值Cordis Fiber 状态含义
pendingPENDING尚未开始加载
loadingLOADING正在加载模块
activeACTIVE已激活运行
failedFAILED加载/激活失败
unloadingUNLOADING正在卸载
nullDISPOSED无存活的根 Fiber

快照是当下的点:Loader 仍是唯一的生命周期权威,本包不拥有缓存、历史、来源模型、事件流或修改路径。服务是 Remote-only,刻意不声明同进程 Cordis Context merge——Client 包经 api-remotes 装配消费它。

// packages/host/plugin-inventory/src/types.ts —— 阶段投影
export type PluginFiberPhase =
| 'pending' | 'loading' | 'active' | 'failed' | 'unloading' | null

Web 设置里的「插件」标签页

packages/client/ui-settings-plugin-inventory(@deepseek-ai/dsh-client-ui-settings-plugin-inventory)是浏览器插件,注册 id 为 all 的本地化 settings.plugins.tab 贡献。「插件」分区拥有导航入口与标签栏。

  • 懒加载:首次选择标签页才挂载组件,经 api-remotes 懒调用 ctx.remote.pluginInventory.list()
  • 渲染一个可搜索的双列卡片目录;每张收起的卡片 = 模块短名称标题 + 有效启停标签 + (已启用时的)彩色根 fiber 状态圆点
  • 展开卡片后:Loader 树条目 id、有效配置状态,已启用条目额外显示 Cordis 状态;已停用条目省略"未挂载"运行状态
  • 搜索匹配 module 名与 entryId;加载/空/无匹配/失败状态只属于已挂载组件,读取失败可重试且不暴露传输细节
// ui-settings-plugin-inventory/src/client/index.ts —— 经 slots 注册,不 import 分区拥有方
ctx.slots.inject('settings.plugins.tab', () => ctx.slots.register({
name: 'settings.plugins.tab', id: 'all', order: 10,
label: () => t('tab'), locale: NS, inject: injected,
}, PluginInventorySettingsTab))

状态点用 data-phase 上色:启用且 active → 表示成功的绿,failed → 错误色,loading → 进行中色,其余为灰(见 PluginInventorySettingsTab.module.css.statusDot[data-phase='…'])。

与相邻能力的区别

能力关系
插件安装管理plugins.md管理面(启用/停用/安装);本能力是只读投影,没有任何修改路径
tool-cordis模型侧的工具;本能力是部署/宿主侧的 Loader 树视图,无工具或提示词注册
ctx.loader生命周期的唯一权威;pluginInventory 只是它的只读镜像

本能力不注册任何提示词、工具、消息或提供方请求(README Model Experience: None)。

验证

# 组合树里确认服务与 Remote 贡献存在
dsh web --dump-config | grep -iE "plugin-inventory|pluginInventory"

# 打开 Web 设置 →「插件」标签页,看可搜索的卡片目录与彩色状态圆点

下一步