@deepseek-ai/dsh-host-plugin-inventory 0.1.6-alpha.2 → 0.1.7-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/host/plugin-inventory/README.md
5
- README.md: b64a017df28716cfd0b5c3a41f437b87b8e4f19e
6
- README.zh.md: a29bc402537d88fa512675bfb768502753ca7929
5
+ README.md: 8450339c1430b2ed1620004343f75d9cc21a0a19
6
+ README.zh.md: 345bf367ce9fe85fdfc80994a09e3b2f26fdc0ce
package/README.md CHANGED
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
9
9
 
10
10
  ## Summary
11
11
 
12
- Clients can call `pluginInventory/list` to display the host’s current plugins in load order, including each entry’s identifier, module specifier, effective enablement, and live phase. Deployments with an agent-preset roster also report each preset’s metadata, health, and flattened plugin composition; without a roster, preset data is absent. Each response is a point-in-time, read-only snapshot for display and diagnostics: it cannot mutate plugins and provides no history, introduction source, or change subscription.
12
+ Clients can call `pluginInventory/list` to display the host’s current plugins in load order, including each entry’s identifier, module specifier, effective enablement, live phase, and available display text. Deployments with an agent-preset roster also report each preset’s metadata, health, and flattened plugin composition; without a roster, preset data is absent. Each response is a point-in-time, read-only snapshot for display and diagnostics: it cannot mutate plugins and provides no history or change subscription.
13
13
 
14
14
  ## Table of Contents
15
15
 
@@ -31,6 +31,8 @@ Call `pluginInventory/list` when a client or settings page needs to show what is
31
31
 
32
32
  Each row is one non-group Loader entry: its entry id, the exact module specifier, the effective enablement (including disabled ancestor groups), and the current root Fiber phase. `pending` means the entry waits to load, `loading` that it is being read, `active` that it is running, `failed` that its fiber rejected, and `unloading` that it is being torn down; `null` means no live root Fiber exists at all. Structural group rows are skipped.
33
33
 
34
+ Loader and preset rows can carry optional `meta` with a title, description, or metadata diagnostic. The Host returns available translations and literal fallbacks; the Client selects its language. Metadata diagnostics do not change enablement or fiber phase.
35
+
34
36
  ### Per-preset compositions
35
37
 
36
38
  With a roster composed, `agentPresets` carries one group per preset in roster order: its id, whether the deployment ships it or the user owns it (`trust`, which clients use to localize shipped names), published display name, whether a session naming no preset composes it, and flattened plugin rows — entry id (null when the file row declares none), module specifier, effective enablement, the row's own `!!js` disabled expression when it carries one, and a root-fiber phase when the composition is live. A preset some session already composed answers from its newest standing generation — even when its file has since broken, because the mount is what those sessions run; one never composed since boot answers from its composition file with disabled gates evaluated against the Loader context, and reading never mounts a preset. `conditional` enablement marks a gate the Host could not evaluate, and a broken preset nothing composed stays listed with its reason and no rows. Without a roster the field is absent.
@@ -49,7 +51,9 @@ The inventory is a snapshot for display and diagnostics: a client can render the
49
51
 
50
52
  ### Design concept
51
53
 
52
- The gateway is a direct projection with no second lifecycle truth: every `list()` call reads `ctx.loader.entries()` and maps each non-group entry to its public row. Cordis's internal `plugin/status` events already maintain `Entry.fiber` and `Fiber.state`, so a cache would only add another lifecycle truth to keep synchronized. The agent-preset roster is an optional peer resolved per call through `ctx.get('agentPresets')`: its `compositionInventory()` owns every preset read, and this package only maps root-fiber states onto the public phase vocabulary.
54
+ The gateway is a direct projection with no second lifecycle truth: every `list()` call reads `ctx.loader.entries()` and maps each non-group entry to its public row. Cordis's internal `plugin/status` events already maintain `Entry.fiber` and `Fiber.state`, so a cache would only add another lifecycle truth to keep synchronized. The agent-preset roster is an optional peer resolved per call through `ctx.get('agentPresets')`: its `compositionInventory()` owns preset composition reads, and this package maps root-fiber states onto the public phases.
55
+
56
+ Display metadata comes from the optional `pluginPackages` service using each Loader tree's resolution base, or the gateway context's base for preset rows. Without the service or the applicable base, `meta` is absent. Reading metadata does not load or activate plugins.
53
57
 
54
58
  ### The phase mapping
55
59
 
@@ -97,8 +101,8 @@ None; this package neither assembles nor sends a provider request.
97
101
  These limits define what a point-in-time inventory cannot tell a client. They are current package constraints, not a task backlog.
98
102
 
99
103
  - **Point-in-time state only** — the result contains no durable failure history or subscription; a missing root Fiber is reported as `null`, regardless of why no live root exists.
100
- - **No introduction source or mutation** — the service does not identify which bundle, profile, or override introduced an entry, and it cannot enable, disable, add, or remove plugins in either plane.
101
- - **Presets appear only with a roster** — a deployment without `dsh-agent-presets` serves Loader entries alone; the `agentPresets` field is absent rather than empty.
104
+ - **No layer attribution or mutation** — the service does not identify which bundle, profile, or override introduced an entry, and it cannot enable, disable, add, or remove plugins in either plane.
105
+ - **Presets appear only with a roster** — a deployment without `dsh-agent-preset-registry` serves Loader entries alone; the `agentPresets` field is absent rather than empty.
102
106
 
103
107
  <a id="dev-note"></a>
104
108
  ### Dev Note
package/README.zh.md CHANGED
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- 客户端可以调用 `pluginInventory/list`,按加载顺序展示宿主的当前插件,包括每个条目的标识符、模块标识、有效启用状态与存活阶段。部署组合了 agent preset roster 时,还会报告各预设的元数据、健康状态与压平后的插件组合;没有 roster 时,预设数据缺席。每次响应都是供展示和诊断使用的只读即时快照:它不能修改插件,也不提供历史、来源信息或变更订阅。
12
+ 客户端可以调用 `pluginInventory/list`,按加载顺序展示宿主的当前插件,包括每个条目的标识符、模块标识、有效启用状态、存活阶段与可用的展示文本。部署组合了 agent preset roster 时,还会报告各预设的元数据、健康状态与压平后的插件组合;没有 roster 时,预设数据缺席。每次响应都是供展示和诊断使用的只读即时快照:它不能修改插件,也不提供历史或变更订阅。
13
13
 
14
14
  ## 目录
15
15
 
@@ -31,6 +31,8 @@ kind: "package-reference"
31
31
 
32
32
  每一行是一个非组 Loader 条目:其条目 id、精确模块标识、有效启用状态(含被禁用的祖先组)与当前根 Fiber 阶段。`pending` 表示条目等待加载,`loading` 表示正在读取,`active` 表示正在运行,`failed` 表示其 fiber 被拒绝,`unloading` 表示正在拆除;`null` 表示完全不存在存活的根 Fiber。结构性的 group 行会被跳过。
33
33
 
34
+ Loader 行与预设行可以携带可选的 `meta`,其中包含标题、描述或元信息诊断。Host 返回可用翻译与字面回退文本,由 Client 选择语言。元信息诊断不改变启停状态或 fiber 阶段。
35
+
34
36
  ### 每个预设的组合
35
37
 
36
38
  组合了 roster 时,`agentPresets` 按 roster 顺序携带每个预设一组:其 id、随部署内置还是用户自建(`trust`,客户端据此本地化内置预设名)、发布的显示名、未指名预设的会话是否组合它,以及压平后的插件行——条目 id(文件行未声明时为 null)、模块标识、有效启用状态、行自带的 `!!js` disabled 表达式(如有),以及组合存活时的根 Fiber 阶段。已有会话组合过的预设由其最新仍存续的世代作答——即使其文件事后损坏也是如此,因为挂载才是这些会话实际运行的组合;开机以来从未被组合的预设由其组合文件作答,disabled 门用 Loader 上下文求值,且读取从不挂载预设。`conditional` 表示宿主无法求值的门;无人组合的坏预设保留在列表中,携带原因且没有行。没有 roster 时该字段缺席。
@@ -49,7 +51,9 @@ kind: "package-reference"
49
51
 
50
52
  ### 设计理念
51
53
 
52
- 网关是一层没有第二个生命周期真源的直接投影:每次 `list()` 调用都读取 `ctx.loader.entries()`,并把每个非组条目映射为公共行。Cordis 内部的 `plugin/status` 事件已经维护了 `Entry.fiber` 与 `Fiber.state`,因此再加缓存只会多出一个需要同步的生命周期真源。agent preset roster 是每次调用经 `ctx.get('agentPresets')` 解析的可选伙伴:所有预设读取都由它的 `compositionInventory()` 负责,本包只把根 Fiber 状态映射到公共阶段词汇。
54
+ 网关是一层没有第二个生命周期真源的直接投影:每次 `list()` 调用都读取 `ctx.loader.entries()`,并把每个非组条目映射为公共行。Cordis 内部的 `plugin/status` 事件已经维护了 `Entry.fiber` 与 `Fiber.state`,因此再加缓存只会多出一个需要同步的生命周期真源。agent preset roster 是每次调用经 `ctx.get('agentPresets')` 解析的可选伙伴:预设组合读取由它的 `compositionInventory()` 负责,本包把根 Fiber 状态映射到公共阶段。
55
+
56
+ 展示元信息来自可选的 `pluginPackages` 服务:Loader 行使用其所属树的解析基准,预设行使用网关上下文的基准。服务或对应基准不存在时,`meta` 缺席。读取元信息不会加载或激活插件。
53
57
 
54
58
  ### 阶段映射
55
59
 
@@ -97,8 +101,8 @@ Typert 生成由 `./typert` 与 `./remote` 导出的 Host 和 Client Remote 产
97
101
  这些限制说明即时清单无法向客户端提供哪些信息。它们是当前包约束,不是任务积压。
98
102
 
99
103
  - **仅表示调用当下**——结果不包含持久的失败历史或订阅;只要不存在存活的根 Fiber,就会报告 `null`,而不区分其原因。
100
- - **无来源与修改能力**——服务不识别条目由哪个 bundle、profile 或 override 引入,也不能在任一平面启用、停用、添加或移除插件。
101
- - **预设仅随 roster 出现**——未装 `dsh-agent-presets` 的部署只提供 Loader 条目;`agentPresets` 字段缺席而非为空。
104
+ - **不标识引入层,也不修改插件**——服务不识别条目由哪个 bundle、profile 或 override 引入,也不能在任一平面启用、停用、添加或移除插件。
105
+ - **预设仅随 roster 出现**——未装 `dsh-agent-preset-registry` 的部署只提供 Loader 条目;`agentPresets` 字段缺席而非为空。
102
106
 
103
107
  <a id="dev-note"></a>
104
108
  ### 开发备注
package/lib/index.js CHANGED
@@ -106,8 +106,8 @@ let PluginInventoryGateway = (() => {
106
106
  * preset's composition rows, because those rows — not the Loader's own
107
107
  * entries — are where a deployment that mounts the roster runs its
108
108
  * model-facing plugins.
109
- * @returns Current non-group Loader entries in Loader order, with per-preset
110
- * compositions when a roster is composed.
109
+ * @returns Current non-group Loader entries in Loader order, with optional display metadata
110
+ * and per-preset compositions when a roster is composed.
111
111
  */
112
112
  async list() {
113
113
  return readPluginInventory(this.ctx);
@@ -116,17 +116,21 @@ let PluginInventoryGateway = (() => {
116
116
  })();
117
117
  /** Read current Loader entries and optional preset compositions.
118
118
  * @param ctx Context with the Loader service.
119
- * @returns Current inventory without a separate runtime cache.
119
+ * @returns Current inventory with optional display metadata and no separate runtime cache.
120
120
  */
121
121
  async function readPluginInventory(ctx) {
122
122
  const entries = [];
123
+ const packages = ctx.get("pluginPackages");
123
124
  for (const entry of ctx.loader.entries()) {
124
125
  if (entry.options.group) continue;
126
+ const base = entry.parent.tree.ctx.baseUrl;
127
+ const meta = base === void 0 ? void 0 : packages?.metaOf(entry.options.name, base);
125
128
  entries.push({
126
129
  entryId: pluginEntryId(entry.id),
127
130
  moduleName: entry.options.name,
128
131
  enabled: !entry.disabled,
129
- fiberPhase: entry.fiber === void 0 ? null : FIBER_PHASE[entry.fiber.state]
132
+ fiberPhase: entry.fiber === void 0 ? null : FIBER_PHASE[entry.fiber.state],
133
+ ...meta === void 0 ? {} : { meta }
130
134
  });
131
135
  }
132
136
  const presets = ctx.get("agentPresets");
@@ -139,10 +143,14 @@ async function readPluginInventory(ctx) {
139
143
  entries,
140
144
  agentPresets: (await presets.compositionInventory()).map((composition) => ({
141
145
  ...composition,
142
- rows: composition.rows.map(({ fiberState, ...row }) => ({
143
- ...row,
144
- fiberPhase: fiberState === void 0 ? null : FIBER_PHASE[fiberState]
145
- }))
146
+ rows: composition.rows.map(({ fiberState, ...row }) => {
147
+ const meta = ctx.baseUrl === void 0 ? void 0 : packages?.metaOf(row.moduleName, ctx.baseUrl);
148
+ return {
149
+ ...row,
150
+ fiberPhase: fiberState === void 0 ? null : FIBER_PHASE[fiberState],
151
+ ...meta === void 0 ? {} : { meta }
152
+ };
153
+ })
146
154
  })),
147
155
  ...management
148
156
  };
@@ -7,21 +7,40 @@ const _deepseek_ai_dsh_host_plugin_inventory_pluginInventory_list_result$schema
7
7
  'entries': z.array(z.object({
8
8
  'entryId': z.intersection(z.string(), z.unknown()).readonly(),
9
9
  'moduleName': z.string().readonly(),
10
+ 'meta': z.object({
11
+ 'title': z.union([z.string(), z.intersection(z.object({
12
+ 'en': z.string().readonly(),
13
+ }), z.record(z.string(), z.string()).readonly())]).readonly().optional(),
14
+ 'description': z.union([z.string(), z.intersection(z.object({
15
+ 'en': z.string().readonly(),
16
+ }), z.record(z.string(), z.string()).readonly())]).readonly().optional(),
17
+ 'icon': z.string().readonly().optional(),
18
+ 'error': z.string().readonly().optional(),
19
+ }).readonly().optional(),
10
20
  'enabled': z.boolean().readonly(),
11
- 'fiberPhase': z.union([z.literal(null), z.literal("pending"), z.literal("active"), z.literal("failed"), z.literal("loading"), z.literal("unloading")]).readonly(),
21
+ 'fiberPhase': z.union([z.literal(null), z.literal("failed"), z.literal("pending"), z.literal("active"), z.literal("loading"), z.literal("unloading")]).readonly(),
12
22
  })).readonly(),
13
23
  'agentPresets': z.array(z.object({
14
24
  'id': z.string().readonly(),
15
- 'trust': z.union([z.literal("system"), z.literal("user")]).readonly(),
16
25
  'name': z.string().readonly().optional(),
17
26
  'isDefault': z.boolean().readonly(),
18
27
  'broken': z.string().readonly().optional(),
19
28
  'rows': z.array(z.object({
20
29
  'entryId': z.union([z.literal(null), z.string()]).readonly(),
21
30
  'moduleName': z.string().readonly(),
31
+ 'meta': z.object({
32
+ 'title': z.union([z.string(), z.intersection(z.object({
33
+ 'en': z.string().readonly(),
34
+ }), z.record(z.string(), z.string()).readonly())]).readonly().optional(),
35
+ 'description': z.union([z.string(), z.intersection(z.object({
36
+ 'en': z.string().readonly(),
37
+ }), z.record(z.string(), z.string()).readonly())]).readonly().optional(),
38
+ 'icon': z.string().readonly().optional(),
39
+ 'error': z.string().readonly().optional(),
40
+ }).readonly().optional(),
22
41
  'enabled': z.union([z.literal(false), z.literal(true), z.literal("conditional")]).readonly(),
23
42
  'condition': z.string().readonly().optional(),
24
- 'fiberPhase': z.union([z.literal(null), z.literal("pending"), z.literal("active"), z.literal("failed"), z.literal("loading"), z.literal("unloading")]).readonly(),
43
+ 'fiberPhase': z.union([z.literal(null), z.literal("failed"), z.literal("pending"), z.literal("active"), z.literal("loading"), z.literal("unloading")]).readonly(),
25
44
  })).readonly(),
26
45
  })).readonly().optional(),
27
46
  }))
@@ -45,7 +64,7 @@ export const TYPERT = {
45
64
  typeSymbol: '@deepseek-ai/dsh-host-plugin-inventory/types#PluginInventorySnapshot',
46
65
  create: _deepseek_ai_dsh_host_plugin_inventory_pluginInventory_list_result$schema,
47
66
  },
48
- sourceLocation: {"file":"packages/host/plugin-inventory/src/index.ts","line":70,"column":9},
67
+ sourceLocation: {"file":"packages/host/plugin-inventory/src/index.ts","line":71,"column":9},
49
68
  },
50
69
  ],
51
70
  model: {
@@ -7,21 +7,40 @@ const _deepseek_ai_dsh_host_plugin_inventory_pluginInventory_list_result$schema
7
7
  'entries': z.array(z.object({
8
8
  'entryId': z.intersection(z.string(), z.unknown()).readonly(),
9
9
  'moduleName': z.string().readonly(),
10
+ 'meta': z.object({
11
+ 'title': z.union([z.string(), z.intersection(z.object({
12
+ 'en': z.string().readonly(),
13
+ }), z.record(z.string(), z.string()).readonly())]).readonly().optional(),
14
+ 'description': z.union([z.string(), z.intersection(z.object({
15
+ 'en': z.string().readonly(),
16
+ }), z.record(z.string(), z.string()).readonly())]).readonly().optional(),
17
+ 'icon': z.string().readonly().optional(),
18
+ 'error': z.string().readonly().optional(),
19
+ }).readonly().optional(),
10
20
  'enabled': z.boolean().readonly(),
11
- 'fiberPhase': z.union([z.literal(null), z.literal("pending"), z.literal("active"), z.literal("failed"), z.literal("loading"), z.literal("unloading")]).readonly(),
21
+ 'fiberPhase': z.union([z.literal(null), z.literal("failed"), z.literal("pending"), z.literal("active"), z.literal("loading"), z.literal("unloading")]).readonly(),
12
22
  })).readonly(),
13
23
  'agentPresets': z.array(z.object({
14
24
  'id': z.string().readonly(),
15
- 'trust': z.union([z.literal("system"), z.literal("user")]).readonly(),
16
25
  'name': z.string().readonly().optional(),
17
26
  'isDefault': z.boolean().readonly(),
18
27
  'broken': z.string().readonly().optional(),
19
28
  'rows': z.array(z.object({
20
29
  'entryId': z.union([z.literal(null), z.string()]).readonly(),
21
30
  'moduleName': z.string().readonly(),
31
+ 'meta': z.object({
32
+ 'title': z.union([z.string(), z.intersection(z.object({
33
+ 'en': z.string().readonly(),
34
+ }), z.record(z.string(), z.string()).readonly())]).readonly().optional(),
35
+ 'description': z.union([z.string(), z.intersection(z.object({
36
+ 'en': z.string().readonly(),
37
+ }), z.record(z.string(), z.string()).readonly())]).readonly().optional(),
38
+ 'icon': z.string().readonly().optional(),
39
+ 'error': z.string().readonly().optional(),
40
+ }).readonly().optional(),
22
41
  'enabled': z.union([z.literal(false), z.literal(true), z.literal("conditional")]).readonly(),
23
42
  'condition': z.string().readonly().optional(),
24
- 'fiberPhase': z.union([z.literal(null), z.literal("pending"), z.literal("active"), z.literal("failed"), z.literal("loading"), z.literal("unloading")]).readonly(),
43
+ 'fiberPhase': z.union([z.literal(null), z.literal("failed"), z.literal("pending"), z.literal("active"), z.literal("loading"), z.literal("unloading")]).readonly(),
25
44
  })).readonly(),
26
45
  })).readonly().optional(),
27
46
  }))
@@ -42,7 +61,7 @@ export const TYPERT_REMOTE = {
42
61
  typeSymbol: '@deepseek-ai/dsh-host-plugin-inventory/types#PluginInventorySnapshot',
43
62
  create: _deepseek_ai_dsh_host_plugin_inventory_pluginInventory_list_result$schema,
44
63
  },
45
- sourceLocation: {"file":"packages/host/plugin-inventory/src/index.ts","line":70,"column":9},
64
+ sourceLocation: {"file":"packages/host/plugin-inventory/src/index.ts","line":71,"column":9},
46
65
  },
47
66
  ],
48
67
  }
@@ -22,15 +22,15 @@ export declare class PluginInventoryGateway extends TypertRemoteService {
22
22
  * preset's composition rows, because those rows — not the Loader's own
23
23
  * entries — are where a deployment that mounts the roster runs its
24
24
  * model-facing plugins.
25
- * @returns Current non-group Loader entries in Loader order, with per-preset
26
- * compositions when a roster is composed.
25
+ * @returns Current non-group Loader entries in Loader order, with optional display metadata
26
+ * and per-preset compositions when a roster is composed.
27
27
  */
28
28
  list(): Promise<PluginInventorySnapshot>;
29
29
  }
30
30
  export default PluginInventoryGateway;
31
31
  /** Read current Loader entries and optional preset compositions.
32
32
  * @param ctx Context with the Loader service.
33
- * @returns Current inventory without a separate runtime cache.
33
+ * @returns Current inventory with optional display metadata and no separate runtime cache.
34
34
  */
35
35
  export declare function readPluginInventory(ctx: Context): Promise<PluginInventorySnapshot>;
36
36
  //# sourceMappingURL=index.d.ts.map
@@ -86,8 +86,8 @@ let PluginInventoryGateway = (() => {
86
86
  * preset's composition rows, because those rows — not the Loader's own
87
87
  * entries — are where a deployment that mounts the roster runs its
88
88
  * model-facing plugins.
89
- * @returns Current non-group Loader entries in Loader order, with per-preset
90
- * compositions when a roster is composed.
89
+ * @returns Current non-group Loader entries in Loader order, with optional display metadata
90
+ * and per-preset compositions when a roster is composed.
91
91
  */
92
92
  async list() {
93
93
  return readPluginInventory(this.ctx);
@@ -98,18 +98,22 @@ export { PluginInventoryGateway };
98
98
  export default PluginInventoryGateway;
99
99
  /** Read current Loader entries and optional preset compositions.
100
100
  * @param ctx Context with the Loader service.
101
- * @returns Current inventory without a separate runtime cache.
101
+ * @returns Current inventory with optional display metadata and no separate runtime cache.
102
102
  */
103
103
  export async function readPluginInventory(ctx) {
104
104
  const entries = [];
105
+ const packages = ctx.get('pluginPackages');
105
106
  for (const entry of ctx.loader.entries()) {
106
107
  if (entry.options.group)
107
108
  continue;
109
+ const base = entry.parent.tree.ctx.baseUrl;
110
+ const meta = base === undefined ? undefined : packages?.metaOf(entry.options.name, base);
108
111
  entries.push({
109
112
  entryId: pluginEntryId(entry.id),
110
113
  moduleName: entry.options.name,
111
114
  enabled: !entry.disabled,
112
115
  fiberPhase: entry.fiber === undefined ? null : FIBER_PHASE[entry.fiber.state],
116
+ ...meta === undefined ? {} : { meta },
113
117
  });
114
118
  }
115
119
  const presets = ctx.get('agentPresets');
@@ -118,10 +122,14 @@ export async function readPluginInventory(ctx) {
118
122
  return { entries, ...management };
119
123
  const agentPresets = (await presets.compositionInventory()).map(composition => ({
120
124
  ...composition,
121
- rows: composition.rows.map(({ fiberState, ...row }) => ({
122
- ...row,
123
- fiberPhase: fiberState === undefined ? null : FIBER_PHASE[fiberState],
124
- })),
125
+ rows: composition.rows.map(({ fiberState, ...row }) => {
126
+ const meta = ctx.baseUrl === undefined ? undefined : packages?.metaOf(row.moduleName, ctx.baseUrl);
127
+ return {
128
+ ...row,
129
+ fiberPhase: fiberState === undefined ? null : FIBER_PHASE[fiberState],
130
+ ...meta === undefined ? {} : { meta },
131
+ };
132
+ }),
125
133
  }));
126
134
  return { entries, agentPresets, ...management };
127
135
  }
@@ -1,4 +1,5 @@
1
1
  import type { Branded } from '@deepseek-ai/dsh-brand';
2
+ import type { PluginLocalizedMeta } from '@deepseek-ai/dsh-package-manifest';
2
3
  /** Stable Loader-tree identity of one configured plugin entry. */
3
4
  export type PluginEntryId = Branded<'PluginEntryId'>;
4
5
  /** Lifecycle state of an entry's root Fiber, or null when it has no live root Fiber. */
@@ -8,6 +9,8 @@ export interface PluginInventoryEntry {
8
9
  readonly entryId: PluginEntryId;
9
10
  /** Exact module specifier imported by the Loader entry. */
10
11
  readonly moduleName: string;
12
+ /** Local package display metadata, independent of whether the entry is enabled. */
13
+ readonly meta?: PluginLocalizedMeta;
11
14
  /** Effective Loader enablement, including disabled ancestor groups. */
12
15
  readonly enabled: boolean;
13
16
  readonly fiberPhase: PluginFiberPhase;
@@ -20,6 +23,8 @@ export interface AgentPresetPluginRow {
20
23
  readonly entryId: string | null;
21
24
  /** Module specifier the row names. */
22
25
  readonly moduleName: string;
26
+ /** Local package display metadata, independent of whether the preset is mounted. */
27
+ readonly meta?: PluginLocalizedMeta;
23
28
  /**
24
29
  * Effective enablement, including disabled ancestor groups. `'conditional'`
25
30
  * marks a `!!js` disabled expression on a composition no session has
@@ -35,8 +40,6 @@ export interface AgentPresetPluginRow {
35
40
  export interface AgentPresetPluginGroup {
36
41
  /** Stable preset id. */
37
42
  readonly id: string;
38
- /** Whether the deployment ships the preset or the user owns it. */
39
- readonly trust: 'system' | 'user';
40
43
  /** Display name the preset published; a reader falls back to the id. */
41
44
  readonly name?: string;
42
45
  /** Whether a session naming no preset composes this one. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-host-plugin-inventory",
3
3
  "description": "Read-only Remote projection of current Cordis Loader plugin state",
4
- "version": "0.1.6-alpha.2",
4
+ "version": "0.1.7-alpha.1",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -47,22 +47,24 @@
47
47
  "zod": "^4.4.3"
48
48
  },
49
49
  "peerDependencies": {
50
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
51
- "@deepseek-ai/dsh-agent-presets": "^0.1.6-alpha.2",
52
- "@deepseek-ai/dsh-brand": "^0.1.6-alpha.2",
53
- "@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2",
54
- "@deepseek-ai/cordis": "^4.0.2"
50
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
51
+ "@deepseek-ai/dsh-agent-preset-registry": "^0.1.7-alpha.1",
52
+ "@deepseek-ai/dsh-brand": "^0.1.7-alpha.1",
53
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.7-alpha.1",
54
+ "@deepseek-ai/cordis": "^4.0.3"
55
55
  },
56
56
  "peerDependenciesMeta": {
57
- "@deepseek-ai/dsh-agent-presets": {
57
+ "@deepseek-ai/dsh-agent-preset-registry": {
58
58
  "optional": true
59
59
  }
60
60
  },
61
61
  "devDependencies": {
62
- "@deepseek-ai/cordis-plugin-loader": "^1.0.3",
63
- "@deepseek-ai/dsh-agent-presets": "^0.1.6-alpha.2",
64
- "@deepseek-ai/dsh-brand": "^0.1.6-alpha.2",
65
- "@deepseek-ai/cordis": "^4.0.2",
66
- "@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2"
62
+ "@deepseek-ai/dsh-app-boot": "^0.1.7-alpha.1",
63
+ "@deepseek-ai/dsh-package-manifest": "^0.1.7-alpha.1",
64
+ "@deepseek-ai/cordis-plugin-loader": "^1.0.4",
65
+ "@deepseek-ai/dsh-agent-preset-registry": "^0.1.7-alpha.1",
66
+ "@deepseek-ai/dsh-brand": "^0.1.7-alpha.1",
67
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.7-alpha.1",
68
+ "@deepseek-ai/cordis": "^4.0.3"
67
69
  }
68
70
  }