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,299 @@
1
+ /**
2
+ * 插件拥有的 agent 预设:归属标记、卸载清理、禁用归档 / 启用恢复。
3
+ *
4
+ * 归属:A 类·重写(读标记载录、移动与删除目录、经官方服务落刀;旧 src/presets.ts
5
+ * 仅作意图参考,未复制代码)。
6
+ * 旧实现参考:dsh-web-plugin-manager/src/presets.ts(385 行:中立标准标记
7
+ * .dsh-preset-owner.json = {format, owners[], digest}、兼容读取 dsh-agent-rp 的
8
+ * .dsh-agent-rp-owner.json 与 gamelike 的 .plugin-manage-owner.json、卸载只清
9
+ * "唯一 owner 且 digest 匹配"、禁用零损失归档、启用恢复)。
10
+ * 官方复用:删除走 ctx.get("agentPresets").remove(id)——官方会同时清掉指向该预设的
11
+ * settings.default 并保留已挂载会话;本模块**绝不直接删官方 roster 里的目录**,
12
+ * 只有在宿主服务不存在时(CLI/离线)才降级为带路径守卫的直删。
13
+ * 目录枚举复用官方 roster 的 roots(ctx.get("agentPresets").roots),比"自己拼
14
+ * <dshHome>/.agent-presets"更贴近官方发现口径。
15
+ * 前提检查:仍然成立——预设目录名是 preset id,不是所属插件名,所以卸载插件后
16
+ * 预设会变成孤儿;官方明文不做这件事("the manager cannot ... edit an agent
17
+ * preset composition")。旧实现里"经宿主 settings 清 default"的部分已由官方
18
+ * remove() 承担,本模块不再自己写 settings。
19
+ *
20
+ * 为什么禁用只能归档不能删:官方对"坏预设"的判定只看组合文件是否可读/可解析,
21
+ * 不反映"它引用的插件被禁用了";拿不到"这个坏是我造成的"这个信号就没有安全删除
22
+ * 的依据,何况临时禁用本来就不该毁数据。
23
+ */
24
+ import { type InstallOutcome } from './kinds.ts';
25
+ import type { InstalledKind } from './types.ts';
26
+ /**
27
+ * 中立标准归属标记文件名(本插件安装预设时写入;兼容读取生态标记见下)。
28
+ *
29
+ * 字面量在这里定义而不是从 kinds.ts 转口:kinds 与 presets 互相 import(kinds 安装时要
30
+ * 写标记、presets 要读磁盘与路径工具),而 ESM 的循环依赖在**模块初始化期**取值会撞上
31
+ * TDZ(Cannot access before initialization)。两边都只在函数体里引用对方,循环就是安全的。
32
+ */
33
+ export declare const OWNER_MARKER = ".dsh-preset-owner.json";
34
+ /** 标记 schema 版本。 */
35
+ export declare const OWNER_MARKER_FORMAT = 0;
36
+ /**
37
+ * 禁用插件的预设归档目录。
38
+ *
39
+ * 必须在官方 user root **之外**(否则 roster 照样发现它),也必须在 profiles 根
40
+ * 之外(否则会被当成一个环境)。放在我们的缓存目录下,与旧仓库同名同位置,
41
+ * 两个包共存期间归档数据是同一份。
42
+ *
43
+ * @returns 归档根目录。
44
+ */
45
+ export declare function presetArchiveDir(): string;
46
+ /**
47
+ * 计算预设目录的安装 digest。
48
+ *
49
+ * 方案沿用既有生态协议:按 DIGEST_FILES 逐个 update(文件名 + NUL + 内容 + NUL),
50
+ * 取 sha256。文件不存在就跳过(预设可以只有组合文件);读取失败返回 null,
51
+ * 语义是"无法核实",由调用方按"可能被改过"处理(fail closed)。
52
+ *
53
+ * @param presetDir - 预设目录。
54
+ * @returns 十六进制 digest;无法读取时为 null。
55
+ */
56
+ export declare function presetDigest(presetDir: string): string | null;
57
+ /**
58
+ * 读取一个预设目录声明的全部 owner(标准标记 + 生态既有标记)。
59
+ *
60
+ * 兼容三种形态:
61
+ * - 我们的标准标记 .dsh-preset-owner.json:{format: 0, owners: string[], digest};
62
+ * - dsh-agent-rp 的 .dsh-agent-rp-owner.json:{owner, format: 0, digest};
63
+ * - gamelike-plugin-manage 的 .plugin-manage-owner.json:{format, owners[]}(无 digest)。
64
+ *
65
+ * 失败策略是**不对称**的,这是刻意的:标准标记存在但损坏 → 整体返回空数组
66
+ * (fail closed,什么都不删);第三方标记损坏/format 不符 → 单个跳过(他们的写入
67
+ * 端约束更松,用一条坏文件阻断全部清理不合理)。
68
+ *
69
+ * @param presetDir - 预设目录。
70
+ * @returns owner 列表(去重、按发现顺序)。
71
+ */
72
+ export declare function readPresetOwners(presetDir: string): string[];
73
+ /** 一个预设目录(目录名即 preset id)。 */
74
+ export interface PresetEntry {
75
+ /** preset id,等于目录名。 */
76
+ readonly id: string;
77
+ /** 绝对路径。 */
78
+ readonly dir: string;
79
+ }
80
+ /**
81
+ * 枚举一个根下的预设目录(跳过点目录与预设归档目录)。
82
+ * @param root - 预设根目录。
83
+ * @returns 预设条目;根不存在或不可读时返回空数组。
84
+ */
85
+ export declare function scanPresets(root: string): PresetEntry[];
86
+ /** 一个预设目录的归属判定。 */
87
+ export interface PresetOwnership {
88
+ /** 这个预设的唯一 owner 是否就是给定插件。 */
89
+ readonly owned: boolean;
90
+ /** 文件是否已不再匹配标记里的 digest(用户改过)。 */
91
+ readonly modified: boolean;
92
+ }
93
+ /**
94
+ * 一个预设目录的归属判定。
95
+ *
96
+ * 只有**唯一 owner 且等于给定插件名**才叫 owned:多 owner 预设(两个插件的归属
97
+ * 重叠)不做任何操作——一个 owner 的卸载不该带走另一个的数据。
98
+ *
99
+ * modified 的三种来源都算"用户改过":digest 不匹配、标准标记损坏(fail closed)、
100
+ * 无法读取组合文件(presetDigest 返回 null)。只有根本没有 digest 的生态标记
101
+ * (gamelike 形态)报未修改——它没有可比对的基线。
102
+ *
103
+ * @param presetDir - 预设目录。
104
+ * @param pluginName - 插件名(通常是包名)。
105
+ * @returns 归属判定。
106
+ */
107
+ export declare function presetOwnedBy(presetDir: string, pluginName: string): PresetOwnership;
108
+ /**
109
+ * 官方 agentPresets 服务的结构式视图。
110
+ *
111
+ * 只声明我们真正调用的方法,不 import 官方类:官方包是 peer,小版本之间可能
112
+ * 有增减,结构式引用让"官方少了一个方法"变成一次运行时检查而不是编译期断裂。
113
+ */
114
+ export interface AgentPresetService {
115
+ /** 列出全部预设。同步值或 Promise 都接受(官方是 async,测试替身常用同步)。 */
116
+ list(): unknown;
117
+ remove(id: string): unknown;
118
+ /** 官方 roster 实际扫描的根(用户根在最后)。 */
119
+ readonly roots?: readonly {
120
+ readonly path: string;
121
+ readonly trust: string;
122
+ }[];
123
+ }
124
+ /**
125
+ * 取官方 agentPresets 服务(ctx 或服务本身都能传)。
126
+ *
127
+ * 传入的可以是 Cordis 的 Context(用 ctx.get 取服务),也可以是服务对象自己
128
+ * (CLI 测试替身)。两者都不满足时返回 undefined——调用方据此降级为直删。
129
+ *
130
+ * @param source - Context 或服务对象。
131
+ * @returns 服务视图;不可用时 undefined。
132
+ */
133
+ export declare function agentPresetsOf(source: unknown): AgentPresetService | undefined;
134
+ /**
135
+ * 官方 roster 里 trust 为 user 的预设根;拿不到时退回 <dshHome>/.agent-presets。
136
+ *
137
+ * @param ctx - Context 或有 root 的服务对象。
138
+ * @returns 用户预设根目录。
139
+ */
140
+ export declare function userPresetRoot(ctx: unknown): string;
141
+ /** 一次归属扫描的结果。 */
142
+ export interface PresetScanResult {
143
+ /** 扫描的根。 */
144
+ readonly root: string;
145
+ /** 每个预设目录及其归属判定。 */
146
+ readonly entries: readonly {
147
+ readonly id: string;
148
+ readonly dir: string;
149
+ readonly owners: readonly string[];
150
+ readonly owned: boolean;
151
+ readonly modified: boolean;
152
+ }[];
153
+ }
154
+ /**
155
+ * 扫描一个根下的全部预设及其归属。
156
+ *
157
+ * @param root - 预设根目录。
158
+ * @param pluginName - 归属判定用的插件名。
159
+ * @returns 扫描结果。
160
+ */
161
+ export declare function scanPresetOwnership(root: string, pluginName: string): PresetScanResult;
162
+ /** 一次归属列举的结果。 */
163
+ export interface PresetOwnershipList {
164
+ /** 我们安装记录里属于该插件的预设 id。 */
165
+ readonly recorded: readonly string[];
166
+ /** 磁盘上标记为属于该插件的预设 id(含手工放进去的)。 */
167
+ readonly marked: readonly string[];
168
+ }
169
+ /**
170
+ * 列出某插件拥有的预设:安装记录 + 磁盘标记两个来源合并。
171
+ *
172
+ * 两个来源都要看:记录可能被删(用户手工 rm 过),标记可能是别的工具写的。
173
+ * 合并后去重,卸载与归档都要用这份清单。
174
+ *
175
+ * @param pluginName - 插件名(包名)。
176
+ * @param root - 覆盖预设根(默认官方用户根)。
177
+ * @returns 预设 id 清单。
178
+ */
179
+ export declare function listOwnedPresetIds(pluginName: string, root?: string): Promise<PresetOwnershipList>;
180
+ /** 一次清理的结果。 */
181
+ export interface PresetCleanupResult {
182
+ /** 已删除的预设 id。 */
183
+ readonly removed: readonly string[];
184
+ /** 保留的预设及原因(用户改过、多 owner、越界、官方服务报错)。 */
185
+ readonly skipped: readonly {
186
+ readonly id: string;
187
+ readonly reason: string;
188
+ }[];
189
+ /**
190
+ * 需要用户知道的附加事实,例如:没有宿主服务时只能直删目录,默认预设可能还指着被删的 id。
191
+ * 刻意与 skipped 分开——同一个 id 不能既出现在 removed 又出现在 skipped 里。
192
+ */
193
+ readonly notes: readonly string[];
194
+ }
195
+ /** 一次归档/恢复的结果。 */
196
+ export interface PresetMoveResult {
197
+ /** 已移动的预设 id。 */
198
+ readonly moved: readonly string[];
199
+ /** 未移动的预设及原因。 */
200
+ readonly skipped: readonly {
201
+ readonly id: string;
202
+ readonly reason: string;
203
+ }[];
204
+ }
205
+ /** 清理结果的可读摘要(CLI/UI 输出用)。 */
206
+ export declare function formatCleanupResult(pluginName: string, result: PresetCleanupResult): string;
207
+ /** 归档结果的可读摘要。 */
208
+ export declare function formatArchiveResult(pluginName: string, result: PresetMoveResult): string;
209
+ /** 恢复结果的可读摘要。 */
210
+ export declare function formatRestoreResult(pluginName: string, result: PresetMoveResult): string;
211
+ /**
212
+ * 卸载清理:删除"唯一 owner 是它且未被用户改过"的预设。
213
+ *
214
+ * 三条判定线,任一条不满足就保留并报告:
215
+ * - 多 owner:归属重叠,一个 owner 的卸载不该带走另一个的数据;
216
+ * - digest 不匹配(用户改过):用户的编辑比插件的原版更有价值,交还给用户;
217
+ * - 路径越界:兜底防线,正常路径不会触发(目录来自 scanPresets)。
218
+ *
219
+ * 删除路径优先官方 agentPresets.remove(id)——它会同时清掉指向该预设的
220
+ * settings.default,并让已挂载会话继续跑;只有在服务不存在时(CLI 无宿主)
221
+ * 才降级为带守卫的直删,此时会多报告一条"宿主不可用,已直删;如需清理
222
+ * 默认预设请在设置页确认"。
223
+ *
224
+ * @param ctx - Context 或官方服务对象;可为 undefined(CLI)。
225
+ * @param pluginName - 被卸载的插件名。
226
+ * @param options - 根覆盖与"是否还有别的环境装着它"。
227
+ * @returns 清理结果。
228
+ */
229
+ export declare function cleanupOwnedPresets(ctx: unknown, pluginName: string, options?: {
230
+ readonly root?: string;
231
+ readonly stillInstalledElsewhere?: boolean;
232
+ }): Promise<PresetCleanupResult>;
233
+ /**
234
+ * 禁用归档:把该插件拥有的预设移出用户根,零数据损失。
235
+ *
236
+ * 与清理的关键差别:**不检查 digest**——用户改过的预设也一起归档。归档不是删除,
237
+ * 数据一点没丢,只是从选择器里消失;禁用本来就是一个可逆动作,没有理由拿
238
+ * "用户改过"当理由把它留在选择器里引用一个被禁用的插件。
239
+ *
240
+ * 目标位置已存在同名归档时保留现场并报告(覆盖等于扔掉上一份归档)。
241
+ *
242
+ * @param pluginName - 被禁用的插件名。
243
+ * @param options - 根覆盖。
244
+ * @returns 归档结果。
245
+ */
246
+ export declare function archiveOwnedPresets(pluginName: string, options?: {
247
+ readonly root?: string;
248
+ }): Promise<PresetMoveResult>;
249
+ /**
250
+ * 启用恢复:把归档的预设移回用户根。
251
+ *
252
+ * 同名预设已经出现(用户新建了同 id 的预设,或另一个插件装了同名的)时**保留
253
+ * 归档副本并报告**——让新的那份继续生效,不静默覆盖用户此刻正在用的东西。
254
+ *
255
+ * @param pluginName - 被重新启用的插件名。
256
+ * @param options - 根覆盖。
257
+ * @returns 恢复结果。
258
+ */
259
+ export declare function restoreArchivedPresets(pluginName: string, options?: {
260
+ readonly root?: string;
261
+ }): Promise<PresetMoveResult>;
262
+ /**
263
+ * 写入中立标准归属标记。
264
+ *
265
+ * 已有标记就**不覆盖**:插件或别的工具可能已经声明过这个目录,覆盖等于篡改
266
+ * 别人的归属(随后卸载会删掉不属于我们的东西)。digest 记录"刚装下去时是什么
267
+ * 样子",之后用户改了它,卸载就会跳过删除。
268
+ *
269
+ * @param presetDir - 预设目录。
270
+ * @param owners - owner 列表(通常是仓库/插件名)。
271
+ * @returns 是否真的写了(已存在时为 false)。
272
+ */
273
+ export declare function writeOwnerMarker(presetDir: string, owners: readonly string[]): Promise<boolean>;
274
+ /**
275
+ * 从安装记录里取"这次安装落下去的预设目录"并写归属标记。
276
+ *
277
+ * installPreset 已经写过一次标记(它知道落地目录);这个函数给"记录已存在但
278
+ * 标记缺失"的补写路径用(例如旧包装的预设迁过来)。
279
+ *
280
+ * @param outcome - 直装结果。
281
+ * @param pluginName - 归属插件名。
282
+ * @returns 实际写了标记的目录数。
283
+ */
284
+ export declare function markInstalledPresets(outcome: InstallOutcome, pluginName: string): Promise<number>;
285
+ /**
286
+ * 该插件是否还装在**别的环境**里。
287
+ *
288
+ * 预设是全局的(在 dshHome 下,不属于任何 profile),所以在一个环境里卸载插件
289
+ * 不等于预设失去了主人。安装记录会写进环境的 package.json dependencies,因此
290
+ * 依赖检查就是"它还在不在"的权威信号。
291
+ *
292
+ * @param currentEnvironment - 正在卸载的环境名(跳过它自己)。
293
+ * @param pluginName - 插件包名。
294
+ * @param profilesRootDir - profiles 根目录;默认取 dshHome()/profiles。
295
+ * @returns 是否还有其他环境声明该依赖。
296
+ */
297
+ export declare function pluginInstalledInOtherEnvironments(currentEnvironment: string, pluginName: string, profilesRootDir?: string): Promise<boolean>;
298
+ /** 一条预设安装记录的组装(供 kinds.ts 的调用点保持单一路径)。 */
299
+ export declare function presetKindRecord(repo: string, outcome: InstallOutcome, installedAt?: string): InstalledKind;