@deepseek-ai/dsh-client-ui-settings-plugin-inventory 0.1.6-alpha.1 → 0.1.6-alpha.2
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 +2 -2
- package/README.md +6 -2
- package/README.zh.md +6 -2
- package/lib/client.js +52 -10
- package/lib/types/client/PluginInventorySettingsTab.d.ts +9 -1
- package/lib/types/client/locales.d.ts +6 -0
- package/package.json +14 -11
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/client/ui-settings-plugin-inventory/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 9b41c7490055dcf9865958a4e243b115fdbd40b8
|
|
6
|
+
README.zh.md: dd4b1ebcd68a48573c42864eb796c58b49f9b834
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
|
|
9
9
|
|
|
10
10
|
## Summary
|
|
11
11
|
|
|
12
|
-
The **Plugin list** tab lets Web users inspect plugins without changing their configuration. It
|
|
12
|
+
The **Plugin list** tab lets Web users inspect plugins without changing their configuration. It lists agent presets, then the global inventory; both start collapsed and open on demand or during a search. Cards retain the package name as the primary title, identify instances by stable entry id, and expose enablement, source details, runtime status, disabled conditions, and discovery failures; preset-provided global entries name their presets. Search covers both groups and points to matches in other presets. The tab handles loading, empty, no-match, failure, and retry states without exposing transport details, and still shows the global inventory without a preset roster.
|
|
13
13
|
|
|
14
14
|
## Table of Contents
|
|
15
15
|
|
|
@@ -27,9 +27,11 @@ The **Plugin list** tab lets Web users inspect plugins without changing their co
|
|
|
27
27
|
|
|
28
28
|
Open the Plugins section in Settings and select the **Plugin list** tab to inspect the Host's plugin inventory. The tab reads no Remote during plugin activation — selecting it for the first time mounts the component and lazily calls `ctx.remote.pluginInventory.list()` through `api-remotes`.
|
|
29
29
|
|
|
30
|
+
A failed installation with pending pnpm build permissions offers **Allow these scripts and retry**. The action displays the exact package names and persistent permission scope, then retries the original package spec and activation choice. One click approves the entire displayed group, which can include pending packages from earlier attempts. Closing the page grants no permission.
|
|
31
|
+
|
|
30
32
|
### Reading a card
|
|
31
33
|
|
|
32
|
-
Each collapsed card uses the short module name as its primary title, shows the stable entry id underneath, and carries a small enablement tag;
|
|
34
|
+
Each collapsed card uses the short module name as its primary title, shows the stable entry id underneath, and carries a small enablement tag; a colored root-fiber status dot marks only the `pending`, `loading`, and `unloading` phases the tag cannot state, so an `active` fiber shows its tag alone. A composition-generated subtitle omits its leading `include:` marker, while hover, search, the accessible name, and expanded details retain the complete id. Long entry ids truncate in the row and remain available on hover. Expanding one card reveals the declared entry id, the full module specifier, and the state facts: a preset row names the preset it comes from, its runtime status when the composition is live, and its disable condition when it carries one; a preset-provided global row explains that agent presets provide it per session, names the presets that enable it, and offers a jump into the preset group. Preset names resolve through the shared `presetDisplayText` fold (`dsh-agent-presets/display`) over [`ui-agent-preset`](../ui-agent-preset/README.md)'s dictionaries: shipped presets follow the active locale while user-authored ones keep their own metadata, so an English surface never echoes the preset files' Chinese names. Search filters both groups by module name and entry id.
|
|
33
35
|
|
|
34
36
|
### The preset switcher
|
|
35
37
|
|
|
@@ -39,6 +41,8 @@ The switcher is the same selector-pill-plus-menu control the General settings ro
|
|
|
39
41
|
|
|
40
42
|
A failed read renders a generic failure state inside the tab; retrying re-runs the lazy `list()` call without exposing transport details.
|
|
41
43
|
|
|
44
|
+
The Plugin list also shows synchronization failures on the current page. Its retry reapplies the latest client graph without changing Host enablement or refreshing the page.
|
|
45
|
+
|
|
42
46
|
-----
|
|
43
47
|
|
|
44
48
|
<a id="understand-the-implementation"></a>
|
package/README.zh.md
CHANGED
|
@@ -9,7 +9,7 @@ kind: "package-reference"
|
|
|
9
9
|
|
|
10
10
|
## 概述
|
|
11
11
|
|
|
12
|
-
**插件列表**标签页让 Web
|
|
12
|
+
**插件列表**标签页让 Web 用户查看插件,而不改变其配置。它先列 agent(智能体)预设分组,再列全局清单;两个分组默认都收起,按需展开,搜索期间保持展开。卡片保留包名作为主标题,以稳定的条目 id 标识实例,并展示启停状态、出处、运行状态、禁用条件与发现失败;由预设提供的全局条目会列出对应预设。搜索覆盖两个分组,并指出其他预设中的匹配。标签页处理加载、空结果、无匹配、失败与重试状态,且不暴露传输细节;没有预设 roster 时仍会展示全局清单。
|
|
13
13
|
|
|
14
14
|
## 目录
|
|
15
15
|
|
|
@@ -27,9 +27,11 @@ kind: "package-reference"
|
|
|
27
27
|
|
|
28
28
|
打开设置中的「插件」分区并选择**插件列表**标签页,即可查看宿主的插件清单。插件激活期间不会读取 Remote——首次选择该标签页时才挂载组件,并通过 `api-remotes` 懒调用 `ctx.remote.pluginInventory.list()`。
|
|
29
29
|
|
|
30
|
+
安装失败且存在待审批的 pnpm 构建权限时,页面提供“允许这些脚本并重试”。该操作展示准确包名和持久授权范围,再使用原来的包规格及启用选项重试。一次点击批准整个列表,其中可能包括此前安装留下的待审批包。关闭页面不会授予权限。
|
|
31
|
+
|
|
30
32
|
### 阅读卡片
|
|
31
33
|
|
|
32
|
-
每张收起的卡片使用模块短名称作为主标题,在下方显示稳定的条目 id
|
|
34
|
+
每张收起的卡片使用模块短名称作为主标题,在下方显示稳定的条目 id,并以小标签表示启停状态;彩色根 fiber 状态圆点只标记标签无法表达的 `pending`、`loading`、`unloading` 阶段,`active` 的条目只显示标签。组合生成的次标题省略开头的 `include:` 标记;悬停、搜索、无障碍名称与展开详情仍保留完整 id。长条目 id 会在行内截断,悬停时仍可查看完整值。展开卡片后会显示声明的条目 id、完整模块标识与状态事实:预设行说明它来自哪个预设、组合存活时的运行状态,以及它携带的禁用条件;被预设提供的全局行说明它由 Agent 预设按会话提供、列出启用它的预设,并提供跳转到预设组的入口。预设名经共享的 `presetDisplayText` 纯函数(`dsh-agent-presets/display`)叠在 [`ui-agent-preset`](../ui-agent-preset/README.zh.md) 的字典上解析:内置预设走当前语言,用户自建预设保留自己的元数据,因此英文界面不会回显预设文件里的中文名。搜索按模块名称与条目 id 过滤两组。
|
|
33
35
|
|
|
34
36
|
### 预设切换器
|
|
35
37
|
|
|
@@ -39,6 +41,8 @@ kind: "package-reference"
|
|
|
39
41
|
|
|
40
42
|
读取失败会在标签页内渲染通用失败状态;重试会重新执行懒 `list()` 调用,且不会暴露传输细节。
|
|
41
43
|
|
|
44
|
+
插件列表还显示当前页面的同步失败。重试会重新应用最新客户端图,不改变 Host 启用状态,也不刷新页面。
|
|
45
|
+
|
|
42
46
|
-----
|
|
43
47
|
|
|
44
48
|
<a id="understand-the-implementation"></a>
|
package/lib/client.js
CHANGED
|
@@ -185,11 +185,13 @@ window.__ModuleLoader__.load({
|
|
|
185
185
|
const PHASE_DOT_STATES = {
|
|
186
186
|
pending: "idle",
|
|
187
187
|
loading: "ongoing",
|
|
188
|
-
active: "done",
|
|
189
|
-
failed: "error",
|
|
190
188
|
unloading: "ongoing"
|
|
191
189
|
};
|
|
192
|
-
/**
|
|
190
|
+
/** Whether a live root-fiber phase carries a dot of its own. */
|
|
191
|
+
function showsPhaseDot(phase) {
|
|
192
|
+
return phase === "pending" || phase === "loading" || phase === "unloading";
|
|
193
|
+
}
|
|
194
|
+
/** Status dot naming a live root-fiber phase; rows without a dotted phase show none. */
|
|
193
195
|
function PhaseDot({ phase, t }) {
|
|
194
196
|
const status = phaseLabel(phase, t);
|
|
195
197
|
return (0, react_jsx_runtime.jsx)("span", {
|
|
@@ -215,7 +217,8 @@ window.__ModuleLoader__.load({
|
|
|
215
217
|
});
|
|
216
218
|
}
|
|
217
219
|
/** Render the read-only plugin inventory: agent presets first, then the global plane. */
|
|
218
|
-
function PluginInventorySettingsTab({ list, presetName, t }) {
|
|
220
|
+
function PluginInventorySettingsTab({ list, presetName, t, useClientSync, retryClient }) {
|
|
221
|
+
const clientSync = useClientSync((snapshot) => snapshot);
|
|
219
222
|
const sectionId = (0, react.useId)();
|
|
220
223
|
const [request, setRequest] = (0, react.useState)(0);
|
|
221
224
|
const [query, setQuery] = (0, react.useState)("");
|
|
@@ -268,8 +271,8 @@ window.__ModuleLoader__.load({
|
|
|
268
271
|
const selectedRows = selected === void 0 ? [] : selected.rows.filter(rowMatch);
|
|
269
272
|
const otherPresetMatches = searching ? presets.filter((preset) => preset !== selected && preset.rows.some(rowMatch)) : [];
|
|
270
273
|
const otherMatchCount = otherPresetMatches.reduce((total, preset) => total + preset.rows.filter(rowMatch).length, 0);
|
|
271
|
-
const presetEffectiveOpen = searching || (presetOpen ??
|
|
272
|
-
const globalEffectiveOpen = searching || (globalOpen ??
|
|
274
|
+
const presetEffectiveOpen = searching || (presetOpen ?? false);
|
|
275
|
+
const globalEffectiveOpen = searching || (globalOpen ?? false);
|
|
273
276
|
const nothingMatches = searching && globalCount === 0 && selectedRows.length === 0 && otherPresetMatches.length === 0;
|
|
274
277
|
const retry = () => {
|
|
275
278
|
setState({ status: "loading" });
|
|
@@ -293,7 +296,7 @@ window.__ModuleLoader__.load({
|
|
|
293
296
|
expanded,
|
|
294
297
|
onToggle: toggleRow,
|
|
295
298
|
ariaLabel: `${title}${row.entryId === null ? "" : `, ${row.entryId}`}, ${stateText}`,
|
|
296
|
-
trailing: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [row.enabled === true &&
|
|
299
|
+
trailing: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [row.enabled === true && showsPhaseDot(row.fiberPhase) ? (0, react_jsx_runtime.jsx)(PhaseDot, {
|
|
297
300
|
phase: row.fiberPhase,
|
|
298
301
|
t
|
|
299
302
|
}) : null, (0, react_jsx_runtime.jsx)(StateTag, {
|
|
@@ -328,7 +331,7 @@ window.__ModuleLoader__.load({
|
|
|
328
331
|
expanded,
|
|
329
332
|
onToggle: toggleRow,
|
|
330
333
|
ariaLabel: `${title}, ${entry.entryId}, ${stateText}`,
|
|
331
|
-
trailing: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [entry.enabled &&
|
|
334
|
+
trailing: (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [entry.enabled && showsPhaseDot(entry.fiberPhase) ? (0, react_jsx_runtime.jsx)(PhaseDot, {
|
|
332
335
|
phase: entry.fiberPhase,
|
|
333
336
|
t
|
|
334
337
|
}) : null, (0, react_jsx_runtime.jsx)(StateTag, {
|
|
@@ -357,6 +360,32 @@ window.__ModuleLoader__.load({
|
|
|
357
360
|
className: PluginInventorySettingsTab_module_css_default.section,
|
|
358
361
|
"aria-busy": state.status === "loading",
|
|
359
362
|
children: [
|
|
363
|
+
clientSync.syncing ? (0, react_jsx_runtime.jsx)("p", {
|
|
364
|
+
className: PluginInventorySettingsTab_module_css_default.status,
|
|
365
|
+
role: "status",
|
|
366
|
+
children: t("clientSyncing")
|
|
367
|
+
}) : null,
|
|
368
|
+
clientSync.failures.length === 0 ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
369
|
+
className: PluginInventorySettingsTab_module_css_default.failure,
|
|
370
|
+
"data-client-sync-failure": true,
|
|
371
|
+
children: [
|
|
372
|
+
(0, react_jsx_runtime.jsx)("p", {
|
|
373
|
+
role: "alert",
|
|
374
|
+
children: t("clientSyncFailed")
|
|
375
|
+
}),
|
|
376
|
+
(0, react_jsx_runtime.jsx)("ul", { children: clientSync.failures.map((failure) => (0, react_jsx_runtime.jsxs)("li", { children: [
|
|
377
|
+
failure.id,
|
|
378
|
+
": ",
|
|
379
|
+
failure.message
|
|
380
|
+
] }, failure.id)) }),
|
|
381
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
382
|
+
type: "button",
|
|
383
|
+
disabled: clientSync.syncing,
|
|
384
|
+
onClick: retryClient,
|
|
385
|
+
children: t("clientSyncRetry")
|
|
386
|
+
})
|
|
387
|
+
]
|
|
388
|
+
}),
|
|
360
389
|
state.status === "loading" ? (0, react_jsx_runtime.jsx)("p", {
|
|
361
390
|
className: PluginInventorySettingsTab_module_css_default.status,
|
|
362
391
|
children: t("loading")
|
|
@@ -559,6 +588,9 @@ window.__ModuleLoader__.load({
|
|
|
559
588
|
const zh = {
|
|
560
589
|
tab: "插件列表",
|
|
561
590
|
loading: "正在读取插件…",
|
|
591
|
+
clientSyncing: "正在同步本页面的插件…",
|
|
592
|
+
clientSyncFailed: "本页面的插件未能完成同步;服务端的启用状态保持不变。",
|
|
593
|
+
clientSyncRetry: "重试本页面同步",
|
|
562
594
|
error: "暂时无法读取插件。",
|
|
563
595
|
retry: "重试",
|
|
564
596
|
search: "搜索插件",
|
|
@@ -598,6 +630,9 @@ window.__ModuleLoader__.load({
|
|
|
598
630
|
const en = {
|
|
599
631
|
tab: "Plugin list",
|
|
600
632
|
loading: "Reading plugins…",
|
|
633
|
+
clientSyncing: "Syncing plugins on this page…",
|
|
634
|
+
clientSyncFailed: "Some plugins could not sync on this page. Host enablement is unchanged.",
|
|
635
|
+
clientSyncRetry: "Retry this page",
|
|
601
636
|
error: "Plugins are temporarily unavailable.",
|
|
602
637
|
retry: "Retry",
|
|
603
638
|
search: "Search plugins",
|
|
@@ -643,7 +678,8 @@ window.__ModuleLoader__.load({
|
|
|
643
678
|
"slots",
|
|
644
679
|
"locale",
|
|
645
680
|
"remote",
|
|
646
|
-
"remote.pluginInventory"
|
|
681
|
+
"remote.pluginInventory",
|
|
682
|
+
"modules"
|
|
647
683
|
];
|
|
648
684
|
/** Contribute the lazy inventory tab to the Plugins settings section. */
|
|
649
685
|
function apply(ctx) {
|
|
@@ -661,7 +697,13 @@ window.__ModuleLoader__.load({
|
|
|
661
697
|
const presetName = (preset) => presetDisplayText(preset, agentPresetCopy).name;
|
|
662
698
|
const injected = () => ({
|
|
663
699
|
list,
|
|
664
|
-
presetName
|
|
700
|
+
presetName,
|
|
701
|
+
hooks: { clientSync: ctx.modules.entries.state },
|
|
702
|
+
retryClient: () => {
|
|
703
|
+
ctx.modules.entries.retry().catch((error) => {
|
|
704
|
+
ctx.logger.error(error);
|
|
705
|
+
});
|
|
706
|
+
}
|
|
665
707
|
});
|
|
666
708
|
ctx.slots.inject("settings.plugins.tab", () => ctx.slots.register({
|
|
667
709
|
name: "settings.plugins.tab",
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
+
import type { ClientEntryState } from '@deepseek-ai/dsh-client-modules/client';
|
|
3
|
+
import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store';
|
|
2
4
|
import type { PluginInventorySnapshot } from '@deepseek-ai/dsh-api-remotes/client';
|
|
3
5
|
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
6
|
type AgentPresetGroup = NonNullable<PluginInventorySnapshot['agentPresets']>[number];
|
|
5
7
|
/** Registration-side Remote face used by the section. */
|
|
6
8
|
export interface PluginInventorySettingsTabInjected {
|
|
9
|
+
/** Page-local module synchronization, independent from the Host inventory. */
|
|
10
|
+
hooks: {
|
|
11
|
+
clientSync: ObservableSnapshot<ClientEntryState>;
|
|
12
|
+
};
|
|
13
|
+
/** Retry the latest client graph without changing the Host composition. */
|
|
14
|
+
retryClient: () => void;
|
|
7
15
|
/** Read a current Host inventory snapshot. */
|
|
8
16
|
list: () => Promise<PluginInventorySnapshot>;
|
|
9
17
|
/**
|
|
@@ -15,6 +23,6 @@ export interface PluginInventorySettingsTabInjected {
|
|
|
15
23
|
/** Full component props assembled by the Settings slot renderer. */
|
|
16
24
|
export type PluginInventorySettingsTabProps = PropsRuntime<'settings.plugins.tab'> & PropsLocale<'settings.pluginInventory'> & InjectFace<PluginInventorySettingsTabInjected>;
|
|
17
25
|
/** Render the read-only plugin inventory: agent presets first, then the global plane. */
|
|
18
|
-
export declare function PluginInventorySettingsTab({ list, presetName, t }: PluginInventorySettingsTabProps): ReactNode;
|
|
26
|
+
export declare function PluginInventorySettingsTab({ list, presetName, t, useClientSync, retryClient }: PluginInventorySettingsTabProps): ReactNode;
|
|
19
27
|
export {};
|
|
20
28
|
//# sourceMappingURL=PluginInventorySettingsTab.d.ts.map
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
export declare const zh: {
|
|
4
4
|
tab: string;
|
|
5
5
|
loading: string;
|
|
6
|
+
clientSyncing: string;
|
|
7
|
+
clientSyncFailed: string;
|
|
8
|
+
clientSyncRetry: string;
|
|
6
9
|
error: string;
|
|
7
10
|
retry: string;
|
|
8
11
|
search: string;
|
|
@@ -44,6 +47,9 @@ export type PluginInventoryLocaleKey = keyof typeof zh;
|
|
|
44
47
|
export declare const en: {
|
|
45
48
|
tab: string;
|
|
46
49
|
loading: string;
|
|
50
|
+
clientSyncing: string;
|
|
51
|
+
clientSyncFailed: string;
|
|
52
|
+
clientSyncRetry: string;
|
|
47
53
|
error: string;
|
|
48
54
|
retry: string;
|
|
49
55
|
search: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-settings-plugin-inventory",
|
|
3
3
|
"description": "Read-only Cordis Loader inventory tab in Web Plugins settings",
|
|
4
|
-
"version": "0.1.6-alpha.
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"@deepseek-ai/dsh-api-remotes",
|
|
32
32
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
33
33
|
"@deepseek-ai/dsh-client-locale",
|
|
34
|
-
"@deepseek-ai/dsh-client-ui-agent-preset"
|
|
34
|
+
"@deepseek-ai/dsh-client-ui-agent-preset",
|
|
35
|
+
"@deepseek-ai/dsh-client-modules"
|
|
35
36
|
],
|
|
36
37
|
"platform": "web"
|
|
37
38
|
}
|
|
@@ -45,16 +46,18 @@
|
|
|
45
46
|
"@types/react": "~18.3.1",
|
|
46
47
|
"react": "^18.2.0",
|
|
47
48
|
"react-dom": "^18.2.0",
|
|
48
|
-
"@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.
|
|
49
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.
|
|
50
|
-
"@deepseek-ai/dsh-client-ui-agent-preset": "^0.1.6-alpha.
|
|
51
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.
|
|
52
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.6-alpha.
|
|
53
|
-
"@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.
|
|
54
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.1",
|
|
49
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.2",
|
|
50
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.2",
|
|
51
|
+
"@deepseek-ai/dsh-client-ui-agent-preset": "^0.1.6-alpha.2",
|
|
52
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.6-alpha.2",
|
|
54
|
+
"@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.2",
|
|
55
55
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
56
|
-
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.
|
|
57
|
-
"@deepseek-ai/dsh-agent-presets": "^0.1.6-alpha.
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.2",
|
|
57
|
+
"@deepseek-ai/dsh-agent-presets": "^0.1.6-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-client-store": "^0.1.6-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-modules": "^0.1.6-alpha.2"
|
|
58
61
|
},
|
|
59
62
|
"files": [
|
|
60
63
|
"lib/index.js",
|