dsh-config-manager 0.1.76 → 0.1.78

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 (84) hide show
  1. package/lib/adapters/plugin-data-declared.d.ts +12 -0
  2. package/lib/adapters/plugin-data-declared.js +57 -0
  3. package/lib/adapters/plugin-data.d.ts +4 -6
  4. package/lib/adapters/plugin-data.js +8 -36
  5. package/lib/adapters/plugins.d.ts +16 -0
  6. package/lib/adapters/plugins.js +223 -16
  7. package/lib/client.d.ts +104 -9
  8. package/lib/client.js +1800 -718
  9. package/lib/core/analyzer.js +3 -1
  10. package/lib/core/backup.d.ts +9 -0
  11. package/lib/core/backup.js +16 -1
  12. package/lib/core/messages.d.ts +11 -0
  13. package/lib/core/messages.js +22 -0
  14. package/lib/core/plugin-cli.d.ts +26 -0
  15. package/lib/core/plugin-cli.js +62 -2
  16. package/lib/core/rollback-attribution.d.ts +81 -0
  17. package/lib/core/rollback-attribution.js +236 -0
  18. package/lib/core/rollback-merge.d.ts +22 -0
  19. package/lib/core/rollback-merge.js +203 -0
  20. package/lib/core/rollback-point.d.ts +114 -0
  21. package/lib/core/rollback-point.js +534 -17
  22. package/lib/core/types.d.ts +28 -0
  23. package/lib/index.d.ts +26 -3
  24. package/lib/index.js +129 -16
  25. package/lib/routes/recovery.js +11 -0
  26. package/lib/schema/section-registry.js +5 -5
  27. package/lib/schema/types.d.ts +14 -0
  28. package/lib/ui/badge-tone.d.ts +16 -0
  29. package/lib/ui/badge-tone.js +20 -0
  30. package/lib/ui/i18n.d.ts +4 -4
  31. package/lib/ui/i18n.js +8 -8
  32. package/lib/ui/rollback-view.d.ts +95 -0
  33. package/lib/ui/rollback-view.js +55 -0
  34. package/lib/ui/selection-model.d.ts +140 -1
  35. package/lib/ui/selection-model.js +241 -9
  36. package/package.json +1 -1
  37. package/src/adapters/plugin-data-declared.ts +60 -0
  38. package/src/adapters/plugin-data.ts +7 -33
  39. package/src/adapters/plugins.test.ts +162 -0
  40. package/src/adapters/plugins.ts +236 -17
  41. package/src/adapters/units.test.ts +26 -0
  42. package/src/client/chat/ChatEntryView.tsx +147 -46
  43. package/src/client/chat/chat-entry-view.test.ts +277 -1
  44. package/src/client/chat/chat-entry-view.ts +98 -4
  45. package/src/client/chat/chat-node-registration.ts +71 -0
  46. package/src/client/chat/chat-slots.ts +30 -12
  47. package/src/client/common/ContentPicker.tsx +581 -175
  48. package/src/client/common/host-primitives.ts +64 -1
  49. package/src/client/common/ui.tsx +17 -3
  50. package/src/client/config-manager.module.css +630 -397
  51. package/src/client/css-scale-guard.test.ts +41 -3
  52. package/src/client/css-token-guard.test.ts +10 -4
  53. package/src/client/export/ExportView.tsx +2 -0
  54. package/src/client/index.ts +15 -3
  55. package/src/client/locales.ts +54 -10
  56. package/src/client/recovery/RollbackCard.tsx +56 -2
  57. package/src/client/recovery/RollbackDiffPane.tsx +5 -0
  58. package/src/client/recovery/RollbackFileChanges.tsx +46 -2
  59. package/src/client/recovery/recovery-locales.ts +22 -0
  60. package/src/client/recovery/rollback-file-changes.test.ts +1 -1
  61. package/src/core/analyzer.ts +3 -1
  62. package/src/core/backup.ts +16 -1
  63. package/src/core/messages.ts +22 -0
  64. package/src/core/plugin-cli.fs.test.ts +65 -3
  65. package/src/core/plugin-cli.ts +55 -2
  66. package/src/core/rollback-attribution.test.ts +120 -0
  67. package/src/core/rollback-attribution.ts +267 -0
  68. package/src/core/rollback-merge.test.ts +133 -0
  69. package/src/core/rollback-merge.ts +213 -0
  70. package/src/core/rollback-point.test.ts +412 -0
  71. package/src/core/rollback-point.ts +560 -20
  72. package/src/core/types.ts +29 -0
  73. package/src/index.facade.test.ts +60 -0
  74. package/src/index.ts +133 -19
  75. package/src/routes/recovery.ts +11 -0
  76. package/src/schema/section-registry.ts +5 -5
  77. package/src/schema/types.ts +14 -0
  78. package/src/ui/badge-tone.test.ts +23 -0
  79. package/src/ui/badge-tone.ts +27 -0
  80. package/src/ui/i18n.ts +8 -8
  81. package/src/ui/rollback-view.test.ts +27 -0
  82. package/src/ui/rollback-view.ts +139 -0
  83. package/src/ui/selection-model.test.ts +240 -2
  84. package/src/ui/selection-model.ts +349 -1
package/lib/client.d.ts CHANGED
@@ -185,6 +185,24 @@ interface ExportUnit {
185
185
  * 只下发**事实**,不下发文案 —— 界面按当前语言显示(与 DSH 同口径),绝不用 uuid 冒充标题。
186
186
  */
187
187
  blank?: boolean;
188
+ /**
189
+ * 该插件**声明的第三方数据区域**(只有 \`plugin:<包名>\` 单元可能有值;导出选择器「按插件看」用)。
190
+ *
191
+ * 用途:选择器要在**不读任何数据目录**的前提下画出「插件 → 数据目录 / 大文件」的树骨架 ——
192
+ * 区域清单来自来源注册表(内置来源表 + 插件自述 dsh.dataDirs),是静态知识,零额外 I/O;
193
+ * 体积与「实际有没有内容」等该分区的清单到货后再填。
194
+ *
195
+ * 语义:**纯展示**,不参与勾选/导出契约(契约只认 id)。这里是「注册表说它应该在哪儿」,
196
+ * **不是**「磁盘上确实有」—— 界面必须把两者分开渲染(unread / 无内容 / 已读到)。
197
+ */
198
+ relatedAreas?: readonly PluginAreaRef[];
199
+ }
200
+ /** 插件数据区域引用(pluginData / pluginAssets;只读展示用,不参与勾选契约)。 */
201
+ interface PluginAreaRef {
202
+ section: 'pluginData' | 'pluginAssets';
203
+ /** home 相对 POSIX 路径 —— 就是该分区单元的 id 后缀(\`pluginData:.mnemon/runtime\` 的末段) */
204
+ relPath: string;
205
+ role: 'config' | 'assets';
188
206
  }
189
207
  type PlanItemKind = 'Create' | 'Update' | 'Skip' | 'Conflict' | 'Install' | 'MissingSecret' | 'MissingDependency' | 'PathMapping' | 'Warning' | 'Error';
190
208
  type ItemResolution = 'keepCurrent' | 'useImported' | 'review';
@@ -1954,10 +1972,10 @@ declare const uiZh: {
1954
1972
  readonly 'export.category.settings': 'DSH 全局设置(namespace 分区,redacted)';
1955
1973
  readonly 'export.category.providers': 'LLM Provider / Model / 默认模型 / BaseURL';
1956
1974
  readonly 'export.category.plugins': '已安装插件清单与启用状态(不含二进制)';
1957
- readonly 'export.category.pluginFiles': '其他插件放在 ~/.dsh 根下的零散配置文件(白名单 + plugin-config/ 目录,整文件复制)';
1958
- readonly 'export.category.self': '本插件自身配置(同步/自动同步/分区选择/UI 偏好/市场;sync-*.json 等,不含凭据值)';
1959
- readonly 'export.category.pluginData': '其他插件在系统主目录下的数据(如 ~/.dsh-wallpaper-engine、~/.mnemon 的配置与状态;可再生成缓存绝不收录)';
1960
- readonly 'export.category.pluginAssets': '其他插件的大体积文件(上传的壁纸、本地数据库等;默认不勾选)';
1975
+ readonly 'export.category.pluginFiles': '插件放在 ~/.dsh 根下的配置文件(白名单 + plugin-config/ 目录,整文件复制)';
1976
+ readonly 'export.category.self': '配置管理器自身的设置(同步/自动同步/分区选择/UI 偏好/市场;sync-*.json 等,不含凭据值)';
1977
+ readonly 'export.category.pluginData': '插件在系统主目录下的数据(如 ~/.dsh-wallpaper-engine、~/.mnemon 的配置与状态;可再生成缓存绝不收录)';
1978
+ readonly 'export.category.pluginAssets': '插件的大体积文件(上传的壁纸、本地数据库等;默认不勾选)';
1961
1979
  readonly 'export.category.mcp': 'MCP 服务器组合配置(需重启生效)';
1962
1980
  readonly 'export.category.prompts': 'System Prompt / Plan Mode 提示';
1963
1981
  readonly 'export.category.skills': '用户技能文件(~/.dsh/skills)';
@@ -4164,6 +4182,23 @@ interface RollbackPreviewFile {
4164
4182
  removed: number | null;
4165
4183
  /** true = 本次没有可信行数(added/removed 均为 null)。**宁可说「不知道」,也绝不谎报行数。** */
4166
4184
  truncated: boolean;
4185
+ /**
4186
+ * true = 该文件在留点**之后**是**别的会话**写的(写入归属台账证明;见 core/rollback-attribution.ts)。
4187
+ * 界面据此默认不勾选它(用户仍可勾上)。缺字段 / false = **没有归属证据**,
4188
+ * 而不是「本会话写的」——「未判定」与「确知是本会话」必须分开。
4189
+ */
4190
+ foreign?: boolean;
4191
+ /** 那些「别的会话」的会话 id(仅当 foreign 为 true) */
4192
+ foreignSessionId?: string;
4193
+ /** 那次写入的时间(毫秒;仅当 foreign 为 true) */
4194
+ foreignAt?: number;
4195
+ /**
4196
+ * true = 这次回退**不会改动它**(与其它对话的改动冲突 / 无法安全合并)。行级统计为 null ——
4197
+ * 「不改动」不是「0 行变化」,界面必须分开说。
4198
+ */
4199
+ skipped?: boolean;
4200
+ /** 不改动的机器原因(界面映射成字典键,绝不裸渲染) */
4201
+ mergeReason?: string;
4167
4202
  }
4168
4203
  interface RollbackWorkspacePreview {
4169
4204
  /** 将被写回(覆盖)的条目数 */
@@ -4285,6 +4320,12 @@ interface RollbackFileDiffResult {
4285
4320
  identical: boolean;
4286
4321
  degraded: boolean;
4287
4322
  reason?: RollbackFileDiffReason;
4323
+ /** true = 「回退后」一侧显示的是三方合并的结果(不是记录里的原文) */
4324
+ merged?: boolean;
4325
+ /** true = 这次回退不会改动它(冲突 / 无法安全合并)——此时两侧相同 */
4326
+ mergeSkipped?: boolean;
4327
+ /** 不改动的机器原因(界面映射成字典键) */
4328
+ mergeReason?: string;
4288
4329
  }
4289
4330
  interface RollbackSegmentResult {
4290
4331
  state: string;
@@ -4310,6 +4351,22 @@ interface RollbackSegmentResult {
4310
4351
  createdRefusedReason?: string | null;
4311
4352
  /** 工作区段:实际写回的字节数(宿主回传才有) */
4312
4353
  writtenBytes?: number;
4354
+ /** 因归属隔离(B)跳过的记录条目数:该文件在留点后被**别的会话**写过(宿主回传才有) */
4355
+ foreignSkipped?: number;
4356
+ /** 因路径选择(A)跳过的记录条目数(宿主回传才有) */
4357
+ selectionSkipped?: number;
4358
+ /** 三方合并成功、写回「撤销本会话 + 保留对方改动」的条目数(宿主回传才有) */
4359
+ mergedCount?: number;
4360
+ mergedPaths?: string[];
4361
+ /** 冲突:两侧改到同一处 ⇒ 未写(宿主回传才有) */
4362
+ conflictCount?: number;
4363
+ conflictPaths?: string[];
4364
+ /** 无法安全撤销 ⇒ 未写(宿主回传才有) */
4365
+ unavailableCount?: number;
4366
+ unavailablePaths?: string[];
4367
+ /** 写入前发现又被改过(并发)⇒ 未写(宿主回传才有) */
4368
+ concurrentCount?: number;
4369
+ concurrentPaths?: string[];
4313
4370
  /** 兼容形态:宿主只回传计数时也算得出来 */
4314
4371
  createdAfter?: RollbackCount;
4315
4372
  createdAfterTruncated?: boolean;
@@ -4348,6 +4405,13 @@ interface RollbackRewindOptions {
4348
4405
  segments?: readonly RollbackState[];
4349
4406
  allowPartial?: boolean;
4350
4407
  preRewindGuard?: RollbackGuardPolicy;
4408
+ /**
4409
+ * 路径级选择性恢复(2026-10-17 定案 A):只恢复这些路径。
4410
+ *
4411
+ * 缺省 = 全量口径(一字不变)。**空数组是无效输入**(宿主 400)—— 「一个都没勾」由界面拦住,
4412
+ * 绝不让它变成「整次回退静默 noop」。
4413
+ */
4414
+ onlyPaths?: readonly string[];
4351
4415
  }
4352
4416
  /** 端口:由 src/client/recovery/recovery-api.ts 实现(Partial 消费,缺失时界面如实说能力缺失)。 */
4353
4417
  interface RollbackPointPort {
@@ -4689,20 +4753,20 @@ declare const zh$4: {
4689
4753
  readonly 'section.settings': '设置';
4690
4754
  readonly 'section.ui': 'UI 偏好';
4691
4755
  readonly 'section.providers': 'Provider 与模型';
4692
- readonly 'section.plugins': '插件';
4756
+ readonly 'section.plugins': '插件清单';
4693
4757
  readonly 'section.mcp': 'MCP 服务器';
4694
4758
  readonly 'section.prompts': '提示词';
4695
4759
  readonly 'section.skills': '技能';
4696
4760
  readonly 'section.agentPresets': 'Agent 预设';
4697
4761
  readonly 'section.agentInstructions': '全局指令';
4698
4762
  readonly 'section.workspaces': '工作区';
4699
- readonly 'section.pluginFiles': '其他插件零散文件';
4763
+ readonly 'section.pluginFiles': '插件散落配置';
4700
4764
  readonly 'section.credentialsStatus': '凭据状态';
4701
4765
  readonly 'section.secrets': '密钥';
4702
4766
  readonly 'section.sessions': '历史会话';
4703
- readonly 'section.self': '本插件自身配置';
4704
- readonly 'section.pluginData': '其他插件数据';
4705
- readonly 'section.pluginAssets': '其他插件大文件';
4767
+ readonly 'section.self': '配置管理器设置';
4768
+ readonly 'section.pluginData': '插件数据目录';
4769
+ readonly 'section.pluginAssets': '插件大文件';
4706
4770
  readonly 'view.about': '关于';
4707
4771
  readonly 'about.snippet.environment': '### 环境 / Environment';
4708
4772
  readonly 'about.releaseNotes.rateLimited': 'GitHub API 速率限制(Rate limit exceeded),请稍后再试或直接在 GitHub 上查看。';
@@ -4842,6 +4906,26 @@ declare const zh$4: {
4842
4906
  readonly 'picker.sensitive': '敏感';
4843
4907
  readonly 'picker.showAll': '显示全部(共 {count} 条)';
4844
4908
  readonly 'picker.summaryImport': '将导入 {sections} 个分区 · {units} 个条目';
4909
+ readonly 'picker.pluginRoot': '插件';
4910
+ readonly 'picker.pluginLeafPlugin': '插件清单条目';
4911
+ readonly 'picker.pluginLeafConfig': '数据目录(配置)';
4912
+ readonly 'picker.pluginLeafAssets': '大文件(壁纸 / 数据库)';
4913
+ readonly 'picker.pluginAreaUnread': '未读取';
4914
+ readonly 'picker.pluginAreaAbsent': '无内容';
4915
+ readonly 'picker.pluginViewEmpty': '插件清单还没读到,先读取「插件」分区。';
4916
+ readonly 'picker.bucketPlugins': '插件分区的其他条目(补丁行 / pnpm-workspace.yaml)';
4917
+ readonly 'picker.bucketLooseFiles': '未归属到插件的配置(~/.dsh 根)';
4918
+ readonly 'picker.bucketHint': '这些条目没有可证明的插件归属,不猜;展开可逐条勾选。';
4919
+ readonly 'picker.groupHint.extensions': '这一组里的插件分区合并成一棵按插件分组的树:默认只显示一个「插件」区块,展开它才列出各个插件,插件名下面是它的清单条目、数据目录与大文件。只显示能证明的归属(内置来源表 + 插件自述 dsh.dataDirs)——「插件散落配置」没有包名信息,因此留在「未归属」里;带「设备相关」的分区默认不勾选,跨设备导入时可能不适用。';
4920
+ readonly 'group.general': '通用';
4921
+ readonly 'group.ai': 'AI';
4922
+ readonly 'group.extensions': '插件与扩展';
4923
+ readonly 'group.mcp': 'MCP / 工具';
4924
+ readonly 'group.customization': '定制';
4925
+ readonly 'group.automation': '自动化';
4926
+ readonly 'group.workspace': '工作区';
4927
+ readonly 'group.ui': '界面';
4928
+ readonly 'group.optional': '可选数据';
4845
4929
  readonly 'import.nothingSelected': '当前没有勾选任何要导入的内容,请把需要导入的分区或条目勾上。';
4846
4930
  readonly 'import.excludedByUser': '本次有 {count} 项被你取消勾选:未导入,也未进快照。';
4847
4931
  readonly 'import.consult.hint': '只读分析:先看结论与依据,确认后再选择要导入的内容。';
@@ -6529,6 +6613,14 @@ declare const zh$1: {
6529
6613
  readonly 'rollback.preview.notice.skipped': '{n} 项在留点时被跳过(未记录;已计入证明名单 ⇒ 不参与删除判据)';
6530
6614
  readonly 'rollback.preview.notice.truncated': '该点捕获被上限截断(超单文件上限 / 字节预算 / 文件数预算);删除判据另看证明名单(路径索引)是否完整';
6531
6615
  readonly 'rollback.preview.files.title': '将被回退的文件:';
6616
+ readonly 'rollback.preview.select.foreign': '其它对话改过';
6617
+ readonly 'rollback.preview.select.toggle': '「{path}」:勾上则这次回退恢复它';
6618
+ readonly 'rollback.result.foreignSkipped': '{n} 个文件在留点后被其它对话改过,这次没有回退它们';
6619
+ readonly 'rollback.result.merged': '{n} 个文件已合并:撤销本次对话的改动,保留其它对话的改动';
6620
+ readonly 'rollback.result.conflict': '{n} 个文件两侧改到同一处,已保持原样 —— 需要你手工处理';
6621
+ readonly 'rollback.result.unavailable': '{n} 个文件无法安全撤销(缺少中间版本 / 二进制 / 差异过大),已保持原样';
6622
+ readonly 'rollback.result.concurrent': '{n} 个文件在回退过程中又被改过,已保持原样';
6623
+ readonly 'rollback.result.selectionSkipped': '{n} 个文件按你的勾选跳过了';
6532
6624
  readonly 'rollback.preview.files.empty': '工作区与该回退点一致,无需恢复';
6533
6625
  readonly 'rollback.preview.files.unavailable': '该回退点的工作区态没有可用的记录(原因:{reason}),无需恢复';
6534
6626
  readonly 'rollback.preview.files.unavailableSession': '该回退点的工作区态没有可用的记录(原因:{reason});会话仍会回退到该点之前';
@@ -6538,6 +6630,9 @@ declare const zh$1: {
6538
6630
  readonly 'rollback.preview.file.removed': '−{n}';
6539
6631
  /** 整文件删除(用户 2026-10-12 第 6 条):写「删除」而不是 `+0 −N` —— 那是两件事。 */
6540
6632
  readonly 'rollback.preview.file.deleted': '删除';
6633
+ readonly 'rollback.preview.file.skipped': '不会改动(与其它对话的改动冲突,或无法安全合并)';
6634
+ readonly 'rollback.diff.merged': '下面是合并后的结果:撤销本对话的改动、保留其它对话的改动';
6635
+ readonly 'rollback.diff.skipped': '这次回退不会改动它(与其它对话的改动冲突,或无法安全合并)';
6541
6636
  readonly 'rollback.preview.file.unknown': '行数未统计';
6542
6637
  readonly 'rollback.preview.file.unknownHint': '这些文件的行数没有统计出来(文件过大、不是文本或内容副本读不出来)—— 回退仍会照常覆盖它们。';
6543
6638
  readonly 'rollback.diff.viewHint': '查看差异:{path}';