dsh-config-manager 0.1.78 → 0.1.79

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 (290) hide show
  1. package/lib/adapters/credentials.d.ts +6 -2
  2. package/lib/adapters/credentials.js +19 -3
  3. package/lib/adapters/file-collection.js +2 -1
  4. package/lib/adapters/mcp.d.ts +48 -2
  5. package/lib/adapters/mcp.js +265 -3
  6. package/lib/adapters/messages.d.ts +3 -0
  7. package/lib/adapters/messages.js +7 -0
  8. package/lib/adapters/plugin-files.js +2 -1
  9. package/lib/adapters/plugins.js +105 -20
  10. package/lib/adapters/pnpm-workspace.d.ts +32 -0
  11. package/lib/adapters/pnpm-workspace.js +113 -2
  12. package/lib/adapters/prompts.d.ts +6 -2
  13. package/lib/adapters/prompts.js +17 -2
  14. package/lib/adapters/providers.d.ts +19 -2
  15. package/lib/adapters/providers.js +59 -3
  16. package/lib/adapters/settings.d.ts +6 -2
  17. package/lib/adapters/settings.js +13 -2
  18. package/lib/adapters/skills.d.ts +25 -1
  19. package/lib/adapters/skills.js +60 -0
  20. package/lib/adapters/ui.d.ts +6 -2
  21. package/lib/adapters/ui.js +13 -2
  22. package/lib/adapters/units.d.ts +18 -0
  23. package/lib/adapters/units.js +39 -0
  24. package/lib/adapters/workspaces.js +2 -1
  25. package/lib/client.d.ts +400 -112
  26. package/lib/client.js +2845 -1524
  27. package/lib/core/backup.js +20 -0
  28. package/lib/core/mcp-connector-store.d.ts +159 -0
  29. package/lib/core/mcp-connector-store.js +445 -0
  30. package/lib/core/messages-core.d.ts +2 -0
  31. package/lib/core/messages-core.js +4 -0
  32. package/lib/core/messages.d.ts +20 -0
  33. package/lib/core/messages.js +44 -0
  34. package/lib/core/phase3-host.js +18 -1
  35. package/lib/core/plugin-cli.d.ts +22 -2
  36. package/lib/core/plugin-cli.js +22 -3
  37. package/lib/core/recovery-orchestrator.d.ts +3 -1
  38. package/lib/core/recovery-orchestrator.js +75 -16
  39. package/lib/core/rollback-activity.d.ts +89 -0
  40. package/lib/core/rollback-activity.js +350 -0
  41. package/lib/core/rollback-ledger.d.ts +0 -9
  42. package/lib/core/rollback-ledger.js +37 -0
  43. package/lib/core/rollback-merge.d.ts +22 -2
  44. package/lib/core/rollback-merge.js +63 -13
  45. package/lib/core/rollback-point.d.ts +93 -0
  46. package/lib/core/rollback-point.js +420 -101
  47. package/lib/core/rollback-undo-journal.d.ts +123 -0
  48. package/lib/core/rollback-undo-journal.js +517 -0
  49. package/lib/core/self-update.js +2 -4
  50. package/lib/core/text-fidelity.d.ts +89 -0
  51. package/lib/core/text-fidelity.js +176 -0
  52. package/lib/core/types.d.ts +12 -3
  53. package/lib/core/update-check.js +2 -4
  54. package/lib/core/validator.d.ts +9 -0
  55. package/lib/core/validator.js +12 -0
  56. package/lib/foreign/bundle.js +42 -3
  57. package/lib/foreign/claude-code.js +358 -26
  58. package/lib/foreign/claude-sessions.d.ts +51 -8
  59. package/lib/foreign/claude-sessions.js +111 -13
  60. package/lib/foreign/read-claude-code.d.ts +33 -4
  61. package/lib/foreign/read-claude-code.js +446 -65
  62. package/lib/foreign/read-claude-plugins.d.ts +36 -0
  63. package/lib/foreign/read-claude-plugins.js +403 -0
  64. package/lib/foreign/registry.js +25 -2
  65. package/lib/foreign/truth-table.js +6 -4
  66. package/lib/foreign/types.d.ts +170 -2
  67. package/lib/index.d.ts +14 -5
  68. package/lib/index.js +60 -16
  69. package/lib/market/git-file-writer.js +7 -1
  70. package/lib/profiles/dsh-profile-launcher.d.ts +20 -0
  71. package/lib/profiles/dsh-profile-launcher.js +58 -1
  72. package/lib/profiles/dsh-profile-shared.d.ts +8 -2
  73. package/lib/profiles/dsh-profile-shared.js +8 -2
  74. package/lib/routes/foreign.js +8 -1
  75. package/lib/routes/index.d.ts +1 -1
  76. package/lib/routes/kit.d.ts +2 -2
  77. package/lib/routes/sync.js +173 -9
  78. package/lib/schema/manifest.d.ts +6 -1
  79. package/lib/schema/manifest.js +55 -0
  80. package/lib/schema/types.d.ts +47 -2
  81. package/lib/sync/autosync-config.d.ts +73 -0
  82. package/lib/sync/autosync-config.js +89 -0
  83. package/lib/sync/autosync-scheduler.d.ts +80 -6
  84. package/lib/sync/autosync-scheduler.js +263 -40
  85. package/lib/sync/gist/gist-transport.d.ts +15 -1
  86. package/lib/sync/gist/gist-transport.js +66 -5
  87. package/lib/sync/gist/messages.d.ts +3 -0
  88. package/lib/sync/gist/messages.js +7 -0
  89. package/lib/sync/git/git-transport.d.ts +42 -3
  90. package/lib/sync/git/git-transport.js +146 -3
  91. package/lib/sync/merge.d.ts +47 -14
  92. package/lib/sync/merge.js +242 -222
  93. package/lib/sync/messages.d.ts +8 -0
  94. package/lib/sync/messages.js +19 -0
  95. package/lib/sync/risk.d.ts +19 -2
  96. package/lib/sync/risk.js +10 -3
  97. package/lib/sync/s3/messages.d.ts +6 -0
  98. package/lib/sync/s3/messages.js +13 -0
  99. package/lib/sync/s3/s3-transport.d.ts +9 -1
  100. package/lib/sync/s3/s3-transport.js +78 -6
  101. package/lib/sync/sync-engine.d.ts +193 -4
  102. package/lib/sync/sync-engine.js +450 -37
  103. package/lib/sync/sync-history.d.ts +11 -0
  104. package/lib/sync/sync-history.js +20 -0
  105. package/lib/sync/sync-state.d.ts +43 -0
  106. package/lib/sync/sync-state.js +44 -0
  107. package/lib/sync/sync-watcher.d.ts +76 -0
  108. package/lib/sync/sync-watcher.js +202 -0
  109. package/lib/sync/text-merge.d.ts +85 -0
  110. package/lib/sync/text-merge.js +513 -0
  111. package/lib/sync/transport.d.ts +48 -0
  112. package/lib/sync/transport.js +12 -0
  113. package/lib/sync/watch-scope.d.ts +38 -0
  114. package/lib/sync/watch-scope.js +95 -0
  115. package/lib/sync/webdav/webdav-transport.d.ts +16 -2
  116. package/lib/sync/webdav/webdav-transport.js +128 -11
  117. package/lib/ui/foreign-view.js +10 -0
  118. package/lib/ui/i18n.d.ts +8 -0
  119. package/lib/ui/i18n.js +20 -0
  120. package/lib/ui/rollback-view.d.ts +12 -0
  121. package/lib/ui/rollback-view.js +2 -0
  122. package/lib/ui/sync-settings-view.d.ts +47 -0
  123. package/lib/ui/sync-settings-view.js +24 -0
  124. package/lib/ui/types.d.ts +21 -0
  125. package/lib/utils/env-lock.d.ts +1 -0
  126. package/lib/utils/env-lock.js +7 -4
  127. package/package.json +6 -6
  128. package/src/adapters/credentials.ts +22 -4
  129. package/src/adapters/file-collection.ts +2 -1
  130. package/src/adapters/mcp.test.ts +235 -1
  131. package/src/adapters/mcp.ts +276 -5
  132. package/src/adapters/messages.ts +7 -0
  133. package/src/adapters/plugin-files.ts +2 -1
  134. package/src/adapters/plugins.test.ts +176 -2
  135. package/src/adapters/plugins.ts +107 -21
  136. package/src/adapters/pnpm-workspace.test.ts +89 -1
  137. package/src/adapters/pnpm-workspace.ts +127 -2
  138. package/src/adapters/prompts.ts +20 -3
  139. package/src/adapters/providers.ts +62 -4
  140. package/src/adapters/settings.ts +16 -3
  141. package/src/adapters/skills.test.ts +141 -0
  142. package/src/adapters/skills.ts +58 -2
  143. package/src/adapters/ui.ts +16 -3
  144. package/src/adapters/units-entries.test.ts +190 -0
  145. package/src/adapters/units.ts +50 -0
  146. package/src/adapters/workspaces.ts +2 -1
  147. package/src/client/about/PluginUpdateDialog.tsx +4 -2
  148. package/src/client/about/ReleaseNotesDialog.tsx +4 -2
  149. package/src/client/chat/RollbackReviewDialog.tsx +3 -2
  150. package/src/client/common/Skeleton.tsx +32 -0
  151. package/src/client/common/routes.ts +9 -0
  152. package/src/client/config-manager.module.css +321 -11
  153. package/src/client/home/HomePanel.tsx +14 -6
  154. package/src/client/import/ForeignImportView.tsx +3 -1
  155. package/src/client/import/import-wizard-steps.tsx +2 -1
  156. package/src/client/library/ArtifactRow.tsx +12 -2
  157. package/src/client/library/LibraryActions.tsx +6 -3
  158. package/src/client/library/LibraryPanel.tsx +21 -3
  159. package/src/client/library/RestorePlanView.tsx +4 -2
  160. package/src/client/locales.ts +3 -0
  161. package/src/client/recovery/RecoveryPanel.tsx +54 -7
  162. package/src/client/recovery/RollbackCard.tsx +7 -2
  163. package/src/client/recovery/RollbackDiffPane.tsx +3 -2
  164. package/src/client/recovery/recovery-locales.ts +20 -2
  165. package/src/client/recovery/recovery-view.test.ts +39 -1
  166. package/src/client/recovery/recovery-view.ts +23 -1
  167. package/src/client/run-store.test.ts +1 -1
  168. package/src/client/run-store.ts +4 -0
  169. package/src/client/sync/AutosyncCard.tsx +49 -6
  170. package/src/client/sync/MergeModal.tsx +219 -0
  171. package/src/client/sync/MergePreviewView.tsx +306 -0
  172. package/src/client/sync/SyncActivityBar.tsx +31 -0
  173. package/src/client/sync/SyncConfirmView.tsx +2 -1
  174. package/src/client/sync/SyncPanel.tsx +130 -87
  175. package/src/client/sync/SyncProbeRow.tsx +162 -0
  176. package/src/client/sync/SyncSettingsView.test.ts +27 -2
  177. package/src/client/sync/WorkDirCard.tsx +44 -6
  178. package/src/client/sync/history-model.ts +4 -1
  179. package/src/client/sync/merge-view.test.ts +234 -0
  180. package/src/client/sync/merge-view.ts +371 -0
  181. package/src/client/sync/probe-view.test.ts +90 -0
  182. package/src/client/sync/probe-view.ts +63 -0
  183. package/src/client/sync/remote-device-view.test.ts +35 -0
  184. package/src/client/sync/remote-device-view.ts +25 -0
  185. package/src/client/sync/sync-api.ts +212 -2
  186. package/src/client/sync/sync-entry.test.ts +78 -0
  187. package/src/client/sync/sync-entry.ts +53 -0
  188. package/src/client/sync/sync-locales.ts +234 -2
  189. package/src/client/sync/sync-view.test.ts +18 -1
  190. package/src/client/sync/sync-view.ts +20 -0
  191. package/src/core/backup.test.ts +41 -0
  192. package/src/core/backup.ts +20 -0
  193. package/src/core/mcp-connector-store.test.ts +265 -0
  194. package/src/core/mcp-connector-store.ts +516 -0
  195. package/src/core/messages-core.ts +4 -0
  196. package/src/core/messages.ts +46 -0
  197. package/src/core/phase3-host.ts +18 -1
  198. package/src/core/phase3-production-integration.test.ts +4 -0
  199. package/src/core/plugin-cli.test.ts +26 -0
  200. package/src/core/plugin-cli.ts +30 -4
  201. package/src/core/recovery-orchestrator.test.ts +104 -5
  202. package/src/core/recovery-orchestrator.ts +74 -17
  203. package/src/core/rollback-activity.test.ts +311 -0
  204. package/src/core/rollback-activity.ts +367 -0
  205. package/src/core/rollback-cross-session.test.ts +694 -0
  206. package/src/core/rollback-interrupted.test.ts +137 -0
  207. package/src/core/rollback-ledger.ts +32 -0
  208. package/src/core/rollback-merge.test.ts +130 -0
  209. package/src/core/rollback-merge.ts +78 -14
  210. package/src/core/rollback-point.ts +468 -91
  211. package/src/core/rollback-undo-journal.test.ts +508 -0
  212. package/src/core/rollback-undo-journal.ts +571 -0
  213. package/src/core/self-update.ts +2 -5
  214. package/src/core/text-fidelity.test.ts +189 -0
  215. package/src/core/text-fidelity.ts +197 -0
  216. package/src/core/types.ts +11 -3
  217. package/src/core/update-check.ts +2 -5
  218. package/src/core/validator.ts +14 -0
  219. package/src/foreign/bundle-origin.test.ts +265 -0
  220. package/src/foreign/bundle.ts +45 -5
  221. package/src/foreign/claude-code.test.ts +268 -0
  222. package/src/foreign/claude-code.ts +406 -25
  223. package/src/foreign/claude-plugins.test.ts +234 -0
  224. package/src/foreign/claude-sessions.test.ts +141 -0
  225. package/src/foreign/claude-sessions.ts +179 -23
  226. package/src/foreign/file-budget.test.ts +4 -1
  227. package/src/foreign/read-claude-code.test.ts +320 -0
  228. package/src/foreign/read-claude-code.ts +490 -71
  229. package/src/foreign/read-claude-plugins.ts +465 -0
  230. package/src/foreign/registry.ts +25 -2
  231. package/src/foreign/session-ir.test.ts +65 -0
  232. package/src/foreign/truth-table.test.ts +81 -0
  233. package/src/foreign/truth-table.ts +6 -3
  234. package/src/foreign/types.ts +162 -2
  235. package/src/index.facade.test.ts +26 -4
  236. package/src/index.ts +76 -19
  237. package/src/market/git-file-writer.test.ts +4 -0
  238. package/src/market/git-file-writer.ts +7 -1
  239. package/src/profiles/dsh-profile-launcher.test.ts +68 -3
  240. package/src/profiles/dsh-profile-launcher.ts +56 -1
  241. package/src/profiles/dsh-profile-shared.ts +8 -2
  242. package/src/routes/foreign.ts +8 -1
  243. package/src/routes/index.ts +1 -1
  244. package/src/routes/kit.ts +2 -2
  245. package/src/routes/sync.ts +176 -9
  246. package/src/schema/manifest-schema.test.ts +87 -2
  247. package/src/schema/manifest.ts +57 -1
  248. package/src/schema/types.ts +45 -2
  249. package/src/sync/autosync-config.test.ts +73 -1
  250. package/src/sync/autosync-config.ts +124 -0
  251. package/src/sync/autosync-risk-tier.test.ts +38 -2
  252. package/src/sync/autosync-scheduler.test.ts +264 -12
  253. package/src/sync/autosync-scheduler.ts +296 -44
  254. package/src/sync/gist/gist-conditional-write.test.ts +223 -0
  255. package/src/sync/gist/gist-transport.ts +73 -7
  256. package/src/sync/gist/messages.ts +7 -0
  257. package/src/sync/git/git-probe.test.ts +80 -0
  258. package/src/sync/git/git-transport.test.ts +185 -0
  259. package/src/sync/git/git-transport.ts +178 -5
  260. package/src/sync/merge.test.ts +188 -55
  261. package/src/sync/merge.ts +282 -224
  262. package/src/sync/messages.ts +19 -0
  263. package/src/sync/risk.ts +29 -5
  264. package/src/sync/s3/messages.ts +13 -0
  265. package/src/sync/s3/s3-conditional-write.test.ts +330 -0
  266. package/src/sync/s3/s3-transport.ts +87 -9
  267. package/src/sync/sync-device-identity.test.ts +267 -0
  268. package/src/sync/sync-engine.test.ts +379 -0
  269. package/src/sync/sync-engine.ts +535 -36
  270. package/src/sync/sync-history.test.ts +16 -1
  271. package/src/sync/sync-history.ts +26 -0
  272. package/src/sync/sync-state.test.ts +64 -0
  273. package/src/sync/sync-state.ts +79 -0
  274. package/src/sync/sync-watcher.test.ts +197 -0
  275. package/src/sync/sync-watcher.ts +246 -0
  276. package/src/sync/text-merge.test.ts +358 -0
  277. package/src/sync/text-merge.ts +554 -0
  278. package/src/sync/transport.ts +57 -0
  279. package/src/sync/watch-scope.test.ts +122 -0
  280. package/src/sync/watch-scope.ts +120 -0
  281. package/src/sync/webdav/webdav-conditional-write.test.ts +360 -0
  282. package/src/sync/webdav/webdav-transport.ts +137 -14
  283. package/src/ui/foreign-view.test.ts +34 -0
  284. package/src/ui/foreign-view.ts +10 -0
  285. package/src/ui/i18n.ts +20 -0
  286. package/src/ui/rollback-view.ts +14 -0
  287. package/src/ui/sync-settings-view.test.ts +28 -1
  288. package/src/ui/sync-settings-view.ts +43 -0
  289. package/src/ui/types.ts +22 -0
  290. package/src/utils/env-lock.ts +8 -5
package/lib/client.d.ts CHANGED
@@ -6,7 +6,6 @@ window.__ModuleLoader__.load({
6
6
 
7
7
  import { ClientContext } from "@deepseek-ai/dsh-client-runtime/client";
8
8
  import { PropsRuntime, TranslateNS } from "@deepseek-ai/dsh-client-ui-slots";
9
- //#region src/schema/types.d.ts
10
9
  /**
11
10
  * 核心领域类型(Export Schema v1 的纯类型定义)。
12
11
  *
@@ -36,6 +35,44 @@ interface EncryptionInfo {
36
35
  authTag: string;
37
36
  version: number;
38
37
  }
38
+ /**
39
+ * **外部来源包**的溯源块(manifest.foreign,2026-10-18 新增,纯 additive)。
40
+ *
41
+ * 为什么需要它:外部来源(Claude Code / Hermes / …)合成的包是**标准 bundle v1**,
42
+ * 落盘后与 DSH 自产备份**逐字同构** —— 事后无法复核「这包从哪来」。本块把来源标识、
43
+ * 读取位置、项目根、插件元数据与跳过聚合写进 manifest,供用户与界面核对。
44
+ *
45
+ * 三条纪律(与 src/foreign/types.ts 的 ForeignOrigin 同口径):
46
+ * ① **只放标识与计数,绝不放值**(凭据只有引用名,诊断只有机器码,无一字配置内容);
47
+ * ② 向后兼容:旧包没有该字段 ⇒ 缺省即合法;本字段的存在**绝不能**让旧/新包被拒;
48
+ * ③ 缺字段即「不知道」,绝不填默认值假装知道。
49
+ */
50
+ interface ManifestForeignOrigin {
51
+ /** 来源 agent id(稳定机器标识,如 claude-code / hermes;不随文案变化) */
52
+ agent: string;
53
+ /** 实际读取的位置(相对 home 的 POSIX 路径;不含任何值) */
54
+ locations?: string[];
55
+ /** 来源侧版本标记(读不到即省略) */
56
+ sourceVersion?: string;
57
+ /** 被扫描的项目根绝对路径(仅溯源,供用户核对;绝不进任何分区载荷) */
58
+ projects?: string[];
59
+ /** 插件清单(名称 / 版本 / 市场 / 来源仓库 / ref / 组件种类;**不含凭据**) */
60
+ plugins?: {
61
+ name: string;
62
+ version?: string;
63
+ marketplace?: string;
64
+ repo?: string;
65
+ ref?: string;
66
+ components?: string[];
67
+ }[];
68
+ /** 跳过与诊断汇总(机器码 + 条数,**不含任何值**) */
69
+ skipped?: {
70
+ code: string;
71
+ count: number;
72
+ }[];
73
+ /** 需要用户在目标机补录的凭据引用名(只有名字,**没有任何值**) */
74
+ credentialRefs?: string[];
75
+ }
39
76
  /** 每个导出 ZIP 根部的 manifest.json */
40
77
  interface Manifest {
41
78
  schemaVersion: number;
@@ -59,6 +96,12 @@ interface Manifest {
59
96
  * 宽容读取:非字符串/缺失一律按「未知」处理(不重定基,不报错)。
60
97
  */
61
98
  sourceHome?: string;
99
+ /**
100
+ * **外部来源包的溯源块**(见 ManifestForeignOrigin);DSH 自产备份没有该字段。
101
+ *
102
+ * 宽容读取:缺省 = 旧包(合法);存在但形状/字段类型不对 = 仅 warning(绝不因此拒绝导入)。
103
+ */
104
+ foreign?: ManifestForeignOrigin;
62
105
  sections: Record<SectionId, boolean>;
63
106
  security: {
64
107
  containsSecrets: boolean;
@@ -66,8 +109,6 @@ interface Manifest {
66
109
  encryption: EncryptionInfo | null;
67
110
  };
68
111
  }
69
- //#endregion
70
- //#region src/schema/tombstones.d.ts
71
112
  /**
72
113
  * 删除墓碑(tombstone)机制(F4):记录用户明确删除的条目,
73
114
  * 导入/恢复时据此过滤,防止「旧备份复活已删条目」。
@@ -84,8 +125,6 @@ interface Manifest {
84
125
  */
85
126
  /** 墓碑条目类型:插件 / 技能(skills 分区文件)/ 整个分区 / 其他文件(agentPresets 等文件类分区) */
86
127
  type TombstoneKind = 'plugin' | 'skill' | 'section' | 'file';
87
- //#endregion
88
- //#region src/core/types.d.ts
89
128
  interface ExportOptions {
90
129
  /** 是否包含真实秘密(必须配合 encryption 提供者;缺省 false = 只导状态) */
91
130
  includeSecrets: boolean;
@@ -569,8 +608,6 @@ interface ExportReport {
569
608
  };
570
609
  warnings: string[];
571
610
  }
572
- //#endregion
573
- //#region src/core/restore.d.ts
574
611
  type RestoreActionKind = 'hostFileRestore' | 'hostFileRemove' | 'pluginRemove' | 'fileRestore' | 'fileRemove' | 'credentialHint' | 'skip';
575
612
  interface RestoreAction {
576
613
  kind: RestoreActionKind;
@@ -650,8 +687,6 @@ interface SnapshotMeta {
650
687
  /** 置顶标记(P1-⑧):置顶快照不参与自动保留清理(最多保留 N 个时的淘汰豁免) */
651
688
  pinned?: boolean;
652
689
  }
653
- //#endregion
654
- //#region src/utils/line-diff.d.ts
655
690
  /**
656
691
  * 行级文本 diff 内核(零依赖纯函数,node 可测)。
657
692
  *
@@ -694,8 +729,6 @@ interface DiffHunk {
694
729
  newCount: number;
695
730
  lines: DiffLine[];
696
731
  }
697
- //#endregion
698
- //#region src/core/snapshot-diff.d.ts
699
732
  /** 读取 / 统计上限(常量导出供测试与 UI 文案引用同一口径)。 */
700
733
  declare const SNAPSHOT_DIFF_LIMITS: {
701
734
  /** 完整 diff:单侧参与逐行对比的字节上限(超出 → 只报体积,不逐行对比) */
@@ -777,8 +810,6 @@ interface SnapshotFileDiff {
777
810
  reason?: SnapshotFileDiffReason;
778
811
  limits: typeof SNAPSHOT_DIFF_LIMITS;
779
812
  }
780
- //#endregion
781
- //#region src/profiles/dsh-profile-shared.d.ts
782
813
  /**
783
814
  * DSH profile 的**零依赖共享层**(host 与 client 双端复用)。
784
815
  *
@@ -938,8 +969,6 @@ interface DshProfileCopyResult {
938
969
  durationMs: number;
939
970
  warnings: DshProfileCopyWarning[];
940
971
  }
941
- //#endregion
942
- //#region src/core/run-registry.d.ts
943
972
  /** run 类型:导出 / 导入 / 自动同步 / 一键同步逐项应用 / 定时备份 / 快照恢复 / 配置档案切换 / recovery 恢复。 */
944
973
  type RunKind = 'export' | 'import' | 'autosync' | 'sync-apply' | 'backup-schedule' | 'restore' | 'profile-switch' | 'recovery';
945
974
  /** run 状态:进行中 / 完成 / 失败。 */
@@ -983,8 +1012,6 @@ interface RunState {
983
1012
  createdAt: number;
984
1013
  updatedAt: number;
985
1014
  }
986
- //#endregion
987
- //#region src/core/migration-consult.d.ts
988
1015
  type ConsultSourceType = 'export-zip' | 'local-snapshot' | 'remote-snapshot';
989
1016
  type HealthVerdict = 'healthy' | 'needs-attention' | 'critical';
990
1017
  type Recommendation = 'proceed' | 'review' | 'block';
@@ -1045,8 +1072,6 @@ interface ConsultReport {
1045
1072
  };
1046
1073
  generatedAt: string;
1047
1074
  }
1048
- //#endregion
1049
- //#region src/sync/retention-policy.d.ts
1050
1075
  /**
1051
1076
  * m-retention:保留策略(GFS 分层)纯函数层。
1052
1077
  *
@@ -1081,8 +1106,6 @@ interface RetentionPolicy {
1081
1106
  /** 每年保留份数(按 UTC 日历年分组,每年至多保留最新 1 份,最多覆盖 N 年) */
1082
1107
  keepYearly: number;
1083
1108
  }
1084
- //#endregion
1085
- //#region src/sync/backup-schedule-config.d.ts
1086
1109
  /** 定时备份间隔档位(全量备份无需太频繁;默认 24h)。
1087
1110
  * - '6h' | '12h' | '24h' | '7d':固定间隔;
1088
1111
  * - 'custom':每周固定时刻(见 customSchedule)。 */
@@ -1101,8 +1124,6 @@ interface BackupWeeklySchedule {
1101
1124
  }
1102
1125
  /** 最近一次定时备份执行状态 */
1103
1126
  type BackupRunStatus = 'success' | 'skipped' | 'failed';
1104
- //#endregion
1105
- //#region src/sync/backup-scheduler.d.ts
1106
1127
  interface BackupRunResult {
1107
1128
  status: BackupRunStatus;
1108
1129
  zip?: string;
@@ -1112,8 +1133,6 @@ interface BackupRunResult {
1112
1133
  error?: string;
1113
1134
  consecutiveFailures: number;
1114
1135
  }
1115
- //#endregion
1116
- //#region src/ui/backup-schedule.d.ts
1117
1136
  /** 设置草稿(表单编辑态:总开关 + 间隔档位 + 自定义周档 + 保留策略)。 */
1118
1137
  interface BackupScheduleDraft {
1119
1138
  enabled: boolean;
@@ -1136,8 +1155,6 @@ interface BackupScheduleStatus {
1136
1155
  lastRunStatus?: BackupRunStatus;
1137
1156
  lastRunMessage?: string;
1138
1157
  }
1139
- //#endregion
1140
- //#region src/utils/shared-constants.d.ts
1141
1158
  /**
1142
1159
  * 插件自更新(POST /update-apply)的失败码(**唯一声明处**:宿主 core/self-update.ts 与
1143
1160
  * 客户端关于页弹窗共用同一份字面量)。
@@ -1180,12 +1197,8 @@ type S3CompatProvider = (typeof S3_COMPAT_PROVIDERS)[number];
1180
1197
  declare const GIST_PROVIDER: 'gist';
1181
1198
  /** Gist 通道类型 */
1182
1199
  type GistProvider = typeof GIST_PROVIDER;
1183
- //#endregion
1184
- //#region src/security/container-kind.d.ts
1185
1200
  /** 备份容器形态。 */
1186
1201
  type BackupContainerKind = 'zip' | 'encrypted';
1187
- //#endregion
1188
- //#region src/sync/backup-files.d.ts
1189
1202
  /** 备份文件来源(UI Badge 展示) */
1190
1203
  type BackupFileSource = 'auto' | 'manual';
1191
1204
  /** 备份文件元信息(列表行数据;无敏感字段) */
@@ -1210,8 +1223,6 @@ interface BackupFileMeta {
1210
1223
  */
1211
1224
  containerType?: BackupContainerKind;
1212
1225
  }
1213
- //#endregion
1214
- //#region src/core/disk-usage.d.ts
1215
1226
  /** 体检子区(顺序即报告/展示顺序:先备份产物,再缓存/暂存,末位为只读保护的附加区) */
1216
1227
  declare const DISK_USAGE_AREAS: readonly ["exports", "snapshots", "sync", "marketCache", "marketWork", "tmp", "logs", "bootState", "migrationHistory", "transactions", "locks", "vault", "rollback-points"];
1217
1228
  /** 全部体检子区 id(= `DISK_USAGE_AREAS` 的元素类型) */
@@ -1293,12 +1304,8 @@ interface DiskUsageReport {
1293
1304
  latestBackupAt: string | null;
1294
1305
  };
1295
1306
  }
1296
- //#endregion
1297
- //#region src/core/session-health.d.ts
1298
1307
  /** 严重级(数组顺序 = 由重到轻;排序与展示都用这一份)。 */
1299
1308
  type SessionHealthSeverity = 'blocksStartup' | 'unloadable' | 'nextRequestFails' | 'invisible' | 'ok';
1300
- //#endregion
1301
- //#region src/ui/session-inventory-view.d.ts
1302
1309
  /** 路由返回的一行(与宿主 session-health 的 SessionHealthRow 同构;此处只取展示所需)。 */
1303
1310
  interface SessionHealthRowView {
1304
1311
  unitId: string;
@@ -1451,8 +1458,6 @@ interface SessionRepairRollbackResult {
1451
1458
  unitId?: string;
1452
1459
  sessionId?: string;
1453
1460
  }
1454
- //#endregion
1455
- //#region src/ui/i18n.d.ts
1456
1461
  /**
1457
1462
  * 客户端展示层(src/ui/*、src/client/common/*)的渲染文案目录(zh 源语言 / en 镜像)。
1458
1463
  *
@@ -1963,6 +1968,14 @@ declare const uiZh: {
1963
1968
  readonly 'foreign.skip.legacy-rules-file': '旧式规则文件:DSH 无对等结构,只报告';
1964
1969
  readonly 'foreign.skip.instructions-merged': '多份指令源被合并为一个全局指令文件';
1965
1970
  readonly 'foreign.skip.instructions-override-selected': '命中更高优先级的指令文件(override),按它导入';
1971
+ readonly 'foreign.skip.unsupported-permissions': '权限规则(allow/ask/deny)未迁移:DSH 没有权限规则文件的对等结构,这些规则不在本包内,导入后不会生效';
1972
+ readonly 'foreign.skip.unsupported-settings-keys': 'settings.json 里其余未迁移的顶层键:只记录键名与条数,键值一律不读取,也不会写进本包';
1973
+ readonly 'foreign.skip.unsupported-agents': '.claude/agents/*.md 子代理定义未迁移:DSH 的子代理是运行时 provider 注册制,没有文件级对等结构';
1974
+ readonly 'foreign.skip.unsupported-rules': '.claude/rules/*.md(带 frontmatter 作用域)未迁移:并入全局指令会丢掉作用域,故只报告不合并';
1975
+ readonly 'foreign.skip.unsupported-plugins': 'Claude Code 插件本体未迁移:插件的 hooks / 命令靠 Claude 运行时执行,DSH 无法加载,插件代码一律不复制;插件自带的 skills 与 .mcp.json 里的 MCP 定义另行迁移';
1976
+ readonly 'foreign.skip.session-id-mismatch': '会话记录里的 sessionId 与文件名不一致:DSH 按目录名/文件名定位会话,本次以文件名为准,记录里的 id 未采用';
1977
+ readonly 'foreign.skip.mcp-server-id-conflict': '同名 MCP server 在多处出现(全局 / 项目级 / 插件):先到先得,其余同名项只报告未迁移';
1978
+ readonly 'foreign.skip.project-scan-truncated': '项目较多:项目级扫描只覆盖了上限内的项目,其余项目本次未读取,其配置不在本包内';
1966
1979
  readonly 'foreign.lossy.file-section-secrets.title': '文件类分区的明文不做剥离';
1967
1980
  readonly 'foreign.lossy.file-section-secrets.detail': '技能 / Agent 预设 / 全局指令 / 插件文件 / 历史会话 / 插件自身配置这六个文件类分区承载的是原始文件内容:命中的明文原样进包(导入侧只报告、不改写;本页的产包路径连扫描都不做)。「默认不含秘密」只对结构化分区成立,对这类分区不成立 —— 需要保密请先清理源文件。';
1968
1981
  readonly 'foreign.lossy.entry-backslash.title': '条目名中段反斜杠:跨平台落点可能不同';
@@ -2004,8 +2017,6 @@ declare const uiZh: {
2004
2017
  type UiTextKey = keyof typeof uiZh;
2005
2018
  /** UI 翻译函数:key → 当前语言文案({param} 插值;未知键回退 zh/键名)。 */
2006
2019
  type UiT = (key: UiTextKey, params?: Record<string, string | number>) => string;
2007
- //#endregion
2008
- //#region src/ui/types.d.ts
2009
2020
  /**
2010
2021
  * GET /update-check 的结果。
2011
2022
  *
@@ -2085,6 +2096,22 @@ interface RecoveryIncident {
2085
2096
  reason: string;
2086
2097
  createdAt: string;
2087
2098
  }
2099
+ /**
2100
+ * 正在**正常执行中**的操作(GET /recovery/status 的 `live`,加法字段)。
2101
+ *
2102
+ * 与 `incidents` 互斥:同一条 active journal 要么是「正在跑」(GLOBAL 锁由它持有、
2103
+ * 且 journal.ownerInstanceId 与锁持有者一致),要么是「一次未正常完成的操作」。
2104
+ * 判别只发生在宿主侧(single source = recovery-orchestrator 的 isLiveInFlight),
2105
+ * 客户端只负责如实展示。
2106
+ *
2107
+ * 旧宿主不返回 → undefined(面板按「无进行中操作」处理)。
2108
+ */
2109
+ interface RecoveryActiveOperation {
2110
+ operationId: string;
2111
+ operationType: string;
2112
+ state: string;
2113
+ startedAt: string;
2114
+ }
2088
2115
  /** GET /recovery/status 响应。 */
2089
2116
  interface RecoveryStatus {
2090
2117
  incidents: RecoveryIncident[];
@@ -2092,6 +2119,11 @@ interface RecoveryStatus {
2092
2119
  runId: string;
2093
2120
  status: string;
2094
2121
  }[];
2122
+ /**
2123
+ * 正在正常执行的操作(不是 incident)。用途:面板要能解释「为什么现在什么都点不动」——
2124
+ * 此前这类操作被误报成事故,「执行恢复」永久灰、放弃恢复一直 423,用户拿不到任何原因。
2125
+ */
2126
+ live?: RecoveryActiveOperation[];
2095
2127
  /**
2096
2128
  * 环境锁状态摘要(issue #31)。纯残留锁**不是** journal:进程在 op 期间被杀时
2097
2129
  * `journalId: null`、`transactions/active/` 为空,incidents 恒为 [],而 423 文案却
@@ -2270,8 +2302,6 @@ interface RecoveryPort {
2270
2302
  /** POST /recovery/sessions/rollback(T8):按台账里的 repairId 回滚一次修复(客户端不传路径)。 */
2271
2303
  rollbackSessionRepair(repairId: string): Promise<SessionRepairRollbackResult>;
2272
2304
  }
2273
- //#endregion
2274
- //#region src/client/session-export/session-export-view.d.ts
2275
2305
  /**
2276
2306
  * 「下载原始日志 (ZIP)」入口的**纯展示模型**(F-2,框架无关、node 可测)。
2277
2307
  *
@@ -2303,8 +2333,6 @@ interface SessionExportProbe {
2303
2333
  /** 探测时刻(ISO) */
2304
2334
  checkedAt: string;
2305
2335
  }
2306
- //#endregion
2307
- //#region src/foreign/types.d.ts
2308
2336
  /** 未能迁移的外部内容(响亮失败:宁可在计划里报出来,也不静默丢) */
2309
2337
  interface ForeignSkip {
2310
2338
  /** 稳定机器码(UI 用它映射文案;禁止渲染裸枚举) */
@@ -2381,9 +2409,23 @@ type ForeignSkipCode =
2381
2409
  * 该来源**没有自动根**(竞品 `defaultRoots.chatgpt = null`)—— 必须由用户显式给出导出文件
2382
2410
  * 路径;本机自动探测永远不会命中,如实报码而不是假装「未安装」。
2383
2411
  */
2384
- 'source-needs-explicit-path';
2385
- //#endregion
2386
- //#region src/ui/foreign-view.d.ts
2412
+ 'source-needs-explicit-path' |
2413
+ /** settings.json 的 permissions(allow/ask/deny):DSH 无权限规则文件对等结构,只报告条数 */
2414
+ 'unsupported-permissions' |
2415
+ /** settings.json 里其余未迁移的顶层键(只记键名与条数,**值一律不读**) */
2416
+ 'unsupported-settings-keys' |
2417
+ /** .claude/agents/*.md 子代理定义:DSH 的 subagent 是运行时 provider 注册制,无文件级对等结构 */
2418
+ 'unsupported-agents' |
2419
+ /** .claude/rules/*.md 带 frontmatter 作用域:合并进全局指令会丢作用域,故只报告 */
2420
+ 'unsupported-rules' |
2421
+ /** Claude Code 插件本体(插件 API / hooks / commands 的执行面):DSH 无法加载,**绝不复制其代码** */
2422
+ 'unsupported-plugins' |
2423
+ /** 会话记录里的 sessionId 与文件名 stem 不一致(DSH 以目录/文件名定位会话,故以文件名为准并如实报码) */
2424
+ 'session-id-mismatch' |
2425
+ /** 同名 MCP server 在多处出现(全局 / 项目级 / 插件):先到先得,其余只报告 */
2426
+ 'mcp-server-id-conflict' |
2427
+ /** 项目级扫描触顶(maxProjects):**不静默**,如实报码 */
2428
+ 'project-scan-truncated';
2387
2429
  /** `GET /foreign-sources` 返回的一条来源检测结果(与宿主 ForeignSourceStatus 同构) */
2388
2430
  interface ForeignSourceStatusInput {
2389
2431
  id: string;
@@ -2400,8 +2442,6 @@ interface ForeignSourcesResponse$1 {
2400
2442
  projectScoped?: boolean;
2401
2443
  sources: readonly ForeignSourceStatusInput[];
2402
2444
  }
2403
- //#endregion
2404
- //#region src/client/common/http.d.ts
2405
2445
  /** 携带路由 JSON error 消息的错误类型(客户端所有请求错误的唯一类型)。 */
2406
2446
  declare class ConfigManagerApiError extends Error {
2407
2447
  /**
@@ -2416,8 +2456,6 @@ declare class ConfigManagerApiError extends Error {
2416
2456
  readonly code?: string;
2417
2457
  constructor(message: string, status?: number, code?: string);
2418
2458
  }
2419
- //#endregion
2420
- //#region src/client/api.d.ts
2421
2459
  /** Host 半健康检查响应(plugin 版本 / DSH 版本 / 平台,用于主页横幅与兼容性说明) */
2422
2460
  interface ServiceStatus {
2423
2461
  ready: boolean;
@@ -2877,8 +2915,6 @@ declare class ConfigManagerApi {
2877
2915
  * 返回分析 + 与当前配置的差异计划摘要("装/导这个备份会动你什么")。 */
2878
2916
  inspectBackup(zipPath: string): Promise<BackupInspectResult>;
2879
2917
  }
2880
- //#endregion
2881
- //#region src/sync/sync-engine.d.ts
2882
2918
  interface SyncPushReport {
2883
2919
  ok: boolean;
2884
2920
  snapshotId: string;
@@ -2887,6 +2923,12 @@ interface SyncPushReport {
2887
2923
  /** 分区级告警(单项失败不拖垮整体,§34.17 语义) */
2888
2924
  warnings: string[];
2889
2925
  message?: string;
2926
+ /**
2927
+ * 本次推送**被前置检测拒绝**(远端已被其它设备推进):未写远端、未记基线、未改 sync-state。
2928
+ * 这是「需要先合并远端」的冲突态,不是通道/凭据故障 —— 调用方(自动同步 / 路由)应按冲突处理,
2929
+ * 而不是记成「同步失败」。
2930
+ */
2931
+ conflict?: boolean;
2890
2932
  }
2891
2933
  /** 差异报告中的单个变更项(PlanItem 摘要,不含敏感细节) */
2892
2934
  interface PullChange {
@@ -2927,8 +2969,6 @@ interface SyncPushPreview {
2927
2969
  credentialsIncluded: boolean;
2928
2970
  message?: string;
2929
2971
  }
2930
- //#endregion
2931
- //#region src/sync/sync-config.d.ts
2932
2972
  /** 同步通道类型(由 SYNC_CHANNELS 派生;host 侧与 client 半统一引用)。 */
2933
2973
  type SyncTransportType$1 = (typeof SYNC_CHANNELS)[number];
2934
2974
  /** S3 兼容系通道的回传视图:**只带 secretStored 标记,绝不带密钥值**。 */
@@ -2951,8 +2991,6 @@ interface CloudGistChannelView {
2951
2991
  filePrefix: string;
2952
2992
  secretStored: boolean;
2953
2993
  }
2954
- //#endregion
2955
- //#region src/client/sync/sync-api.d.ts
2956
2994
  /**
2957
2995
  * 远程同步通道类型:git(默认)或 webdav。
2958
2996
  * **唯一来源** = 宿主 src/sync/sync-config.ts 的 SYNC_CHANNELS(此处仅 type-only 别名:
@@ -2962,6 +3000,11 @@ type SyncTransportType = SyncTransportType$1;
2962
3000
  /** GET /sync/status 响应:配置/凭据/上次同步的只读事实(无任何 secret 值) */
2963
3001
  interface SyncStatusResponse {
2964
3002
  ok: boolean;
3003
+ /**
3004
+ * 方案 A:是否存在同步基线(本地祖先指针;宿主只回布尔,绝不回快照 id)。
3005
+ * **缺省 undefined = 未知 → 一律按「无基准」处理**,走老导入确认路径(fail-safe)。
3006
+ */
3007
+ hasBaseline?: boolean;
2965
3008
  /** 是否已保存过仓库/通道配置(sync-config.json;任一通道配置过即为 true) */
2966
3009
  configured: boolean;
2967
3010
  /** git 通道:已配置的仓库地址(不含 token,可回显;与当前通道无关,配置过即返回) */
@@ -3030,6 +3073,8 @@ interface SyncWorkDirFacts {
3030
3073
  ahead: number | null;
3031
3074
  /** 工作树是否有未提交改动(仅 detail 自检时给出,否则 null) */
3032
3075
  dirty: boolean | null;
3076
+ /** 远端分支上的快照数(仅 detail 自检时给出,否则 null;issue #104 建议 3) */
3077
+ remoteSnapshots: number | null;
3033
3078
  }
3034
3079
  /** 同步密码的保存状态(只回布尔;密码值永不回传浏览器)。 */
3035
3080
  interface SyncPasswordState {
@@ -3188,6 +3233,37 @@ interface SyncPullPayload extends SyncPushPayload {
3188
3233
  /** 解密密码(拉取/一键同步遇到加密快照时提供;仅内存传输,绝不落盘) */
3189
3234
  decryptPassword?: string;
3190
3235
  }
3236
+ /**
3237
+ * POST /sync/probe 结果。
3238
+ *
3239
+ * **失败也是正常返回**(HTTP 200 + \`ok:false\`):测试连接是**预期会失败**的诊断动作,
3240
+ * 用 5xx 表达会被界面当成基础设施崩溃。\`message\` / \`hint\` 由通道层本地化并脱敏后原样带回。
3241
+ */
3242
+ interface SyncProbeSuccess {
3243
+ ok: true;
3244
+ transport: string;
3245
+ /** 结论(可直接展示的成功文案) */
3246
+ message: string;
3247
+ /** 附加提醒(例如「该 S3 兼容端点应把 region 填成 xxx」),有值时界面按 warn 级展示 */
3248
+ hint?: string;
3249
+ /** 远端已有快照数(取得时回传) */
3250
+ snapshotCount?: number;
3251
+ /** 自检过程中**自动创建**的远端目录(webdav 幂等 MKCOL;界面须逐条说明,绝不静默写远端) */
3252
+ createdCollections?: string[];
3253
+ }
3254
+ /** 自检失败(诊断动作的预期结果,不是异常) */
3255
+ interface SyncProbeFailure {
3256
+ ok: false;
3257
+ error: string;
3258
+ /**
3259
+ * **能力边界标记**:该通道不提供连通性自检(传输层未实现 probe)。
3260
+ *
3261
+ * 与故障**严格区分**:true = 这个通道没有这项能力(中性提示,同步功能不受影响);
3262
+ * 缺省/undefined = 真的没连通(按故障展示)。界面据此选 info 而不是「操作失败」。
3263
+ */
3264
+ unsupported?: boolean;
3265
+ }
3266
+ type SyncProbeResult = SyncProbeSuccess | SyncProbeFailure;
3191
3267
  /** GET /sync/snapshots-list 响应:远端历史快照列表(按 createdAt 倒序)。 */
3192
3268
  interface SyncSnapshotsListResponse {
3193
3269
  ok: boolean;
@@ -3213,6 +3289,14 @@ interface SyncSnapshotLite {
3213
3289
  sectionCount: number;
3214
3290
  platform: string;
3215
3291
  dshVersion: string;
3292
+ /**
3293
+ * cloud-sync 借鉴项 ⑥:推送方设备身份(宿主从快照 manifest 读出)。
3294
+ * **旧快照没有这两个字段** —— 界面必须据此不显示设备行,绝不把 undefined 渲染成文案、
3295
+ * 也不显示空串占位。
3296
+ */
3297
+ deviceName?: string;
3298
+ /** 稳定设备 id(换主机名/改机器名都不变;用于认出「同一台设备」)。 */
3299
+ deviceId?: string;
3216
3300
  }
3217
3301
  /** POST /sync/sync 请求体(一键同步第一步:拉取 → 差异确认会话)。 */
3218
3302
  interface SyncStartPayload extends SyncPushPayload {
@@ -3343,14 +3427,117 @@ interface SyncRollbackFailedItem {
3343
3427
  reason: string;
3344
3428
  manualHint?: string;
3345
3429
  }
3430
+ /**
3431
+ * 合并冲突成因(对齐宿主 src/sync/merge.ts 的 MergeConflictReason)。
3432
+ * 未在本联合里的字符串照样可能从宿主回传 —— 界面侧一律经 merge-view.ts 的
3433
+ * mergeReasonKey() 映射,未知值按 both-modified 措辞,**绝不渲染裸枚举**。
3434
+ */
3435
+ type MergeConflictReason = 'both-modified' | 'modify-delete' | 'delete-modify' | 'no-ancestor' | 'binary' | 'format' | 'array' | 'section';
3436
+ /** 分区级合并决策('conflict' = 双侧改动重叠,必须由用户裁决)。 */
3437
+ type MergeSectionDecision = 'useRemote' | 'keepLocal' | 'merge' | 'skip' | 'conflict';
3438
+ /** 单条冲突的三列预览(已由宿主脱敏/序列化,界面负责截断)。 */
3439
+ interface MergePreviewConflict {
3440
+ /** 冲突位置:JSON 分区是 top-level key;FilesSection 是 relativePath。 */
3441
+ path: string;
3442
+ kind: 'key' | 'file';
3443
+ reason?: MergeConflictReason;
3444
+ localPreview: string;
3445
+ remotePreview: string;
3446
+ ancestorPreview: string;
3447
+ }
3448
+ /** 单个分区的合并预览。 */
3449
+ interface MergePreviewSection {
3450
+ id: SectionId;
3451
+ decision: MergeSectionDecision;
3452
+ /** 自动合并并入的变更点数量(仅自动合并成功时有意义) */
3453
+ autoMerged?: number;
3454
+ conflictCount: number;
3455
+ conflicts: MergePreviewConflict[];
3456
+ }
3457
+ /** 预览摘要(可自动应用 / 待裁决 / 冲突条目 / 无变化)。 */
3458
+ interface MergePreviewSummary {
3459
+ auto: number;
3460
+ review: number;
3461
+ conflicts: number;
3462
+ skipped: number;
3463
+ }
3464
+ /** POST /sync/merge-preview 请求体(只读;密码仅内存传输,绝不落盘/落日志)。 */
3465
+ interface MergePreviewPayload {
3466
+ /** 远端快照 id;缺省 = 最新 */
3467
+ snapshotId?: string;
3468
+ /** 解密密码(仅当远端快照加密时使用;缺省 = 已保存的 DECRYPT 凭据) */
3469
+ decryptPassword?: string;
3470
+ /** 跨机路径映射(与一键同步同一口径) */
3471
+ pathMappings?: PathMapping[];
3472
+ }
3473
+ /** POST /sync/merge-preview 响应(只读三方合并结果)。 */
3474
+ interface MergePreviewResponse {
3475
+ ok: boolean;
3476
+ snapshotId: string;
3477
+ /** 是否存在共同基准快照(false = 退化为两方比较,双侧不一致一律按冲突) */
3478
+ hasAncestor: boolean;
3479
+ sections: MergePreviewSection[];
3480
+ summary: MergePreviewSummary;
3481
+ /** 失败/降级原因(仅在 ok=false 等场景出现) */
3482
+ message?: string;
3483
+ }
3484
+ /** 单条裁决动作。 */
3485
+ type MergeResolutionActionWire = 'keepLocal' | 'useRemote' | 'useMerged' | 'skip';
3486
+ /** 单条裁决:id = 分区 id(分区级)或 `分区id::冲突路径`(冲突级,见 merge-view.ts)。 */
3487
+ interface MergeResolution {
3488
+ id: string;
3489
+ action: MergeResolutionActionWire;
3490
+ }
3491
+ /** POST /sync/apply-merge 请求体(写动作;过 mutation gate)。 */
3492
+ interface MergeApplyPayload extends MergePreviewPayload {
3493
+ resolutions: MergeResolution[];
3494
+ }
3495
+ /** POST /sync/apply-merge 响应(字段与 /sync/apply-items 同风格 + pendingConflicts)。 */
3496
+ interface MergeApplyResponse {
3497
+ ok: boolean;
3498
+ applied: string[];
3499
+ skipped: string[];
3500
+ needsRestart?: boolean;
3501
+ warnings: string[];
3502
+ /** 执行前快照 id(界面一键回滚用) */
3503
+ restoreId?: string;
3504
+ /** 任一失败是否整体回滚 */
3505
+ rolledBack?: boolean;
3506
+ /** 整体回滚是否完整(false = 有项未恢复,见 warnings;缺省 = 旧宿主未回传) */
3507
+ rollbackFull?: boolean;
3508
+ /** 执行后仍待裁决的分区(下次同步仍会出现) */
3509
+ pendingConflicts: SectionId[];
3510
+ failed?: {
3511
+ itemId: string;
3512
+ message?: string;
3513
+ }[];
3514
+ ineffective?: {
3515
+ itemId: string;
3516
+ adapter: string;
3517
+ message?: string;
3518
+ }[];
3519
+ historyWriteError?: string;
3520
+ }
3346
3521
  /** 统一间隔类型。 */
3347
3522
  type AutosyncInterval = '5m' | '15m' | '30m' | '60m' | '6h' | '12h' | '24h';
3348
3523
  /** 最近一次自动同步执行状态。 */
3349
3524
  type AutosyncRunStatus = 'success' | 'skipped' | 'failed' | 'partial';
3525
+ /** 自动应用的最高风险等级(low = 只自动落低风险分区;medium = plugins/mcp 也自动落盘)。 */
3526
+ type AutosyncAutoApplyTier = 'low' | 'medium';
3527
+ /** 双侧都改(真冲突)时的策略(ask = 保留冲突待人工裁决;local = 保留本机并推上去)。 */
3528
+ type AutosyncConflictPolicy = 'ask' | 'local';
3350
3529
  /** GET/POST /sync/autosync 响应:自动同步状态。 */
3351
3530
  interface AutosyncStatusResponse {
3352
3531
  enabled: boolean;
3353
3532
  interval: AutosyncInterval;
3533
+ /** 真·自动同步:本地改动即时触发(缺省 true;host 读取层已补缺省) */
3534
+ realtime?: boolean;
3535
+ /** realtime 下的远端轮询间隔(ms;缺省 60000) */
3536
+ remoteCheckMs?: number;
3537
+ /** 自动应用的最高风险等级(缺省 medium:plugins/mcp 也自动落盘) */
3538
+ autoApplyTier?: AutosyncAutoApplyTier;
3539
+ /** 双侧都改时的策略(缺省 local:保留本机并推上去) */
3540
+ conflictPolicy?: AutosyncConflictPolicy;
3354
3541
  lastRunAt?: string;
3355
3542
  lastRunStatus?: AutosyncRunStatus;
3356
3543
  lastRunMessage?: string;
@@ -3374,6 +3561,14 @@ interface AutosyncUpdatePayload {
3374
3561
  enabled: boolean;
3375
3562
  interval?: AutosyncInterval;
3376
3563
  startupMinIntervalMs?: number;
3564
+ /** 本地改动即时触发(缺省 true) */
3565
+ realtime?: boolean;
3566
+ /** realtime 下的远端轮询间隔(ms;宿主 clamp 到 15s–1h) */
3567
+ remoteCheckMs?: number;
3568
+ /** 自动应用等级(缺省 medium) */
3569
+ autoApplyTier?: AutosyncAutoApplyTier;
3570
+ /** 冲突策略(缺省 local) */
3571
+ conflictPolicy?: AutosyncConflictPolicy;
3377
3572
  }
3378
3573
  /** 自动同步执行记录(§3.7 AutosyncHistoryEntry)。 */
3379
3574
  interface AutosyncHistoryEntry {
@@ -3487,12 +3682,14 @@ declare class SyncApi {
3487
3682
  * 重建 git 工作副本(issue #79 的自救入口)。
3488
3683
  *
3489
3684
  * - `relink`:只把 origin / push URL 重指向当前配置地址(非破坏性,不碰工作树与本地提交);
3685
+ * - `adopt`:把当前地址的远端历史合并进工作副本(issue #104:换仓库 / 远端历史被重写后两条历史
3686
+ * 不相交,pull --ff-only 永远失败)。不改写本地提交、可 `git revert`,冲突由 host 自动 `merge --abort`;
3490
3687
  * - `reclone`:删除工作副本后重新 clone(**丢弃未上行的本地提交**)→ 必须带 `confirm: true`。
3491
3688
  *
3492
3689
  * 写动作:host 侧过 mutation gate(SAFE MODE / 环境锁)。
3493
3690
  */
3494
3691
  workdirReset(payload: {
3495
- mode: 'relink' | 'reclone';
3692
+ mode: 'relink' | 'adopt' | 'reclone';
3496
3693
  confirm?: boolean;
3497
3694
  }): Promise<{
3498
3695
  ok: boolean;
@@ -3501,6 +3698,13 @@ declare class SyncApi {
3501
3698
  facts: SyncWorkDirFacts;
3502
3699
  };
3503
3700
  }>;
3701
+ /**
3702
+ * cloud-sync 借鉴项 ②:连通性自检(**只读**)。
3703
+ *
3704
+ * 失败回 \`ok:false\` 而非抛错 —— 调用方必须按 \`result.ok\` 分流,把失败当**结论**展示,
3705
+ * 不要落进 catch(否则「连不上」会被渲染成崩溃)。
3706
+ */
3707
+ probe(payload: SyncPushPayload): Promise<SyncProbeResult>;
3504
3708
  /**
3505
3709
  * 分区条目清单(复用 /export-preview;**只读**,不写任何内容)。
3506
3710
  *
@@ -3597,6 +3801,20 @@ declare class SyncApi {
3597
3801
  rollback(payload: {
3598
3802
  restoreId: string;
3599
3803
  }): Promise<SyncRollbackResponse>;
3804
+ /**
3805
+ * T-ui-merge:远程合并**只读**预览(三方合并 + 冲突清单 + 摘要),零写入。
3806
+ *
3807
+ * 与 /sync/sync 的区别:这里不做导入计划、不登记同步会话,只回答「远端与本地差在哪、
3808
+ * 哪些分区需要我裁决」;密码只在请求体内传输(宿主绝不回传/落日志)。
3809
+ */
3810
+ mergePreview(payload?: MergePreviewPayload): Promise<MergePreviewResponse>;
3811
+ /**
3812
+ * T-ui-merge:按逐项裁决执行合并(写动作,宿主侧过 mutation gate)。
3813
+ *
3814
+ * 返回 pendingConflicts = 执行后**仍**待裁决的分区:界面据此告诉用户
3815
+ * 「跳过 ≠ 已解决,下次同步仍会出现」,而不是把一次带 skip 的执行报成「已解决」。
3816
+ */
3817
+ applyMerge(payload: MergeApplyPayload): Promise<MergeApplyResponse>;
3600
3818
  /** Phase 7 迁移前咨询(只读健康评分 + 建议):对远端快照生成咨询报告。 */
3601
3819
  consult(input: {
3602
3820
  type: 'remote-snapshot';
@@ -3604,8 +3822,6 @@ declare class SyncApi {
3604
3822
  snapshotId?: string;
3605
3823
  }): Promise<ConsultReport>;
3606
3824
  }
3607
- //#endregion
3608
- //#region src/market/types.d.ts
3609
3825
  /**
3610
3826
  * 发布模式(F6 迁移/分享双模式,借鉴 dsh-packer config.personalPatterns 同源设计):
3611
3827
  * - 'migrate'(缺省):迁移模式,同一份数据全带(只受 BANNED 分区与字面量凭据扫描约束);
@@ -3749,8 +3965,6 @@ interface MarketPrepareResponse {
3749
3965
  /** 供应链警示(恒生成:发布即公开、未经审核) */
3750
3966
  warnings: string[];
3751
3967
  }
3752
- //#endregion
3753
- //#region src/client/market/market-api.d.ts
3754
3968
  /** 配置市场浏览器半数据入口(备份与迁移页第 5 个 tab 的注入业务面) */
3755
3969
  declare class MarketApi {
3756
3970
  readonly t: UiT;
@@ -3773,8 +3987,6 @@ declare class MarketApi {
3773
3987
  /** 发布包下载 URL(受控临时区 zip;经宿主 /download 端点,无凭据、无写操作) */
3774
3988
  downloadPublishUrl(zipPath: string): string;
3775
3989
  }
3776
- //#endregion
3777
- //#region src/market/my-repo.d.ts
3778
3990
  /** 条目收录状态:未收录(本地独有)| PR 待审核(带 PR 链接)| 已收录(官方市场 index 含该 id) */
3779
3991
  type MyItemStatus = 'not-listed' | 'pr-pending' | 'listed';
3780
3992
  /** 上传表单:仅用户填写的描述性内容;id/author/version/updatedAt/repoUrl 全自动 */
@@ -3865,8 +4077,6 @@ interface MyItemEntry {
3865
4077
  /** 用户公开仓库(<login>/dsh-configs)的 star 数(仓库级;undefined = 无数据) */
3866
4078
  stars?: number;
3867
4079
  }
3868
- //#endregion
3869
- //#region src/client/market/my-configs-api.d.ts
3870
4080
  /**
3871
4081
  * POST /me/status 响应:登录态 + 用户配置仓库状态(设计文档 §4.2)。
3872
4082
  * 仅非敏感展示位:login 用户名可回显;token 值永不回传浏览器。
@@ -3926,8 +4136,6 @@ declare class MyConfigsApi {
3926
4136
  /** 删除条目(同步删本地索引+文件;已收录自动后台提下架 PR;待审核自动关闭收录 PR) */
3927
4137
  meDelete(itemId: string): Promise<DeleteResult>;
3928
4138
  }
3929
- //#endregion
3930
- //#region src/core/session-repair.d.ts
3931
4139
  /** 单条会话的修复原因(机器可读;文案由 CLI 输出层决定)。 */
3932
4140
  type SessionRepairReason =
3933
4141
  /** header 里没有 cwd(DSH 的 _no-cwd 会话):无法判定目标目录 */
@@ -3969,8 +4177,6 @@ interface SessionRepairSummary {
3969
4177
  /** 受影响的重复 id 条数(同一 id 的多份只算一次) */
3970
4178
  duplicates: number;
3971
4179
  }
3972
- //#endregion
3973
- //#region src/ui/session-layout-view.d.ts
3974
4180
  /** E1 计划里的一条动作(**不含绝对路径**:身份 = `<fromProjectKey>/<sessionId>`)。 */
3975
4181
  interface SessionLayoutPlanItemView {
3976
4182
  unitId: string;
@@ -4025,8 +4231,6 @@ interface SessionLayoutApplyView {
4025
4231
  * 判别:执行结果带 `results` 数组,计划带 `actions`/`needsKeep`。
4026
4232
  */
4027
4233
  type SessionLayoutResponse = SessionLayoutPlanView | SessionLayoutApplyView;
4028
- //#endregion
4029
- //#region src/ui/rollback-view.d.ts
4030
4234
  /** 只保留两态(S2):工作区 + 会话。 */
4031
4235
  declare const ROLLBACK_STATES: readonly ['workspace', 'session'];
4032
4236
  type RollbackState = (typeof ROLLBACK_STATES)[number];
@@ -4364,6 +4568,12 @@ interface RollbackSegmentResult {
4364
4568
  /** 无法安全撤销 ⇒ 未写(宿主回传才有) */
4365
4569
  unavailableCount?: number;
4366
4570
  unavailablePaths?: string[];
4571
+ /**
4572
+ * **落点无人认领**(时间窗证据表明那一刻没有任何会话活跃:手改 / 外部工具 / 另一个进程)
4573
+ * ⇒ 未写(宿主回传才有)。与 unavailableCount 分开:成因不同,用户要做的事也不同。
4574
+ */
4575
+ externalCount?: number;
4576
+ externalPaths?: string[];
4367
4577
  /** 写入前发现又被改过(并发)⇒ 未写(宿主回传才有) */
4368
4578
  concurrentCount?: number;
4369
4579
  concurrentPaths?: string[];
@@ -4440,8 +4650,6 @@ interface RollbackPointPort {
4440
4650
  includeGuards: boolean;
4441
4651
  }): Promise<RollbackPurgeResult>;
4442
4652
  }
4443
- //#endregion
4444
- //#region src/client/recovery/recovery-api.d.ts
4445
4653
  /** Recovery 浏览器半数据入口(实现 RecoveryPort 契约 + rollback-points 族)。 */
4446
4654
  declare class RecoveryApi implements RecoveryPort, RollbackPointPort {
4447
4655
  readonly t: UiT;
@@ -4573,8 +4781,6 @@ declare class RecoveryApi implements RecoveryPort, RollbackPointPort {
4573
4781
  */
4574
4782
  clearSafeMode(userConfirmed: boolean): Promise<RecoverySafeModeClearResult>;
4575
4783
  }
4576
- //#endregion
4577
- //#region src/core/migration-history.d.ts
4578
4784
  /** 合法 kind 集合(§5 COMPLETE 清单 + 评审补 'profile-import')。 */
4579
4785
  declare const MIGRATION_KINDS: readonly ['import', 'restore', 'rollback', 'profile-create', 'profile-select', 'profile-switch', 'profile-delete', 'profile-rename', 'profile-save', 'profile-import', 'sync-apply', 'autosync', 'recovery', 'backup', 'backup-manual', 'snapshot-delete', 'snapshot-prune'];
4580
4786
  /** §5 覆盖的操作 kind(COMPLETE 不变量;常量枚举,天然非敏感)。 */
@@ -4619,8 +4825,6 @@ interface MigrationHistoryStats {
4619
4825
  byKind: Partial<Record<MigrationKind, number>>;
4620
4826
  byResult: Partial<Record<MigrationResult, number>>;
4621
4827
  }
4622
- //#endregion
4623
- //#region src/client/history/history-api.d.ts
4624
4828
  /** 列表查询返回体。 */
4625
4829
  interface HistoryListResult {
4626
4830
  ok: boolean;
@@ -4660,8 +4864,6 @@ declare class HistoryApi {
4660
4864
  }>;
4661
4865
  private buildExportUrl;
4662
4866
  }
4663
- //#endregion
4664
- //#region src/client/recovery/incident-api.d.ts
4665
4867
  /** 崩溃归因分类(与 core/crash-report.ts 的 CrashKind 同构)。 */
4666
4868
  type CrashKind = 'session-corrupt' | 'bundle-check' | 'patch-tree' | 'unknown';
4667
4869
  /** 建议动作(与 core/crash-report.ts 的 CrashAdvice 同构)。 */
@@ -4709,8 +4911,6 @@ declare class IncidentApi {
4709
4911
  /** POST /rescue {action:off}:退出救援模式(从备份完整还原)。 */
4710
4912
  rescueOff(): Promise<RescueActionResult>;
4711
4913
  }
4712
- //#endregion
4713
- //#region src/client/client-types.d.ts
4714
4914
  /** 本插件 Client 半的注入业务面:每个 settings.section 注册项都拿到同一个 api 实例 */
4715
4915
  interface ConfigManagerSectionInjected {
4716
4916
  api: ConfigManagerApi;
@@ -4740,8 +4940,6 @@ interface ConfigManagerSectionInjected {
4740
4940
  */
4741
4941
  uiT: UiT;
4742
4942
  }
4743
- //#endregion
4744
- //#region src/client/locales.d.ts
4745
4943
  /**
4746
4944
  * Config Manager 表面文案:zh 为源语言,en 镜像每个键。
4747
4945
  * 字典 namespace 由 client/index.ts 注册(declare module 合并进 LocaleNamespaceMap)。
@@ -5521,6 +5719,7 @@ declare const zh$4: {
5521
5719
  readonly 'library.kind.snapshot': '本机快照';
5522
5720
  readonly 'library.kind.backupFile': '备份文件';
5523
5721
  readonly 'library.kind.remote': '远端快照';
5722
+ readonly 'library.remoteDevice': '由 {device} 推送';
5524
5723
  readonly 'library.kind.market': '市场配置';
5525
5724
  readonly 'library.title': '产物库';
5526
5725
  readonly 'library.refresh': '刷新';
@@ -5647,8 +5846,6 @@ declare const zh$4: {
5647
5846
  };
5648
5847
  /** 字典键联合(注册处 compile-time 校验) */
5649
5848
  type ConfigManagerKey = keyof typeof zh$4;
5650
- //#endregion
5651
- //#region src/client/sync/sync-locales.d.ts
5652
5849
  /**
5653
5850
  * 远程同步设置区块(config-manager-sync)表面文案:zh 为源语言,en 镜像每个键。
5654
5851
  * 独立命名空间、独立文件:不触碰共享的 locales.ts(并行会话已改),零冲突。
@@ -5696,11 +5893,18 @@ declare const zh$3: {
5696
5893
  readonly 'workdir.missing': '尚未创建(首次同步时克隆)';
5697
5894
  readonly 'workdir.unknown': '读不出工作副本状态';
5698
5895
  readonly 'workdir.relink': '重指向仓库地址';
5896
+ readonly 'workdir.adopt': '采纳远端历史';
5897
+ readonly 'workdir.adoptHint': '把远端的提交历史合并进本机工作副本(用于「换了仓库或远端历史被重写」后无法合并的情况)。不会改写本地提交,合并后可 git revert 撤销;一旦冲突会自动撤销这次合并,工作副本回到操作前。';
5699
5898
  readonly 'workdir.reclone': '重新克隆工作副本';
5700
5899
  readonly 'workdir.recloneConfirmTitle': '重新克隆工作副本?';
5701
5900
  readonly 'workdir.recloneConfirmMessage': '将删除本机工作副本目录并从远端重新克隆。本机配置与远端快照都不受影响,但工作副本里尚未推送的本地提交会被丢弃 —— 需要时请先在同步页执行一次推送。';
5702
5901
  readonly 'workdir.recloneConfirm': '重新克隆';
5902
+ readonly 'workdir.ahead': '未上传的本地提交';
5903
+ readonly 'workdir.remoteSnapshots': '远端快照数';
5904
+ readonly 'workdir.backlogAhead': '有本地提交还没上传到远端';
5905
+ readonly 'workdir.backlogNeverSynced': '本地领先,但远端从未收到过快照 —— 这条通道可能一直没在真正备份';
5703
5906
  readonly 'toast.workdirRelinked': '工作副本已重指向当前仓库地址';
5907
+ readonly 'toast.workdirAdopted': '已采纳远端历史(本地提交未改写,已生成一次合并提交)';
5704
5908
  readonly 'toast.workdirRecloned': '工作副本已重新克隆';
5705
5909
  readonly 'toast.workdirResetFailed': '重建工作副本失败';
5706
5910
  readonly 'syncStatus.lastSync': '上次同步';
@@ -5771,7 +5975,9 @@ declare const zh$3: {
5771
5975
  readonly 'warnings.title': '分区告警';
5772
5976
  readonly 'syncflow.title': '一键同步';
5773
5977
  readonly 'syncflow.button': '一键同步';
5978
+ readonly 'syncflow.upToDate': '已是最新,无需同步';
5774
5979
  readonly 'syncflow.syncing': '正在同步…';
5980
+ readonly 'syncflow.checkingRemote': '正在检查远端变更…';
5775
5981
  readonly 'syncflow.syncFailed': '同步失败';
5776
5982
  readonly 'syncflow.snapshotOption': '({date} · {count} 分区)';
5777
5983
  readonly 'syncflow.selectSnapshot': '选择历史快照';
@@ -5865,7 +6071,17 @@ declare const zh$3: {
5865
6071
  readonly 'autosync.description': '开启后,DSH 在后台保持配置一致:本地配置有改动时自动上传,检测到远端有新快照时才自动拉取合并;定时器仅作兜底轮询,无变化不重复动作。仅在无冲突且无需人工干预时才自动写入本地。';
5866
6072
  readonly 'autosync.enable': '启用自动同步';
5867
6073
  readonly 'autosync.interval': '兜底轮询间隔';
5868
- readonly 'autosync.intervalHint': '间隔到点 / DSH 启动时检查远端是否有新快照,有才拉取合并(不上传本地);本地配置改动会触发上传。';
6074
+ readonly 'autosync.intervalHint': '兜底检查节奏:间隔到点 / DSH 启动时检查远端是否有新快照,有才拉取合并。启用「本地改动即时同步」后,保存配置会立刻触发一轮,不必等这里。';
6075
+ readonly 'autosync.realtime': '本地改动即时同步';
6076
+ readonly 'autosync.realtimeHint': '监听本机可同步的配置(settings.yaml、cordis.patch.yml、skills、profiles 下的插件清单等),保存后立即上传;关闭则只在兜底间隔到点时检查。';
6077
+ readonly 'autosync.autoApplyTier': '自动应用范围';
6078
+ readonly 'autosync.autoApplyTierHint': '决定远端改动能自动写回本机的范围:「仅低风险分区」= settings / ui / providers / prompts / skills 等;「含 plugins 与 mcp」= 连中风险分区也自动落盘(缺省)。凭据、插件数据类分区永不自动写入。';
6079
+ readonly 'autosync.tierLow': '仅低风险分区';
6080
+ readonly 'autosync.tierMedium': '含 plugins 与 mcp(推荐)';
6081
+ readonly 'autosync.conflictPolicy': '双侧都改时';
6082
+ readonly 'autosync.conflictPolicyHint': '本机与远端都改了同一分区时:「保留本机并推上去」= 本机版本成为新的远端最新(被覆盖的远端快照仍在历史里,可回滚);「保留冲突待我确认」= 上下行都停下,等你在同步页裁决。';
6083
+ readonly 'autosync.conflictLocal': '保留本机并推上去';
6084
+ readonly 'autosync.conflictAsk': '保留冲突待我确认';
5869
6085
  readonly 'autosync.interval5m': '5 分钟';
5870
6086
  readonly 'autosync.interval15m': '15 分钟';
5871
6087
  readonly 'autosync.interval30m': '30 分钟';
@@ -5908,6 +6124,7 @@ declare const zh$3: {
5908
6124
  readonly 'history.autosyncReasonEncrypted': '远端快照已加密,自动同步跳过(请手动同步)';
5909
6125
  readonly 'history.autosyncReasonMutationLocked': '环境锁被占用(另一项任务进行中,或存在需回收的残留锁)';
5910
6126
  readonly 'history.autosyncReasonUnknown': '未知';
6127
+ readonly 'history.autosyncReasonConflictKeptLocal': '已按策略保留本机并覆盖远端';
5911
6128
  readonly 'history.autosyncReasonUpToDate': '无变化(本地与远端一致)';
5912
6129
  readonly 'history.autosyncReasonUnchanged': '远端无新快照,无需合并';
5913
6130
  readonly 'history.autosyncConflicted': '跳过冲突分区:{sections}';
@@ -6014,11 +6231,96 @@ declare const zh$3: {
6014
6231
  readonly 'cloud.apiBaseUrlInvalid': 'API 根地址必须是 http(s) 且不含用户名/密码';
6015
6232
  readonly 'cloud.secretWriterRequired': '宿主未提供凭据写入通道,无法保存密钥';
6016
6233
  readonly 'cloud.credentialsWriteFailed': '密钥写入 DSH 凭据失败(配置未保存)';
6234
+ readonly 'merge.title': '远程合并';
6235
+ readonly 'merge.subtitle': '读取远端快照做三方合并(本地 / 远端 / 共同基准),列出需要你裁决的分区;预览阶段零写入。';
6236
+ readonly 'merge.entry': '检查远程合并';
6237
+ readonly 'merge.entryHint': '只读:先看远端与本地差在哪、哪些分区需要裁决。不会写任何内容。';
6238
+ readonly 'merge.loading': '正在读取远端快照并合并…';
6239
+ readonly 'merge.reload': '重新预览';
6240
+ readonly 'merge.empty': '没有需要合并的内容';
6241
+ readonly 'merge.emptyHint': '远端与本地一致,或当前没有分区参与同步。';
6242
+ readonly 'merge.noAncestor': '没有共同基准快照:合并退化为两方比较,两侧不一致的分区一律按冲突处理,需要你逐个裁决。';
6243
+ readonly 'merge.summary.auto': '可自动应用';
6244
+ readonly 'merge.summary.review': '待裁决';
6245
+ readonly 'merge.summary.conflicts': '冲突';
6246
+ readonly 'merge.summary.skipped': '无变化';
6247
+ readonly 'merge.section.title': '分区裁决';
6248
+ readonly 'merge.scopeNotice': '冲突按分区整体裁决(本版不做逐条裁决)。';
6249
+ readonly 'merge.skipNotice': '跳过 ≠ 已解决:跳过的冲突不会推进同步基线,下次同步仍会出现。';
6250
+ readonly 'merge.decision.useRemote': '采用远端';
6251
+ readonly 'merge.decision.keepLocal': '保留本地';
6252
+ readonly 'merge.decision.merge': '自动合并';
6253
+ readonly 'merge.decision.skip': '无变化';
6254
+ readonly 'merge.decision.conflict': '需裁决';
6255
+ readonly 'merge.kind.key': '键';
6256
+ readonly 'merge.kind.file': '文件';
6257
+ readonly 'merge.reason.bothModified': '两侧都改动了同一位置';
6258
+ readonly 'merge.reason.modifyDelete': '一侧改动、另一侧删除';
6259
+ readonly 'merge.reason.deleteModify': '一侧删除、另一侧改动';
6260
+ readonly 'merge.reason.noAncestor': '没有共同基准,无法判断谁改动了';
6261
+ readonly 'merge.reason.binary': '二进制内容无法安全合并';
6262
+ readonly 'merge.reason.format': '内容格式不支持自动合并';
6263
+ readonly 'merge.reason.array': '数组无法按位置合并';
6264
+ readonly 'merge.reason.section': '整个分区冲突';
6265
+ readonly 'merge.conflictCount': '{n} 处冲突';
6266
+ readonly 'merge.autoMergedCount': '已自动并入 {n} 处改动';
6267
+ readonly 'merge.col.path': '冲突位置';
6268
+ readonly 'merge.col.local': '本地';
6269
+ readonly 'merge.col.remote': '远端';
6270
+ readonly 'merge.col.ancestor': '基准';
6271
+ readonly 'merge.preview.empty': '(空)';
6272
+ readonly 'merge.action.useLocal': '采用本地';
6273
+ readonly 'merge.action.useRemote': '采用远端';
6274
+ readonly 'merge.action.useMerged': '采用自动合并';
6275
+ readonly 'merge.action.useMergedDisabled': '该分区没有可用的自动合并结果(两侧改动重叠),只能采用一侧或跳过。';
6276
+ readonly 'merge.action.skip': '跳过';
6277
+ readonly 'merge.action.current': '当前裁决';
6278
+ readonly 'merge.bulk.keepLocal': '全部采用本地';
6279
+ readonly 'merge.bulk.useRemote': '全部采用远端';
6280
+ readonly 'merge.bulk.useMerged': '全部采用自动合并';
6281
+ readonly 'merge.bulk.autoOnly': '仅处理无冲突项';
6282
+ readonly 'merge.bulk.leavePending': '冲突留到下次';
6283
+ readonly 'merge.bulk.hint': '「全部采用自动合并」只对真有自动合并结果的分区生效;「冲突留到下次」把需要你裁决的分区全部移出本次操作(不写入、不推进基线),下次同步它们还会出现。';
6284
+ readonly 'merge.bulk.title': '批量';
6285
+ readonly 'merge.apply': '执行合并';
6286
+ readonly 'merge.applying': '执行中…';
6287
+ readonly 'merge.apply.nothing': '当前没有会产生写入的裁决:所有待裁决分区都停在「跳过」。';
6288
+ readonly 'merge.apply.summary': '已裁决 {decided} / 待裁决 {needs} 个分区';
6289
+ readonly 'merge.apply.skips': '其中 {n} 个是「跳过」(不会推进同步基线)';
6290
+ readonly 'merge.apply.undecided': '还有 {n} 个分区未裁决(未裁决不会被执行,等同跳过)。';
6291
+ readonly 'merge.apply.pendingHint': '还有 {n} 个分区待裁决:本次不会应用它们,下次同步仍会出现。';
6292
+ readonly 'merge.apply.nothingPending': '所有分区都没有变化,本次不需要执行合并。';
6293
+ readonly 'merge.apply.willApply': '本次会应用 {n} 个分区';
6294
+ readonly 'merge.result.title': '合并结果';
6295
+ readonly 'merge.result.applied': '已应用分区';
6296
+ readonly 'merge.result.skipped': '已跳过';
6297
+ readonly 'merge.result.warnings': '警告';
6298
+ readonly 'merge.result.restoreId': '回滚点';
6299
+ readonly 'merge.result.rolledBack': '已整体回滚';
6300
+ readonly 'merge.result.rollbackIncomplete': '整体回滚不完整:有项未恢复(见警告)';
6301
+ readonly 'merge.result.none': '没有分区被改动';
6302
+ readonly 'merge.result.pending': '仍有 {n} 个分区待裁决(跳过 ≠ 已解决,下次同步仍会出现)';
6303
+ readonly 'merge.result.rollback': '一键回滚';
6304
+ readonly 'merge.result.rollingBack': '回滚中…';
6305
+ readonly 'merge.result.rolledBackTo': '已回滚到 {id}';
6306
+ readonly 'merge.result.failed': '{n} 项失败';
6307
+ readonly 'merge.result.ineffective': '{n} 项未生效';
6308
+ readonly 'merge.error.previewFailed': '合并预览失败';
6309
+ readonly 'merge.toast.applyFailed': '执行合并失败';
6310
+ readonly 'merge.toast.applied': '合并已执行';
6311
+ readonly 'merge.toast.rollbackFailed': '回滚失败';
6312
+ readonly 'merge.toast.previewFailed': '读取远程合并预览失败';
6313
+ readonly 'probe.run': '测试连接';
6314
+ readonly 'probe.running': '正在测试连接…';
6315
+ readonly 'probe.hint': '只读自检:凭据 / 端点 / 目标容器 / 目录可达。WebDAV 通道可能幂等创建上级目录(那正是它要修的故障);不会推送或改动任何快照。';
6316
+ readonly 'probe.createdCollections': '已在远端自动创建目录:{list}';
6317
+ readonly 'probe.snapshotCount': '远端现有快照:{count} 份';
6318
+ readonly 'probe.unsupported': '该通道不提供连通性自检';
6319
+ readonly 'probe.unsupportedHint': '这是能力边界,不是故障:该通道的同步功能不受影响,只是没有自检这项能力。';
6320
+ readonly 'syncflow.snapshotDevice': '由 {device} 推送';
6017
6321
  };
6018
6322
  /** 字典键联合(注册处 compile-time 校验) */
6019
6323
  type SyncKey = keyof typeof zh$3;
6020
- //#endregion
6021
- //#region src/client/market/market-locales.d.ts
6022
6324
  /**
6023
6325
  * 配置市场区块(config-manager-market)表面文案:zh 为源语言,en 镜像每个键。
6024
6326
  * 独立命名空间、独立文件:与 config-manager / config-manager-sync 平行,不触碰共享字典。
@@ -6218,8 +6520,6 @@ declare const zh$2: {
6218
6520
  };
6219
6521
  /** 字典键联合(注册处 compile-time 校验) */
6220
6522
  type MarketKey = keyof typeof zh$2;
6221
- //#endregion
6222
- //#region src/client/recovery/recovery-locales.d.ts
6223
6523
  /**
6224
6524
  * Recovery 区块(config-manager-recovery)表面文案:zh 为源语言,en 镜像每个键。
6225
6525
  * 独立命名空间、独立文件:不触碰共享的 locales.ts(并行会话已改),零冲突。
@@ -6240,7 +6540,7 @@ declare const zh$1: {
6240
6540
  readonly 'recovery.banner': '配置修改已被保护:存在未完成的恢复事项。请先处理后继续。';
6241
6541
  readonly 'recovery.bannerAction': '去处理';
6242
6542
  readonly 'recovery.required': '需要恢复';
6243
- readonly 'recovery.requiredHint': '检测到一次操作未正常完成,为安全起见已暂停所有会修改配置的操作。请处理以下恢复事项以恢复正常。';
6543
+ readonly 'recovery.requiredHint': '存在需要处理的恢复事项(残留锁、未完成的操作或中断的复制)。处理完这些事项即恢复正常。';
6244
6544
  readonly 'recovery.rollbackRecommended': '建议回滚';
6245
6545
  readonly 'recovery.rollbackContinue': '续跑回滚';
6246
6546
  readonly 'recovery.inProgress': '恢复进行中';
@@ -6267,6 +6567,12 @@ declare const zh$1: {
6267
6567
  readonly 'recovery.verify.verdict.unknown': '未知';
6268
6568
  readonly 'recovery.currentState.title': '当前状态';
6269
6569
  readonly 'recovery.currentState.safeMode': '已进入安全模式(会修改配置的操作已暂停)';
6570
+ readonly 'recovery.currentState.itemsOnly': '存在需要处理的恢复事项(写操作未被暂停)';
6571
+ readonly 'recovery.live.title': '正在执行的操作';
6572
+ readonly 'recovery.live.hint': '这些操作正在正常执行中,不是未完成的恢复事项;结束后会自动消失。';
6573
+ readonly 'recovery.incident.liveBlocked': '该操作仍在进行中,现在不能恢复也不能放弃,请等它结束。';
6574
+ readonly 'recovery.incident.blockReason.noSnapshot': '本次操作没有绑定可信恢复快照,因此无法执行恢复。';
6575
+ readonly 'recovery.incident.blockReason.needsAttention': '该事项被判定为需要人工处理,无法自动恢复。';
6270
6576
  readonly 'recovery.currentState.hasSnapshot': '存在可信恢复快照';
6271
6577
  readonly 'recovery.currentState.noSnapshot': '无可信恢复快照';
6272
6578
  readonly 'recovery.snapshot.title': '恢复快照';
@@ -6620,6 +6926,7 @@ declare const zh$1: {
6620
6926
  readonly 'rollback.result.conflict': '{n} 个文件两侧改到同一处,已保持原样 —— 需要你手工处理';
6621
6927
  readonly 'rollback.result.unavailable': '{n} 个文件无法安全撤销(缺少中间版本 / 二进制 / 差异过大),已保持原样';
6622
6928
  readonly 'rollback.result.concurrent': '{n} 个文件在回退过程中又被改过,已保持原样';
6929
+ readonly 'rollback.result.unclaimed': '{n} 个文件无法判定属于哪个对话(改动时没有任何对话在运行),已保持原样';
6623
6930
  readonly 'rollback.result.selectionSkipped': '{n} 个文件按你的勾选跳过了';
6624
6931
  readonly 'rollback.preview.files.empty': '工作区与该回退点一致,无需恢复';
6625
6932
  readonly 'rollback.preview.files.unavailable': '该回退点的工作区态没有可用的记录(原因:{reason}),无需恢复';
@@ -6773,16 +7080,12 @@ declare const zh$1: {
6773
7080
  };
6774
7081
  /** 字典键联合(注册处 compile-time 校验)。 */
6775
7082
  type RecoveryKey = keyof typeof zh$1;
6776
- //#endregion
6777
- //#region src/client/history/history-locales.d.ts
6778
7083
  type KindKey = `history.kind.${MigrationKind}`;
6779
7084
  type ResultKey = `history.result.${MigrationResult}`;
6780
7085
  type CommonKey = 'view.history' | 'history.title' | 'history.subtitle' | 'history.empty' | 'history.loading' | 'history.corruptedBanner' | 'history.corruptedCount' | 'history.stats.total' | 'history.stats.success' | 'history.stats.failed' | 'history.stats.skipped' | 'history.filter.kind' | 'history.filter.result' | 'history.filter.recent' | 'history.filter.recent.all' | 'history.filter.recent.50' | 'history.filter.recent.200' | 'history.filter.sections' | 'history.filter.title' | 'history.search.placeholder' | 'history.export.json' | 'history.export.markdown' | 'history.exported' | 'history.exporting' | 'history.exportError' | 'history.loadError' | 'history.reload' | 'history.table.time' | 'history.table.kind' | 'history.table.result' | 'history.table.sections' | 'history.table.summary' | 'history.updatedAt' | 'history.refresh' |
6781
7086
  /** ⓘ 说明按钮的可访问名(与主字典 / market / sync / recovery 同口径,见 info-hint-guard t6-4) */
6782
7087
  'common.infoHint';
6783
7088
  type HistoryKey = KindKey | ResultKey | CommonKey;
6784
- //#endregion
6785
- //#region src/client/chat/chat-locales.d.ts
6786
7089
  /**
6787
7090
  * 聊天内「↺ 回退」入口(config-manager-chat)的独立字典:zh 为源语言,en 镜像每个键。
6788
7091
  * 独立命名空间、独立文件:不触碰共享的 locales.ts,也不与 recovery 字典混住。
@@ -6893,27 +7196,19 @@ declare const zh: {
6893
7196
  readonly 'chat.entry.disabled.turnUnknown': '这个回合的收尾状态未知,暂不可回退';
6894
7197
  };
6895
7198
  type ChatKey = keyof typeof zh;
6896
- //#endregion
6897
- //#region src/client/ConfigManagerSection.d.ts
6898
7199
  type ConfigManagerSectionProps = PropsRuntime<'settings.section'> & ConfigManagerSectionInjected & {
6899
7200
  t: TranslateNS<'config-manager'>;
6900
7201
  };
6901
- //#endregion
6902
- //#region src/client/export/ExportView.d.ts
6903
7202
  interface ExportViewProps {
6904
7203
  api: ConfigManagerApi;
6905
7204
  t: TranslateNS<'config-manager'>;
6906
7205
  }
6907
- //#endregion
6908
- //#region src/client/import/ImportWizardView.d.ts
6909
7206
  interface ImportWizardViewProps {
6910
7207
  api: ConfigManagerApi;
6911
7208
  t: TranslateNS<'config-manager'>;
6912
7209
  uiT?: UiT;
6913
7210
  onOpenForeignImport?: () => void;
6914
7211
  }
6915
- //#endregion
6916
- //#region src/client/sync/SyncPanel.d.ts
6917
7212
  interface SyncPanelProps {
6918
7213
  api: SyncApi;
6919
7214
  t: TranslateNS<'config-manager-sync'>;
@@ -6923,8 +7218,6 @@ interface SyncPanelProps {
6923
7218
  */
6924
7219
  cmT: TranslateNS<'config-manager'>;
6925
7220
  }
6926
- //#endregion
6927
- //#region src/client/market/MarketPanel.d.ts
6928
7221
  interface MarketPanelProps {
6929
7222
  api: MarketApi;
6930
7223
  /** 「我的配置」API(/me/* 端点:登录态/一键上传/查看已上传/一键更新;登录复用 SyncApi.github*) */
@@ -6950,14 +7243,10 @@ interface MarketPanelProps {
6950
7243
  */
6951
7244
  initialSubView?: 'browse' | 'myconfigs';
6952
7245
  }
6953
- //#endregion
6954
- //#region src/client/about/AboutPanel.d.ts
6955
7246
  interface AboutPanelProps {
6956
7247
  api: ConfigManagerApi;
6957
7248
  t: TranslateNS<'config-manager'>;
6958
7249
  }
6959
- //#endregion
6960
- //#region src/client/index.d.ts
6961
7250
  declare module '@deepseek-ai/dsh-client-ui-slots' {
6962
7251
  interface LocaleNamespaceMap {
6963
7252
  /** Config Manager 表面文案。 */
@@ -6981,7 +7270,6 @@ export declare const inject: string[];
6981
7270
  * @param ctx - client root context(slots + locale 服务)。
6982
7271
  */
6983
7272
  export declare function apply(ctx: ClientContext): void;
6984
- //#endregion
6985
7273
  export type { AboutPanelProps, ChatKey, ConfigManagerApiError, ConfigManagerKey, ConfigManagerSectionProps, DownloadResult, ExportViewProps, HistoryKey, ImportWizardViewProps, MarketKey, MarketPanelProps, RecoveryKey, ServiceStatus, SyncKey, SyncPanelProps, UploadResponse };
6986
7274
 
6987
7275
  return module.exports;