dsh-plugin-manager-companion 0.1.0

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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +144 -0
  3. package/README.md +142 -0
  4. package/cordis.patch.yml +9 -0
  5. package/dist/about.d.ts +77 -0
  6. package/dist/about.js +179 -0
  7. package/dist/cli.d.ts +226 -0
  8. package/dist/cli.js +856 -0
  9. package/dist/client/AboutPage.d.ts +75 -0
  10. package/dist/client/ConsolePage.d.ts +79 -0
  11. package/dist/client/KindsPage.d.ts +21 -0
  12. package/dist/client/MarketplacePage.d.ts +36 -0
  13. package/dist/client/OfficialSlots.d.ts +35 -0
  14. package/dist/client/UpgradeRow.d.ts +108 -0
  15. package/dist/client/index.d.ts +26 -0
  16. package/dist/client/locales.d.ts +475 -0
  17. package/dist/client/pmSelect.d.ts +38 -0
  18. package/dist/client/shared.d.ts +928 -0
  19. package/dist/client/upgradeView.d.ts +278 -0
  20. package/dist/client/wire.d.ts +401 -0
  21. package/dist/client.js +9194 -0
  22. package/dist/diagnostics.d.ts +332 -0
  23. package/dist/diagnostics.js +2631 -0
  24. package/dist/envManager.d.ts +1047 -0
  25. package/dist/envManager.js +3214 -0
  26. package/dist/fix.d.ts +60 -0
  27. package/dist/fix.js +168 -0
  28. package/dist/guard.d.ts +133 -0
  29. package/dist/guard.js +232 -0
  30. package/dist/index.d.ts +121 -0
  31. package/dist/index.js +1150 -0
  32. package/dist/installSession.d.ts +111 -0
  33. package/dist/installSession.js +150 -0
  34. package/dist/kinds.d.ts +464 -0
  35. package/dist/kinds.js +1029 -0
  36. package/dist/marketView.d.ts +261 -0
  37. package/dist/marketView.js +406 -0
  38. package/dist/marketplace.d.ts +248 -0
  39. package/dist/marketplace.js +500 -0
  40. package/dist/match.d.ts +67 -0
  41. package/dist/match.js +203 -0
  42. package/dist/net.d.ts +108 -0
  43. package/dist/net.js +163 -0
  44. package/dist/official.d.ts +145 -0
  45. package/dist/official.js +205 -0
  46. package/dist/paths.d.ts +108 -0
  47. package/dist/paths.js +236 -0
  48. package/dist/presets.d.ts +299 -0
  49. package/dist/presets.js +578 -0
  50. package/dist/qualityGate.d.ts +66 -0
  51. package/dist/qualityGate.js +247 -0
  52. package/dist/rank.d.ts +88 -0
  53. package/dist/rank.js +164 -0
  54. package/dist/registry.d.ts +295 -0
  55. package/dist/registry.js +686 -0
  56. package/dist/rest.d.ts +122 -0
  57. package/dist/rest.js +219 -0
  58. package/dist/scan.d.ts +134 -0
  59. package/dist/scan.js +396 -0
  60. package/dist/settings.d.ts +447 -0
  61. package/dist/settings.js +263 -0
  62. package/dist/tags.d.ts +119 -0
  63. package/dist/tags.js +166 -0
  64. package/dist/tools.d.ts +131 -0
  65. package/dist/tools.js +377 -0
  66. package/dist/types.d.ts +651 -0
  67. package/dist/types.js +13 -0
  68. package/dist/upgrade.d.ts +428 -0
  69. package/dist/upgrade.js +1100 -0
  70. package/dist/upgradeView.d.ts +313 -0
  71. package/dist/upgradeView.js +273 -0
  72. package/docs/images/readme/01-console-health.png +0 -0
  73. package/docs/images/readme/02-console-envs.png +0 -0
  74. package/docs/images/readme/03-marketplace.png +0 -0
  75. package/docs/images/readme/04-official-plugin-page.png +0 -0
  76. package/package.json +104 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * AboutPage — 「关于」一级入口:关于这套软件本身的事实面板(task-95)。
3
+ *
4
+ * 归属:A 类·新界面(补官方没有的信息面板)。
5
+ * 旧实现参考:无(旧 dsh-web-plugin-manager 没有信息面板)。
6
+ * 官方复用:@deepseek-ai/dsh-client-ui-primitives(Button/Tag);
7
+ * 事实来自自有 REST 的 `about` op(host 侧读,客户端只渲染)。
8
+ * 前提检查:这些事实**客户端一个都拿不到**(浏览器 bundle:无 process、无 node:fs),
9
+ * 所以必须由 host 读经 op 下发——调研见 docs/private/task76-recon.md。
10
+ *
11
+ * 子页机制**复用环境控制台那一套**(tablist + roving tabindex + 声明式 store 保存选中):
12
+ * 本任务只落「DSH 信息」一个子页,第二个子页(软件升级)由 task-77 挂上——
13
+ * 届时这里加一条数据即可,不新造机器。
14
+ *
15
+ * 硬约束(任务描述):不复述官方侧栏已有的构建标签;不显示 token 或完整启动命令行。
16
+ */
17
+ import { type HandleOf, type SnapshotStore } from '@deepseek-ai/dsh-client-store';
18
+ import type { ComposedProps, EntryKeyOf } from '@deepseek-ai/dsh-client-ui-slots';
19
+ import { NS } from './locales.ts';
20
+ import { type AboutState, type UpgradeFace, type UpgradeState } from './shared.ts';
21
+ /**
22
+ * 「关于」页的子页 store(与 createConsoleStore 同一理由与同一形状)。
23
+ *
24
+ * 为什么也放声明式 store:关于页只有一个子页时不明显,但 task-77 会挂上第二个
25
+ * (软件升级)——届时"切到软件升级、被一次 store 发布弹回 DSH 信息"就会重演
26
+ * 控制台踩过的那个缺陷(结果块被藏起来)。机制先建对,加子页只是一条数据。
27
+ *
28
+ * @returns 声明式 store。
29
+ */
30
+ export declare function createAboutStore(): import("@deepseek-ai/dsh-client-store").EngineStoreHandle<AboutStoreState, {
31
+ /**
32
+ * 选中一个子页并记进"已挂载"集合。
33
+ * @param draft - store 草稿。
34
+ * @param id - 子页 id。
35
+ */
36
+ select(draft: AboutStoreState, id: string): void;
37
+ }>;
38
+ /** 「关于」页 store 的状态形状。 */
39
+ export interface AboutStoreState {
40
+ activeId: string | undefined;
41
+ visitedIds: readonly string[];
42
+ }
43
+ /** 「关于」页 store 的句柄类型(句柄在 apply 里创建;模块级不放句柄)。 */
44
+ export type AboutStoreHandle = ReturnType<typeof createAboutStore>;
45
+ /**
46
+ * 「关于」页的注入面:关于页自己的面 + 升级面。
47
+ *
48
+ * 为什么写成一个显式接口(而不是 `AboutFace & UpgradeFace`):与
49
+ * {@link MarketplaceConsoleFace} 同一个坑——官方 `PropsHooks` 的映射类型在**交叉类型**上
50
+ * 推导不出 `useAbout` / `useUpgrade` 两个成员(实测编译报 "Property 'useAbout' is missing")。
51
+ * 一个显式的 hooks 记录把两件事说清楚,也省掉一处会被读错的类型体操。
52
+ */
53
+ export interface AboutConsoleFace {
54
+ hooks: {
55
+ about: SnapshotStore<AboutState>;
56
+ upgrade: SnapshotStore<UpgradeState>;
57
+ };
58
+ loadAbout(refresh: boolean): void;
59
+ ensureUpgrades(): void;
60
+ loadUpgrades(refresh: boolean): void;
61
+ upgradePackage(name: string, version: string, spec?: string): void;
62
+ rollbackPackage(name: string, version: string, spec?: string): void;
63
+ dismissUpgradeNotice(): void;
64
+ }
65
+ /** 软件升级子页要用的升级动作(与 UpgradeRow 的入参同形)。 */
66
+ export type AboutUpgradeActions = Pick<UpgradeFace, 'ensureUpgrades' | 'loadUpgrades' | 'upgradePackage' | 'rollbackPackage' | 'dismissUpgradeNotice'>;
67
+ /** 「关于」页的注册项 props(官方组合别名 + store 座位 + 本插件字典)。 */
68
+ export type AboutPageProps = ComposedProps<'settings.section', EntryKeyOf<'settings.section'>, never, HandleOf<AboutStoreHandle>, AboutConsoleFace, never, typeof NS>;
69
+ /**
70
+ * 渲染「关于」页。
71
+ *
72
+ * @param props - 字典座位、子页选择、事实与读动作。
73
+ * @returns 带本地子页面切换的关于页。
74
+ */
75
+ export declare function AboutPage({ t, useStore, actions, useAbout, loadAbout, useUpgrade, ...upgradeActions }: AboutPageProps): import("react").JSX.Element;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * ConsolePage — 环境控制台:一个设置入口内的三个本地子页面(体检 / 环境 / 设置)。
3
+ *
4
+ * 归属:A 类·重写(旧仓库把这三个能力拆在 PluginManagerSettingsTab /
5
+ * PluginEnvironmentsTab / PluginCatalogTab 里,且自带样式与散落文案)。
6
+ * 旧实现参考:dsh-web-plugin-manager/src/client/*Tab.tsx(只取交互意图:健康总览、
7
+ * 分环境卡片、分级修复;未复制代码)。
8
+ * 官方复用:子页机制沿用官方 ui-settings-plugins 的 PluginsSettingsSection 形态
9
+ * (role=tablist/tab/tabpanel + 方向键导航 + 首次选中才挂载、之后隐藏保留草稿),
10
+ * 但**选中状态放在 register 声明的 store 里**而不是组件内 useState:任何一次 store 发布或
11
+ * 条目重挂载都会让组件内状态复位回「体检」,而结果块就在「环境」子页里(实测缺陷,见
12
+ * createConsoleStore 的注释);全部控件来自 @deepseek-ai/dsh-client-ui-primitives;
13
+ * 配置读写走官方 ctx.settingsScope(经 ConfigController 注入)。
14
+ * 前提检查:旧实现的"官方没有管理页,所以自建"前提已消失——启停/安装/卸载交给
15
+ * 官方通道,本页只做官方不做的事:诊断报告、多环境管理、本插件配置。
16
+ */
17
+ import { type HandleOf } from '@deepseek-ai/dsh-client-store';
18
+ import type { ComposedProps, EntryKeyOf, SnapshotSelectorHook, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
19
+ import { NS } from './locales.ts';
20
+ import { type ConfigFace, type ConfigState, type ConsoleFace, type TrialFace, type TrialState } from './shared.ts';
21
+ /** 本文件里 t 的键域(本插件字典)。 */
22
+ type T = TranslateNS<typeof NS>;
23
+ type ConfigActions = Omit<ConfigFace, 'hooks'>;
24
+ type TrialActions = Omit<TrialFace, 'hooks'>;
25
+ /** 控制台里跨重挂载必须存活的状态。 */
26
+ export interface ConsoleStoreState {
27
+ /** 当前子页 id;undefined = 还没选过(首屏落在第一个子页)。 */
28
+ activeId: string | undefined;
29
+ /** 已经挂载过的子页:切回来时本地草稿、展开状态与已读报告都还在。 */
30
+ visitedIds: readonly string[];
31
+ }
32
+ /**
33
+ * 控制台的声明式 store(在 apply 里创建,经 register 的 store 座位交给框架)。
34
+ *
35
+ * 为什么必须是 store,而不是组件内 useState:控制台只有一个注册项,但它的渲染路径会被
36
+ * **任何一次 store 发布**穿过(体检在跑时每秒都在发布),组件内状态会当场复位到第一个子页。
37
+ * 后果很具体:用户在「环境」子页点操作、结果块就在那个子页里,页面却跳回「体检」——等于把
38
+ * 刚发生的结果藏起来。write-auditor 5 轮里撞到 2 轮(当时未定性),client-dev 真机复现两次,
39
+ * task-17 取证时连点 6 次「环境」都被弹回。所以这一项状态属于"跨重挂载必须存活",
40
+ * 按官方 slot 纪律放进声明式 store。
41
+ */
42
+ export declare function createConsoleStore(): import("@deepseek-ai/dsh-client-store").EngineStoreHandle<ConsoleStoreState, {
43
+ /**
44
+ * 选中一个子页并记进"已挂载"集合。
45
+ * @param draft - store 草稿。
46
+ * @param id - 子页 id。
47
+ */
48
+ select(draft: ConsoleStoreState, id: string): void;
49
+ }>;
50
+ /** 控制台的 store 句柄类型(句柄在 apply 里创建;模块级不放句柄)。 */
51
+ export type ConsoleStoreHandle = ReturnType<typeof createConsoleStore>;
52
+ /** 环境控制台的注册项 props(官方组合别名 + store 座位 + 本插件字典)。 */
53
+ export type ConsolePageProps = ComposedProps<'settings.section', EntryKeyOf<'settings.section'>, never, HandleOf<ConsoleStoreHandle>, ConsoleFace, never, typeof NS>;
54
+ /**
55
+ * 渲染环境控制台。
56
+ *
57
+ * @param props - 框架绑定的五个 share(owner / 注入面 / 字典座位等)。
58
+ * @returns 带本地子页面切换的控制台。
59
+ */
60
+ export declare function ConsolePage({ t, useStore, actions, useHealth, useEnvironments, useConfig, useTrial, diagnose, fix, setDiagnosticTarget, refreshEnvironments, startEnvironment, stopEnvironment, createEnvironment, renameEnvironment, removeEnvironment, copyPlugins, exportBackup, loadBackup, diffBackup, restoreBackup, dismissEnvironmentNotice, editConfigField, saveConfig, discardConfig, loadTrial, removeTrialEnvironment, cleanupTrialEnvironments, }: ConsolePageProps): import("react").JSX.Element;
61
+ /** 设置子页的 props。 */
62
+ interface ConfigPanelProps {
63
+ readonly t: T;
64
+ readonly useConfig: SnapshotSelectorHook<ConfigState>;
65
+ readonly useTrial: SnapshotSelectorHook<TrialState>;
66
+ readonly actions: ConfigActions;
67
+ readonly trialActions: TrialActions;
68
+ }
69
+ /**
70
+ * 渲染「设置」子页:本插件配置表单(质量门、诊断分层、市场)。
71
+ *
72
+ * 与官方插件配置页同一交互模型:改的是本地草稿,保存时才写;离开页面即放弃。
73
+ * 这个组件同时被官方插件页的 `plugins.item` / `plugins.bundle.config` 注册项复用。
74
+ *
75
+ * @param props - 字典座位、配置状态选择器与配置动作。
76
+ * @returns 配置表单。
77
+ */
78
+ export declare function ConfigPanel({ t, useConfig, useTrial, actions, trialActions }: ConfigPanelProps): import("react").JSX.Element;
79
+ export {};
@@ -0,0 +1,21 @@
1
+ /**
2
+ * KindsPage — 技能与预设:本插件安装过的 SKILL.md / agent.cordis.yml 资源清单与卸载。
3
+ *
4
+ * 归属:A 类·重写(旧 src/client 的 Kinds 相关交互只作意图参考:列表 + 卸载确认;
5
+ * 未复制代码)。
6
+ * 旧实现参考:dsh-web-plugin-manager/src/client/*(旧的技能/预设面板)。
7
+ * 官方复用:@deepseek-ai/dsh-client-ui-primitives(Button/Tag/RiskConfirmation/Toast/Tooltip)
8
+ * + RiskConfirmation 作为破坏性操作的确认面;数据来自自有 REST 的 listKinds / uninstallKind。
9
+ * 前提检查:旧实现自己扫磁盘并自己删目录;现在扫描与删除都在 host(task-4 的
10
+ * kinds 管道),客户端只渲染与触发,破坏性动作必须显式勾选确认。
11
+ */
12
+ import { type CompanionSlotProps, type KindsFace } from './shared.ts';
13
+ /** 技能与预设页的注册项 props。 */
14
+ export type KindsPageProps = CompanionSlotProps<'settings.section', KindsFace>;
15
+ /**
16
+ * 渲染技能与预设页。
17
+ *
18
+ * @param props - 字典座位、记录选择器与卸载动作。
19
+ * @returns 技能与预设页。
20
+ */
21
+ export declare function KindsPage({ t, useKinds, loadKinds, uninstallKind }: KindsPageProps): import("react").JSX.Element;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * MarketplacePage — 插件市场:索引浏览、搜索、排序、分类筛选、安装(官方通道 + 质量门)。
3
+ *
4
+ * 归属:A 类·重写(旧 src/client/PluginMarketplaceTab.tsx 815 行只作意图参考:
5
+ * 搜索框 + 分类筛选 + 条目卡片 + 安装按钮;未复制代码)。
6
+ * 旧实现参考:dsh-web-plugin-manager/src/client/PluginMarketplaceTab.tsx。旧缺陷面:
7
+ * 排序方向与比较器不一致(按钮宣称降序、列表却是升序)、已安装条目不置顶、
8
+ * 标签顺序随实现漂移——这三件事现在都由 src/marketView.ts / src/tags.ts 的纯函数
9
+ * 契约承担,组件只做渲染。
10
+ * 官方复用:@deepseek-ai/dsh-client-ui-primitives(Button/Input/Tag/Modal/Toast/Tooltip/Menu…)。
11
+ * 前提检查:索引抓取与合并都在 host(task-3 的市场管道),客户端不联网抓 GitHub,
12
+ * 也不自建 pnpm:安装走自有 install op(内部是官方 Remote 的禁用态安装 + 回滚)。
13
+ *
14
+ * 本轮(task-41)修掉的两条实证缺陷:
15
+ * 1. **安装 spec 不在这里拼**:以前送 item.repo(owner/repo),官方 parseInstallSpec 判 invalid-spec,
16
+ * 每一条都装不上。现在送 host 在 MarketItem.installSpec 里定好的值。
17
+ * 2. **索引状态要说出来**:source/stale/notes 由 host 送来,不可用画成"索引不可用 + 原因 + 重试",
18
+ * 过期画成"这是缓存索引(生成于 X)",不再与"没有匹配的条目"混为一谈。
19
+ * 另:搜索从"只搜名称"改为 name/repo/主题/描述(中文查询以前命中恒为 0)。
20
+ */
21
+ import { type CompanionSlotProps, type MarketplaceConsoleFace } from './shared.ts';
22
+ /**
23
+ * 市场页的注册项 props。
24
+ *
25
+ * 注入面 = 市场自己的面 + 升级面:已装条目的卡片上那个「升级到 x.y.z」用的是**同一份**
26
+ * 升级检查结果与同一个升级动作(零新机制),所以两个面在装配处合成一份(index.ts),
27
+ * 这里按合成后的形状声明。
28
+ */
29
+ export type MarketplacePageProps = CompanionSlotProps<'settings.section', MarketplaceConsoleFace>;
30
+ /**
31
+ * 渲染插件市场页。
32
+ *
33
+ * @param props - 字典座位、市场状态选择器与市场动作。
34
+ * @returns 市场页。
35
+ */
36
+ export declare function MarketplacePage({ t, useMarketplace, useUpgrade, loadMarketplace, setMarketQuery, setMarketCategory, setMarketKind, installMarketItem, dismissInstallNotice, ensureUpgrades, upgradePackage, }: MarketplacePageProps): import("react").JSX.Element;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * OfficialSlots — 在官方插件页里注册本插件的卡片与配置面("点开即可管理")。
3
+ *
4
+ * 归属:A 类·重写(旧仓库用遮蔽注册抢官方插件的 tab,前提已消失)。
5
+ * 旧实现参考:dsh-web-plugin-manager/src/client/*(旧做法是注册 settings.plugins.tab
6
+ * 把官方只读清单挤掉;新做法是**作为注册方**接入官方声明的 slot,不遮蔽任何东西)。
7
+ * 官方复用:官方 slot 契约(镜像见 shared.ts 的 SlotMap 声明)+ 官方插件页的
8
+ * `plugins.item` / `plugins.bundle.config`(owner props: view = summary | page);
9
+ * 配置表单复用 ConsolePage 的 ConfigPanel(与设置子页同一份官方 settings 文档)。
10
+ * 前提检查:官方页面声明这三个 slot 并要求"注册方与页面同生"——注册只在该行启用
11
+ * 期间存在,组合包关闭时不显示配置控件是预期行为,这里不绕。
12
+ */
13
+ import type { TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
14
+ import { NS } from './locales.ts';
15
+ import type { CompanionSlotProps, ConsoleFace } from './shared.ts';
16
+ /** 本文件里 t 的键域(本插件字典)。 */
17
+ type T = TranslateNS<typeof NS>;
18
+ /** 官方 `plugins.item` 卡片与 `plugins.bundle.config` 配置面共用的注册项 props。 */
19
+ export type CompanionOfficialProps = CompanionSlotProps<'plugins.item', ConsoleFace> | CompanionSlotProps<'plugins.bundle.config', ConsoleFace>;
20
+ /** 官方插件页为我们声明的 owner props 只有 view 一个字段;两处形状一致。 */
21
+ interface ViewProps {
22
+ readonly t: T;
23
+ readonly view: 'summary' | 'page';
24
+ }
25
+ /**
26
+ * 渲染本插件在官方插件页里的两个视图。
27
+ *
28
+ * summary:标题下的一句话(卡片与详情页顶部都用它)。
29
+ * page:带自己保存控件的配置表单——与「设置 → 环境控制台 → 设置」是同一份文档。
30
+ *
31
+ * @param props - 官方页面传入的 view + 框架绑定的注入面 + 字典座位。
32
+ * @returns 对应视图的节点。
33
+ */
34
+ export declare function CompanionOfficialItem(props: CompanionOfficialProps & ViewProps): import("react").JSX.Element;
35
+ export {};
@@ -0,0 +1,108 @@
1
+ /**
2
+ * UpgradeRow — 官方插件页里该组合包自己的升级行(主落点,按包名注册)。
3
+ *
4
+ * 归属:A 类·重写(新组件;旧仓库没有升级界面)。
5
+ * 旧实现参考:无。
6
+ * 官方复用:官方 ui-primitives(Button / Tag / Tooltip)与官方插件页的
7
+ * plugins.bundle.config 槽位契约(owner props 只有 view:'summary' | 'page')。
8
+ * 前提检查(已核官方源码,不另找位置):官方插件页只有三个槽位——plugins.item(list,只服务
9
+ * "官方"那一组)/ plugins.bundle.config(keyed by 包名)/ plugins.row.config(keyed <包名>#<行 id>);
10
+ * 卸载按钮与启用开关在 DetailTop 的 actions 里,**没有槽位**。所以"加在删除旁边"做不到,
11
+ * 本组件**不做任何 DOM 注入**,只作为注册方接入官方声明的槽位。
12
+ *
13
+ * 四态显示规则(DESIGN §5.5,防"靠缺席传达"):
14
+ * 有更新 → 升级入口(多 dist-tag 时列出让用户挑,默认高亮与当前同线的最新);
15
+ * 已检查无更新 → 不画(由 index.ts 的注册对账把 key 撤掉,那一节当场消失);
16
+ * 检查失败 → **必须画**「查不到:<原因>」+ 重试,绝不显示"已是最新";
17
+ * 不可升级 → 说明 + 命令,**不给按钮**(安装方提供的层在 profile 内升不了)。
18
+ *
19
+ * view='summary' 时只给一句话:官方的卡片与详情页顶部都会渲染它。
20
+ */
21
+ import type { SnapshotSelectorHook, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots';
22
+ import { NS } from './locales.ts';
23
+ import type { UpgradeActionResultState, UpgradeFace, UpgradeRollbackResultState, UpgradeState } from './shared.ts';
24
+ import type { UpgradeUnitView } from './wire.ts';
25
+ /** 本文件里 t 的键域(本插件字典)。 */
26
+ type T = TranslateNS<typeof NS>;
27
+ /** 升级行从注册项拿到的注入面(注册项自己的 face 里就有这几个动作)。 */
28
+ export type UpgradeRowActions = Pick<UpgradeFace, 'ensureUpgrades' | 'loadUpgrades' | 'upgradePackage' | 'rollbackPackage' | 'dismissUpgradeNotice'>;
29
+ /**
30
+ * 注册项交给本组件的完整 props。
31
+ *
32
+ * `useUpgrade` 是框架从注册项 inject 的 `hooks` 隔间合成的选择器 Hook(业务组件不自己订阅,
33
+ * 官方 slot 纪律第 4 条);`view` 是官方页面传进来的 owner props;其余四个升级动作
34
+ * **平铺**在这里——官方 slot 契约就是"inject 返回的成员逐项成为组件 props",
35
+ * 所以本类型直接继承 {@link UpgradeRowActions},不另包一层 actions。
36
+ */
37
+ export interface UpgradeRowProps extends UpgradeRowActions {
38
+ readonly t: T;
39
+ readonly useUpgrade: SnapshotSelectorHook<UpgradeState>;
40
+ readonly view: 'summary' | 'page';
41
+ /** 本行对应的包名(keyed slot 的 key)。 */
42
+ readonly name: string;
43
+ }
44
+ /**
45
+ * 渲染一个组合包的升级行。
46
+ *
47
+ * @param props - 字典座位、owner 的 view、该包的单元视图与升级动作。
48
+ * @returns 升级行;状态为"已是最新"时返回 null(那一节由注册对账撤掉,这里再兜一层)。
49
+ */
50
+ export declare function UpgradeRow({ t, unit, checked, view, actions, busy, }: {
51
+ readonly t: T;
52
+ /**
53
+ * 这一轮检查里该包的单元。
54
+ *
55
+ * undefined 有**两种**含义,靠 {@link checked} 分开(真机实测踩过):
56
+ * · 还没查过 → 画"尚未检查更新 + 检查按钮"("没查"也必须说出来,§12.3.3);
57
+ * · 查过了但这次没有它 → 什么都不画(它已经不是这一轮的升级单元了,
58
+ * 注册对账随后会把这个 key 撤掉;此时画"尚未检查更新"是在**编一个不存在的事实**)。
59
+ */
60
+ readonly unit: UpgradeUnitView | undefined;
61
+ /** 这一轮检查是否已经落定(check 有值)。 */
62
+ readonly checked: boolean;
63
+ readonly view: 'summary' | 'page';
64
+ readonly actions: UpgradeRowActions;
65
+ readonly busy: boolean;
66
+ }): import("react").JSX.Element | null;
67
+ /**
68
+ * 渲染最近一次升级(或回滚)的结果。
69
+ *
70
+ * 这是"失败态不得渲染成完成"在界面上的落点,所以四档各有自己的措辞与色调:
71
+ * · done 成功(并且要说清生效时机);
72
+ * · unverified **升级了,但没验证** —— 既不是失败也不是通过,必须能看出来;
73
+ * · rolled-back 试装拦下:**没有升级**,真实环境没被动过;
74
+ * · failed 没完成(官方通道失败 / 盘上核对没对上 / 传输失败)。
75
+ *
76
+ * 金丝雀那一行单独给(passed / failed / not-run / absent 四态各自可辨),
77
+ * 因为"没验证"与"验证失败"混起来就等于把风险藏了。
78
+ *
79
+ * **回滚入口就在这个块里**(task-97 的 Lead 裁决):回滚的语义是"刚升完发现问题",
80
+ * 天然跟在一次升级之后;做成卡片上常驻的按钮,用户按下去会面临"回到哪个版本"的不确定。
81
+ * 所以入口只在这一块出现,且必须**二次确认**。
82
+ *
83
+ * @param props - 字典座位、升级结果与回滚结果、回滚动作与处置回调。
84
+ * @returns 结果块;没有结果时 null。
85
+ */
86
+ export declare function UpgradeResult({ t, action, rollback, onRollback, onDismiss, }: {
87
+ readonly t: T;
88
+ readonly action: UpgradeActionResultState | undefined;
89
+ readonly rollback: UpgradeRollbackResultState | undefined;
90
+ /** 触发回滚(二次确认之后才调)。 */
91
+ readonly onRollback: (name: string, version: string, spec?: string) => void;
92
+ readonly onDismiss: () => void;
93
+ }): import("react").JSX.Element | null;
94
+ /**
95
+ * 造一个绑定到某个包名的注册项组件。
96
+ *
97
+ * 为什么是工厂而不是给组件传 `name`:keyed slot 的注册项 props 由官方页面决定(只有 view),
98
+ * 包名是本插件在注册期就知道的事实,不该指望框架传进来。工厂把 `name` 闭包进去,
99
+ * 于是每个 key 的组件只订阅**自己那一条**单元——任何一个包的状态变化不会让别人的行重画。
100
+ *
101
+ * 放在本文件(.tsx)而不是 index.ts(.ts):注册项要 JSX,而 tsconfig.client.json 的编译面
102
+ * 只有 index.ts 及其相对 import 链,两者同属一个程序。
103
+ *
104
+ * @param name - 包名(也就是 keyed slot 的 key)。
105
+ * @returns 可直接交给 ctx.slots.register 的组件。
106
+ */
107
+ export declare function createUpgradeRowComponent(name: string): ({ t, useUpgrade, view, ...actions }: Omit<UpgradeRowProps, "name">) => import("react").JSX.Element;
108
+ export {};
@@ -0,0 +1,26 @@
1
+ /**
2
+ * index.ts — 客户端入口:字典、三个一级设置入口,以及官方插件页内的注册面。
3
+ *
4
+ * 归属:A 类·重写(旧仓库的客户端入口把 27 个 op 的 SDK、路由、状态与页面装配
5
+ * 都塞在一个文件里;这里只做装配)。
6
+ * 旧实现参考:dsh-web-plugin-manager/src/client/index.ts(理解"一个入口 + 若干子页"的
7
+ * 组织方式;未复制代码)。
8
+ * 官方复用:ctx.locale.register(字典)、ctx.slots.inject + ctx.slots.register(设置入口
9
+ * 与官方插件页 slot)、ctx.settingsScope.bind(配置读写,经 ConfigController)、
10
+ * ctx.get('remote').pluginManager.listBundles(已装集合的 live 台账,用于升级行的注册对账)。
11
+ * 前提检查:官方 settings.section 已存在且 order 约定为
12
+ * general=0 / models=10 / plugins=15 / agent-presets=20 / archived-sessions=25,
13
+ * 所以本插件用 16 / 17 / 22 插在 plugins 之后、archived-sessions 之前。
14
+ *
15
+ * 硬约束:不注册任何名为 pluginManager 的服务;不遮蔽官方任何页面(旧仓库的
16
+ * `settings.plugins.tab` 抢占已删除);官方插件页只作为注册方接入,**不做 DOM 注入**。
17
+ */
18
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
19
+ /** 本插件依赖的客户端服务:注册面、字典与 t 座位、配置读写。 */
20
+ export declare const inject: string[];
21
+ /**
22
+ * 装配客户端:字典 → 三个一级设置入口 → 官方插件页内的注册面。
23
+ *
24
+ * @param ctx - 浏览器侧 cordis 上下文。
25
+ */
26
+ export declare function apply(ctx: ClientContext): void;