dsh-config-manager 0.1.71 → 0.1.73

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 (596) hide show
  1. package/README.md +149 -98
  2. package/README.zh-CN.md +245 -88
  3. package/lib/adapters/agent-instructions.js +1 -1
  4. package/lib/adapters/file-collection.js +1 -1
  5. package/lib/adapters/index.d.ts +2 -1
  6. package/lib/adapters/index.js +6 -1
  7. package/lib/adapters/link-report.d.ts +1 -0
  8. package/lib/adapters/link-report.js +27 -3
  9. package/lib/adapters/messages.d.ts +21 -0
  10. package/lib/adapters/messages.js +57 -0
  11. package/lib/adapters/plugin-data.d.ts +114 -0
  12. package/lib/adapters/plugin-data.js +309 -0
  13. package/lib/adapters/plugin-files.js +3 -2
  14. package/lib/adapters/plugins.js +4 -3
  15. package/lib/adapters/prompts.d.ts +1 -0
  16. package/lib/adapters/prompts.js +7 -1
  17. package/lib/adapters/self.d.ts +8 -2
  18. package/lib/adapters/self.js +3 -2
  19. package/lib/adapters/sessions.d.ts +1 -0
  20. package/lib/adapters/sessions.js +4 -2
  21. package/lib/adapters/test-helpers.d.ts +9 -0
  22. package/lib/adapters/test-helpers.js +14 -0
  23. package/lib/adapters/ui.d.ts +2 -2
  24. package/lib/adapters/ui.js +25 -25
  25. package/lib/adapters/workspaces.d.ts +1 -0
  26. package/lib/adapters/workspaces.js +7 -3
  27. package/lib/cli/actions.d.ts +9 -1
  28. package/lib/cli/actions.js +5 -2
  29. package/lib/cli/help.js +23 -10
  30. package/lib/cli/index.d.ts +23 -0
  31. package/lib/cli/index.js +90 -32
  32. package/lib/cli/sessions-inspect.js +3 -1
  33. package/lib/cli/sessions-repair.js +25 -6
  34. package/lib/cli/web/page.d.ts +12 -0
  35. package/lib/cli/web/page.js +21 -12
  36. package/lib/cli/web/routes.js +2 -2
  37. package/lib/cli/web/server.js +4 -4
  38. package/lib/client.d.ts +1442 -494
  39. package/lib/client.js +15326 -8520
  40. package/lib/core/analyzer.d.ts +11 -2
  41. package/lib/core/analyzer.js +31 -8
  42. package/lib/core/backup-plan.d.ts +10 -0
  43. package/lib/core/backup-plan.js +51 -20
  44. package/lib/core/backup-verify.js +24 -23
  45. package/lib/core/backup.d.ts +25 -1
  46. package/lib/core/backup.js +99 -28
  47. package/lib/core/boot-rescue.js +4 -3
  48. package/lib/core/boot-safety.js +2 -1
  49. package/lib/core/command-rollback.d.ts +182 -0
  50. package/lib/core/command-rollback.js +293 -0
  51. package/lib/core/consult-source.js +7 -6
  52. package/lib/core/disk-usage.d.ts +74 -10
  53. package/lib/core/disk-usage.js +67 -4
  54. package/lib/core/engine-locale.d.ts +87 -0
  55. package/lib/core/engine-locale.js +125 -0
  56. package/lib/core/exporter.js +3 -3
  57. package/lib/core/fork-reconcile.d.ts +128 -0
  58. package/lib/core/fork-reconcile.js +150 -0
  59. package/lib/core/journal.js +6 -5
  60. package/lib/core/local-plugin-host.js +3 -2
  61. package/lib/core/local-plugin-pack.js +11 -6
  62. package/lib/core/messages-core.d.ts +294 -0
  63. package/lib/core/messages-core.js +619 -0
  64. package/lib/core/messages.d.ts +61 -2
  65. package/lib/core/messages.js +118 -13
  66. package/lib/core/migration-consult.js +21 -20
  67. package/lib/core/migration-history.js +19 -5
  68. package/lib/core/model-tools.d.ts +0 -22
  69. package/lib/core/model-tools.js +50 -27
  70. package/lib/core/phase3-host.js +30 -5
  71. package/lib/core/plugin-cli.js +18 -19
  72. package/lib/core/plugin-data-registry.d.ts +124 -0
  73. package/lib/core/plugin-data-registry.js +198 -0
  74. package/lib/core/reconcile.d.ts +2 -14
  75. package/lib/core/reconcile.js +87 -17
  76. package/lib/core/recovery-orchestrator.js +19 -18
  77. package/lib/core/reinstall.d.ts +4 -0
  78. package/lib/core/reinstall.js +26 -21
  79. package/lib/core/restore.js +20 -17
  80. package/lib/core/rollback-gate.d.ts +33 -0
  81. package/lib/core/rollback-gate.js +57 -0
  82. package/lib/core/rollback-ignore-rules.d.ts +31 -0
  83. package/lib/core/rollback-ignore-rules.js +140 -0
  84. package/lib/core/rollback-ledger.d.ts +248 -0
  85. package/lib/core/rollback-ledger.js +1282 -0
  86. package/lib/core/rollback-point.d.ts +1391 -0
  87. package/lib/core/rollback-point.js +3503 -0
  88. package/lib/core/rollback.js +6 -4
  89. package/lib/core/run-registry.js +6 -5
  90. package/lib/core/session-health.d.ts +15 -0
  91. package/lib/core/session-meta.d.ts +42 -2
  92. package/lib/core/session-meta.js +140 -1
  93. package/lib/core/session-title.d.ts +28 -0
  94. package/lib/core/session-title.js +185 -0
  95. package/lib/core/startup-barrier.d.ts +24 -0
  96. package/lib/core/startup-barrier.js +22 -0
  97. package/lib/core/transaction-coordinator.js +4 -3
  98. package/lib/core/types.d.ts +37 -1
  99. package/lib/core/validator.js +5 -4
  100. package/lib/core/verify-recovery.js +31 -30
  101. package/lib/foreign/bundle.js +3 -2
  102. package/lib/foreign/continue.js +2 -1
  103. package/lib/foreign/crush.js +2 -1
  104. package/lib/foreign/gemini.js +2 -1
  105. package/lib/foreign/goose.js +2 -1
  106. package/lib/foreign/kilocode.js +2 -1
  107. package/lib/foreign/kimi.js +2 -1
  108. package/lib/foreign/messages.d.ts +15 -0
  109. package/lib/foreign/messages.js +40 -0
  110. package/lib/foreign/mimocode.js +2 -1
  111. package/lib/foreign/openclaw.js +2 -1
  112. package/lib/foreign/opencode.js +2 -1
  113. package/lib/foreign/pi.js +2 -1
  114. package/lib/foreign/qoder.js +2 -1
  115. package/lib/foreign/qwen.js +2 -1
  116. package/lib/foreign/registry.d.ts +1 -1
  117. package/lib/foreign/registry.js +8 -7
  118. package/lib/foreign/teleagent.js +2 -1
  119. package/lib/foreign/workbuddy.js +2 -1
  120. package/lib/foreign/zcode.js +2 -1
  121. package/lib/foreign/zed.js +2 -1
  122. package/lib/index.d.ts +227 -7
  123. package/lib/index.js +799 -54
  124. package/lib/market/git-file-writer.js +20 -19
  125. package/lib/market/github-repos.js +35 -19
  126. package/lib/market/index-parser.js +31 -30
  127. package/lib/market/messages-market.d.ts +138 -0
  128. package/lib/market/messages-market.js +305 -0
  129. package/lib/market/my-repo.d.ts +2 -2
  130. package/lib/market/my-repo.js +32 -29
  131. package/lib/market/prepare.js +18 -15
  132. package/lib/market/security.js +20 -19
  133. package/lib/market/types.js +2 -1
  134. package/lib/market/url.js +2 -1
  135. package/lib/migrations/index.js +6 -5
  136. package/lib/migrations/messages-migrations.d.ts +32 -0
  137. package/lib/migrations/messages-migrations.js +58 -0
  138. package/lib/profiles/dsh-profile-launcher.js +2 -1
  139. package/lib/profiles/dsh-profile-runtime.js +2 -1
  140. package/lib/profiles/messages.d.ts +7 -0
  141. package/lib/profiles/messages.js +27 -0
  142. package/lib/routes/backup.js +18 -2
  143. package/lib/routes/import.js +3 -3
  144. package/lib/routes/index.d.ts +1 -1
  145. package/lib/routes/kit.d.ts +3 -2
  146. package/lib/routes/kit.js +6 -1
  147. package/lib/routes/market.js +1 -1
  148. package/lib/routes/messages.d.ts +43 -0
  149. package/lib/routes/messages.js +102 -0
  150. package/lib/routes/prefs.js +26 -3
  151. package/lib/routes/profiles.js +12 -6
  152. package/lib/routes/recovery.d.ts +21 -0
  153. package/lib/routes/recovery.js +478 -94
  154. package/lib/routes/snapshots.js +51 -4
  155. package/lib/routes/sync.js +79 -17
  156. package/lib/schema/config.d.ts +11 -1
  157. package/lib/schema/config.js +52 -20
  158. package/lib/schema/index.d.ts +8 -6
  159. package/lib/schema/index.js +8 -6
  160. package/lib/schema/manifest.js +19 -18
  161. package/lib/schema/messages.d.ts +47 -0
  162. package/lib/schema/messages.js +110 -0
  163. package/lib/schema/section-registry.d.ts +42 -15
  164. package/lib/schema/section-registry.js +67 -32
  165. package/lib/schema/types.d.ts +1 -1
  166. package/lib/schema/versions.js +6 -5
  167. package/lib/security/encryption.js +16 -15
  168. package/lib/security/integrity.js +8 -7
  169. package/lib/security/messages.d.ts +30 -0
  170. package/lib/security/messages.js +77 -0
  171. package/lib/security/redaction.js +12 -0
  172. package/lib/security/secret-scanner.js +16 -13
  173. package/lib/security/vault.js +2 -1
  174. package/lib/security/zip-security.js +4 -3
  175. package/lib/sync/ancestor.js +2 -1
  176. package/lib/sync/autosync-config.d.ts +11 -0
  177. package/lib/sync/autosync-config.js +12 -0
  178. package/lib/sync/autosync-scheduler.d.ts +11 -1
  179. package/lib/sync/autosync-scheduler.js +115 -76
  180. package/lib/sync/backup-files.js +3 -2
  181. package/lib/sync/backup-scheduler.js +6 -5
  182. package/lib/sync/blob-store.js +2 -1
  183. package/lib/sync/git/git-transport.d.ts +55 -0
  184. package/lib/sync/git/git-transport.js +152 -2
  185. package/lib/sync/github-auth.js +10 -9
  186. package/lib/sync/layout.js +13 -12
  187. package/lib/sync/messages.d.ts +63 -0
  188. package/lib/sync/messages.js +149 -0
  189. package/lib/sync/review-queue.js +6 -5
  190. package/lib/sync/s3/messages.d.ts +7 -0
  191. package/lib/sync/s3/messages.js +16 -0
  192. package/lib/sync/s3/s3-providers.d.ts +4 -1
  193. package/lib/sync/s3/s3-providers.js +5 -5
  194. package/lib/sync/s3/s3-transport.js +1 -1
  195. package/lib/sync/s3/sigv4.js +2 -1
  196. package/lib/sync/snapshot-crypto.js +6 -5
  197. package/lib/sync/snapshot-json.js +3 -2
  198. package/lib/sync/sync-engine.d.ts +58 -22
  199. package/lib/sync/sync-engine.js +119 -48
  200. package/lib/sync/sync-history.js +7 -6
  201. package/lib/sync/sync-selection.d.ts +15 -4
  202. package/lib/sync/sync-selection.js +17 -5
  203. package/lib/sync/ui-prefs.d.ts +22 -0
  204. package/lib/sync/ui-prefs.js +28 -0
  205. package/lib/sync/webdav/webdav-transport.d.ts +1 -0
  206. package/lib/sync/webdav/webdav-transport.js +4 -1
  207. package/lib/ui/artifact-view.js +4 -3
  208. package/lib/ui/commands.d.ts +1 -1
  209. package/lib/ui/commands.js +10 -0
  210. package/lib/ui/diff-view.d.ts +10 -0
  211. package/lib/ui/diff-view.js +17 -0
  212. package/lib/ui/disk-usage-view.d.ts +33 -4
  213. package/lib/ui/disk-usage-view.js +29 -1
  214. package/lib/ui/errors.d.ts +1 -1
  215. package/lib/ui/errors.js +4 -3
  216. package/lib/ui/export-flow.js +26 -20
  217. package/lib/ui/foreign-view.d.ts +5 -1
  218. package/lib/ui/foreign-view.js +26 -2
  219. package/lib/ui/i18n.d.ts +68 -1
  220. package/lib/ui/i18n.js +120 -2
  221. package/lib/ui/import-wizard.d.ts +7 -0
  222. package/lib/ui/import-wizard.js +13 -10
  223. package/lib/ui/progress.d.ts +2 -2
  224. package/lib/ui/progress.js +1 -2
  225. package/lib/ui/report.d.ts +5 -5
  226. package/lib/ui/report.js +6 -6
  227. package/lib/ui/rollback-view.d.ts +815 -0
  228. package/lib/ui/rollback-view.js +738 -0
  229. package/lib/ui/selection-model.d.ts +41 -0
  230. package/lib/ui/selection-model.js +30 -0
  231. package/lib/ui/session-inventory-view.d.ts +97 -3
  232. package/lib/ui/session-inventory-view.js +76 -2
  233. package/lib/ui/session-issue-labels.d.ts +43 -0
  234. package/lib/ui/session-issue-labels.js +48 -0
  235. package/lib/ui/sync-settings-view.d.ts +33 -0
  236. package/lib/ui/sync-settings-view.js +40 -0
  237. package/lib/ui/test-helpers.js +2 -1
  238. package/lib/ui/types.d.ts +8 -3
  239. package/lib/ui/types.js +1 -1
  240. package/lib/utils/atomic-write.js +6 -5
  241. package/lib/utils/bundle-scan.d.ts +11 -1
  242. package/lib/utils/bundle-scan.js +12 -1
  243. package/lib/utils/env-lock.d.ts +10 -0
  244. package/lib/utils/env-lock.js +73 -46
  245. package/lib/utils/json.js +6 -5
  246. package/lib/utils/messages-utils.d.ts +96 -0
  247. package/lib/utils/messages-utils.js +216 -0
  248. package/lib/utils/proxy.js +18 -5
  249. package/lib/utils/recursive-walk.d.ts +22 -0
  250. package/lib/utils/recursive-walk.js +75 -1
  251. package/lib/utils/session-log-repair.js +10 -9
  252. package/lib/utils/zip.js +27 -26
  253. package/package.json +12 -2
  254. package/src/adapters/agent-instructions.ts +1 -1
  255. package/src/adapters/file-collection.test.ts +1 -0
  256. package/src/adapters/file-collection.ts +1 -1
  257. package/src/adapters/files.test.ts +27 -0
  258. package/src/adapters/index.ts +6 -1
  259. package/src/adapters/link-report.test.ts +22 -2
  260. package/src/adapters/link-report.ts +29 -4
  261. package/src/adapters/messages.ts +61 -0
  262. package/src/adapters/plugin-data.test.ts +225 -0
  263. package/src/adapters/plugin-data.ts +351 -0
  264. package/src/adapters/plugin-files.ts +3 -2
  265. package/src/adapters/plugins.ts +4 -3
  266. package/src/adapters/prompts.ts +7 -1
  267. package/src/adapters/self.test.ts +26 -0
  268. package/src/adapters/self.ts +10 -3
  269. package/src/adapters/sessions.ts +4 -2
  270. package/src/adapters/settings.test.ts +38 -1
  271. package/src/adapters/test-helpers.ts +15 -0
  272. package/src/adapters/ui.test.ts +2 -2
  273. package/src/adapters/ui.ts +27 -26
  274. package/src/adapters/workspaces.ts +7 -3
  275. package/src/cli/actions.test.ts +28 -0
  276. package/src/cli/actions.ts +11 -2
  277. package/src/cli/help.ts +23 -10
  278. package/src/cli/index-guards.test.ts +193 -0
  279. package/src/cli/index.ts +106 -31
  280. package/src/cli/sessions-inspect.test.ts +15 -1
  281. package/src/cli/sessions-inspect.ts +3 -1
  282. package/src/cli/sessions-repair.test.ts +84 -0
  283. package/src/cli/sessions-repair.ts +33 -7
  284. package/src/cli/web/console-route-parity.test.ts +115 -0
  285. package/src/cli/web/page.ts +23 -12
  286. package/src/cli/web/routes.ts +2 -1
  287. package/src/cli/web/server.ts +4 -4
  288. package/src/cli/web/web.test.ts +2 -2
  289. package/src/client/ConfigManagerSection.tsx +30 -2
  290. package/src/client/about/AboutPanel.tsx +2 -2
  291. package/src/client/about/PluginUpdateDialog.tsx +1 -1
  292. package/src/client/about/ReleaseNotesDialog.tsx +2 -2
  293. package/src/client/about/about-view.test.ts +13 -3
  294. package/src/client/about/about-view.ts +10 -6
  295. package/src/client/about/release-notes-view.test.ts +14 -4
  296. package/src/client/about/release-notes-view.ts +4 -2
  297. package/src/client/api.ts +18 -6
  298. package/src/client/chat/ChatEntryView.tsx +411 -0
  299. package/src/client/chat/RollbackDiffTab.tsx +108 -0
  300. package/src/client/chat/RollbackFileIcon.tsx +96 -0
  301. package/src/client/chat/RollbackReviewDialog.tsx +607 -0
  302. package/src/client/chat/chat-entry-view.test.ts +1174 -0
  303. package/src/client/chat/chat-entry-view.ts +758 -0
  304. package/src/client/chat/chat-locales.ts +152 -0
  305. package/src/client/chat/chat-node-registration.ts +64 -0
  306. package/src/client/chat/chat-point-window.ts +183 -0
  307. package/src/client/chat/chat-slots.ts +107 -0
  308. package/src/client/chat/rollback-diff-tab.test.ts +105 -0
  309. package/src/client/chat/rollback-diff-tab.ts +174 -0
  310. package/src/client/chat/rollback-entry-view.test.ts +1469 -0
  311. package/src/client/chat/rollback-entry-view.ts +946 -0
  312. package/src/client/chat/sidebar-slots.ts +59 -0
  313. package/src/client/common/ConfirmDialog.tsx +7 -3
  314. package/src/client/common/ContentPicker.tsx +48 -10
  315. package/src/client/common/DiffTable.tsx +133 -0
  316. package/src/client/common/ErrorBanner.tsx +4 -4
  317. package/src/client/common/Icon.tsx +2 -0
  318. package/src/client/common/Modal.tsx +8 -1
  319. package/src/client/common/ProgressBar.tsx +8 -2
  320. package/src/client/common/ReportView.tsx +4 -4
  321. package/src/client/common/RunsCenter.tsx +1 -0
  322. package/src/client/common/client-route-parity.test.ts +84 -0
  323. package/src/client/common/info-hint-guard.test.ts +46 -13
  324. package/src/client/common/picker-lazy-units.test.ts +42 -0
  325. package/src/client/common/plan-text-redaction.test.ts +17 -6
  326. package/src/client/common/progress-view-edge.test.ts +8 -7
  327. package/src/client/common/progress-view.test.ts +9 -9
  328. package/src/client/common/progress-view.ts +2 -2
  329. package/src/client/common/routes.ts +38 -0
  330. package/src/client/common/section-labels.test.ts +1 -0
  331. package/src/client/common/section-labels.ts +2 -0
  332. package/src/client/common/ui.tsx +73 -10
  333. package/src/client/config-manager.module.css +1109 -31
  334. package/src/client/css-scale-guard.test.ts +30 -0
  335. package/src/client/environment/EnvironmentPanel.tsx +11 -4
  336. package/src/client/environment/maintenance/DiskUsageCard.tsx +23 -2
  337. package/src/client/export/ExportView.tsx +13 -8
  338. package/src/client/history/HistoryPanel.tsx +4 -3
  339. package/src/client/history/history-api.ts +2 -2
  340. package/src/client/history/history-locales.ts +5 -1
  341. package/src/client/home/HomePanel.tsx +29 -8
  342. package/src/client/import/ForeignImportView.tsx +4 -5
  343. package/src/client/import/ImportWizardView.tsx +5 -3
  344. package/src/client/import/import-wizard-split.test.ts +3 -1
  345. package/src/client/import/import-wizard-steps.tsx +9 -9
  346. package/src/client/index.ts +232 -3
  347. package/src/client/library/LibraryActions.tsx +32 -7
  348. package/src/client/library/LibraryPanel.tsx +23 -3
  349. package/src/client/library/RestorePlanView.tsx +9 -66
  350. package/src/client/locales.ts +62 -9
  351. package/src/client/lucide-icons.d.ts +1 -0
  352. package/src/client/market/MarketPanel.tsx +13 -2
  353. package/src/client/market/MyConfigsView.tsx +5 -4
  354. package/src/client/market/MyConfigsWizard.tsx +10 -8
  355. package/src/client/market/market-api.test.ts +9 -8
  356. package/src/client/market/market-api.ts +2 -2
  357. package/src/client/market/market-locales.ts +3 -0
  358. package/src/client/market/market-view.test.ts +6 -6
  359. package/src/client/market/market-view.ts +3 -3
  360. package/src/client/market/my-configs-api.ts +2 -2
  361. package/src/client/market/my-configs-view.test.ts +23 -22
  362. package/src/client/market/my-configs-view.ts +8 -8
  363. package/src/client/recovery/IncompleteCopiesSection.tsx +2 -1
  364. package/src/client/recovery/RecoveryPanel.tsx +442 -283
  365. package/src/client/recovery/RollbackCard.tsx +859 -0
  366. package/src/client/recovery/RollbackDiffPane.tsx +69 -0
  367. package/src/client/recovery/RollbackFileChanges.tsx +163 -0
  368. package/src/client/recovery/incident-api.ts +2 -2
  369. package/src/client/recovery/recovery-api.ts +144 -6
  370. package/src/client/recovery/recovery-locales.test.ts +299 -0
  371. package/src/client/recovery/recovery-locales.ts +520 -149
  372. package/src/client/recovery/recovery-panel-layout.test.ts +132 -2
  373. package/src/client/recovery/rollback-enabled.ts +41 -0
  374. package/src/client/recovery/rollback-file-changes.test.ts +114 -0
  375. package/src/client/recovery/session-dialog-mount.test.ts +54 -0
  376. package/src/client/run-store.ts +84 -21
  377. package/src/client/sync/AutosyncCard.tsx +25 -1
  378. package/src/client/sync/ChannelClearConfirmDialog.tsx +6 -3
  379. package/src/client/sync/ChannelConfigDialog.tsx +10 -10
  380. package/src/client/sync/DecryptPasswordCard.tsx +2 -2
  381. package/src/client/sync/SecurityOptionsCard.tsx +27 -17
  382. package/src/client/sync/SyncChannelEntryCard.tsx +14 -2
  383. package/src/client/sync/SyncConfirmView.tsx +46 -8
  384. package/src/client/sync/SyncLogList.tsx +1 -1
  385. package/src/client/sync/SyncPanel.tsx +31 -23
  386. package/src/client/sync/SyncRepositoryPicker.tsx +3 -5
  387. package/src/client/sync/SyncSectionPickerDialog.tsx +11 -2
  388. package/src/client/sync/SyncSettingsView.test.ts +20 -1
  389. package/src/client/sync/UnreadableSnapshotsBanner.tsx +1 -1
  390. package/src/client/sync/WorkDirCard.tsx +112 -0
  391. package/src/client/sync/history-model.test.ts +42 -9
  392. package/src/client/sync/history-model.ts +30 -15
  393. package/src/client/sync/sync-api.test.ts +57 -33
  394. package/src/client/sync/sync-api.ts +80 -6
  395. package/src/client/sync/sync-locales.ts +104 -3
  396. package/src/client/sync/sync-view-v2.test.ts +65 -13
  397. package/src/client/sync/sync-view.test.ts +107 -52
  398. package/src/client/sync/sync-view.ts +124 -41
  399. package/src/core/analyzer.ts +31 -9
  400. package/src/core/backup-plan.test.ts +48 -5
  401. package/src/core/backup-plan.ts +51 -20
  402. package/src/core/backup-verify.ts +24 -23
  403. package/src/core/backup.test.ts +76 -0
  404. package/src/core/backup.ts +105 -29
  405. package/src/core/boot-rescue.ts +4 -3
  406. package/src/core/boot-safety.ts +2 -1
  407. package/src/core/command-rollback.test.ts +536 -0
  408. package/src/core/command-rollback.ts +406 -0
  409. package/src/core/consult-source.ts +7 -6
  410. package/src/core/disk-usage.test.ts +257 -1
  411. package/src/core/disk-usage.ts +134 -14
  412. package/src/core/engine-locale.test.ts +593 -0
  413. package/src/core/engine-locale.ts +175 -0
  414. package/src/core/exporter.ts +3 -3
  415. package/src/core/fork-reconcile.test.ts +279 -0
  416. package/src/core/fork-reconcile.ts +234 -0
  417. package/src/core/journal.ts +6 -5
  418. package/src/core/local-plugin-host.ts +3 -2
  419. package/src/core/local-plugin-pack.ts +11 -6
  420. package/src/core/messages-core.ts +661 -0
  421. package/src/core/messages.ts +125 -17
  422. package/src/core/migration-consult.ts +21 -20
  423. package/src/core/migration-history.ts +19 -5
  424. package/src/core/model-tools.ts +28 -27
  425. package/src/core/phase3-host.ts +21 -5
  426. package/src/core/phase3-p2b-fingerprint.test.ts +22 -0
  427. package/src/core/plugin-cli.ts +18 -19
  428. package/src/core/plugin-data-registry.test.ts +113 -0
  429. package/src/core/plugin-data-registry.ts +261 -0
  430. package/src/core/reconcile.test.ts +117 -0
  431. package/src/core/reconcile.ts +85 -17
  432. package/src/core/recovery-orchestrator.ts +19 -18
  433. package/src/core/reinstall.ts +26 -21
  434. package/src/core/restore.ts +20 -17
  435. package/src/core/rollback-file-diff.test.ts +159 -0
  436. package/src/core/rollback-gate.test.ts +66 -0
  437. package/src/core/rollback-gate.ts +61 -0
  438. package/src/core/rollback-ignore-rules.ts +126 -0
  439. package/src/core/rollback-ledger.test.ts +655 -0
  440. package/src/core/rollback-ledger.ts +1314 -0
  441. package/src/core/rollback-point.test.ts +2853 -0
  442. package/src/core/rollback-point.ts +4340 -0
  443. package/src/core/rollback.ts +5 -3
  444. package/src/core/run-registry.ts +6 -5
  445. package/src/core/session-health.ts +15 -0
  446. package/src/core/session-meta.test.ts +117 -1
  447. package/src/core/session-meta.ts +149 -2
  448. package/src/core/session-title.test.ts +127 -0
  449. package/src/core/session-title.ts +189 -0
  450. package/src/core/startup-barrier.test.ts +69 -0
  451. package/src/core/startup-barrier.ts +27 -0
  452. package/src/core/transaction-coordinator.ts +4 -3
  453. package/src/core/types.ts +37 -1
  454. package/src/core/validator.ts +5 -4
  455. package/src/core/verify-recovery.ts +31 -30
  456. package/src/foreign/bundle.ts +3 -2
  457. package/src/foreign/continue.ts +2 -1
  458. package/src/foreign/crush.ts +2 -1
  459. package/src/foreign/file-budget.test.ts +2 -0
  460. package/src/foreign/gemini.ts +2 -1
  461. package/src/foreign/goose.ts +2 -1
  462. package/src/foreign/kilocode.ts +2 -1
  463. package/src/foreign/kimi.ts +2 -1
  464. package/src/foreign/messages.ts +44 -0
  465. package/src/foreign/mimocode.ts +2 -1
  466. package/src/foreign/openclaw.ts +2 -1
  467. package/src/foreign/opencode.ts +2 -1
  468. package/src/foreign/pi.ts +2 -1
  469. package/src/foreign/qoder.ts +2 -1
  470. package/src/foreign/qwen.ts +2 -1
  471. package/src/foreign/registry.test.ts +1 -1
  472. package/src/foreign/registry.ts +8 -7
  473. package/src/foreign/teleagent.ts +2 -1
  474. package/src/foreign/workbuddy.ts +2 -1
  475. package/src/foreign/zcode.ts +2 -1
  476. package/src/foreign/zed.ts +2 -1
  477. package/src/index.facade.test.ts +340 -1
  478. package/src/index.ts +876 -57
  479. package/src/market/git-file-writer.ts +20 -19
  480. package/src/market/github-repos.test.ts +23 -0
  481. package/src/market/github-repos.ts +37 -19
  482. package/src/market/index-parser.ts +31 -30
  483. package/src/market/messages-market.ts +325 -0
  484. package/src/market/my-repo.ts +32 -29
  485. package/src/market/prepare.ts +18 -15
  486. package/src/market/security.ts +20 -19
  487. package/src/market/types.ts +2 -1
  488. package/src/market/url.ts +2 -1
  489. package/src/migrations/index.ts +6 -5
  490. package/src/migrations/messages-migrations.ts +59 -0
  491. package/src/profiles/dsh-profile-launcher.ts +2 -1
  492. package/src/profiles/dsh-profile-runtime.ts +2 -1
  493. package/src/profiles/messages.ts +31 -0
  494. package/src/routes/backup.ts +18 -2
  495. package/src/routes/import.ts +3 -3
  496. package/src/routes/index.ts +1 -1
  497. package/src/routes/kit.ts +9 -3
  498. package/src/routes/market.ts +1 -1
  499. package/src/routes/messages.ts +106 -0
  500. package/src/routes/prefs.ts +31 -2
  501. package/src/routes/profiles.ts +12 -6
  502. package/src/routes/recovery.test.ts +405 -1
  503. package/src/routes/recovery.ts +477 -94
  504. package/src/routes/snapshots.ts +51 -4
  505. package/src/routes/sync.ts +82 -17
  506. package/src/schema/config.ts +53 -20
  507. package/src/schema/index.ts +7 -5
  508. package/src/schema/manifest-schema.test.ts +4 -4
  509. package/src/schema/manifest.ts +19 -18
  510. package/src/schema/messages.ts +120 -0
  511. package/src/schema/registry.test.ts +28 -7
  512. package/src/schema/section-registry.ts +96 -42
  513. package/src/schema/types.ts +2 -1
  514. package/src/schema/versions.ts +6 -5
  515. package/src/security/encryption.ts +16 -15
  516. package/src/security/integrity.ts +8 -7
  517. package/src/security/messages.ts +87 -0
  518. package/src/security/redaction.test.ts +17 -1
  519. package/src/security/redaction.ts +13 -0
  520. package/src/security/secret-scanner.ts +19 -12
  521. package/src/security/security.test.ts +47 -0
  522. package/src/security/vault.ts +2 -1
  523. package/src/security/zip-security.ts +4 -3
  524. package/src/sync/ancestor.ts +2 -1
  525. package/src/sync/autosync-config.ts +21 -0
  526. package/src/sync/autosync-scheduler.test.ts +63 -7
  527. package/src/sync/autosync-scheduler.ts +118 -78
  528. package/src/sync/backup-files.ts +3 -2
  529. package/src/sync/backup-scheduler.ts +6 -5
  530. package/src/sync/blob-store.ts +2 -1
  531. package/src/sync/git/git-transport.test.ts +170 -8
  532. package/src/sync/git/git-transport.ts +176 -2
  533. package/src/sync/github-auth.ts +10 -9
  534. package/src/sync/layout.ts +13 -12
  535. package/src/sync/messages.ts +153 -0
  536. package/src/sync/review-queue.ts +6 -5
  537. package/src/sync/s3/messages.ts +16 -0
  538. package/src/sync/s3/s3-providers.ts +9 -6
  539. package/src/sync/s3/s3-transport.ts +1 -1
  540. package/src/sync/s3/sigv4.ts +3 -1
  541. package/src/sync/snapshot-crypto.ts +6 -5
  542. package/src/sync/snapshot-json.ts +3 -2
  543. package/src/sync/sync-credentials.test.ts +119 -0
  544. package/src/sync/sync-engine-download-tombstone.test.ts +1 -1
  545. package/src/sync/sync-engine.test.ts +226 -8
  546. package/src/sync/sync-engine.ts +154 -52
  547. package/src/sync/sync-history.ts +7 -6
  548. package/src/sync/sync-selection.test.ts +12 -2
  549. package/src/sync/sync-selection.ts +18 -5
  550. package/src/sync/transport.test.ts +1 -0
  551. package/src/sync/ui-prefs.test.ts +44 -1
  552. package/src/sync/ui-prefs.ts +39 -0
  553. package/src/sync/webdav/webdav-transport.ts +4 -1
  554. package/src/ui/artifact-view.ts +4 -3
  555. package/src/ui/commands.test.ts +1 -0
  556. package/src/ui/commands.ts +11 -1
  557. package/src/ui/diff-view.test.ts +9 -1
  558. package/src/ui/diff-view.ts +22 -0
  559. package/src/ui/disk-usage-view.test.ts +113 -6
  560. package/src/ui/disk-usage-view.ts +63 -7
  561. package/src/ui/errors.ts +4 -3
  562. package/src/ui/export-flow.ts +26 -20
  563. package/src/ui/foreign-view.test.ts +43 -0
  564. package/src/ui/foreign-view.ts +30 -3
  565. package/src/ui/i18n.ts +131 -2
  566. package/src/ui/import-wizard.ts +18 -10
  567. package/src/ui/progress.ts +2 -2
  568. package/src/ui/report.ts +7 -6
  569. package/src/ui/rollback-view.test.ts +836 -0
  570. package/src/ui/rollback-view.ts +1405 -0
  571. package/src/ui/selection-model.test.ts +33 -1
  572. package/src/ui/selection-model.ts +53 -0
  573. package/src/ui/session-inventory-view.test.ts +109 -0
  574. package/src/ui/session-inventory-view.ts +138 -3
  575. package/src/ui/session-issue-labels.test.ts +51 -0
  576. package/src/ui/session-issue-labels.ts +70 -0
  577. package/src/ui/sync-settings-view.test.ts +36 -0
  578. package/src/ui/sync-settings-view.ts +49 -0
  579. package/src/ui/test-helpers.ts +2 -1
  580. package/src/ui/types.ts +10 -4
  581. package/src/utils/atomic-write.ts +6 -5
  582. package/src/utils/bundle-scan.test.ts +2 -2
  583. package/src/utils/bundle-scan.ts +12 -1
  584. package/src/utils/env-lock.ts +83 -49
  585. package/src/utils/json.ts +7 -5
  586. package/src/utils/messages-utils.ts +232 -0
  587. package/src/utils/proxy.test.ts +25 -0
  588. package/src/utils/proxy.ts +19 -5
  589. package/src/utils/recursive-walk.test.ts +43 -0
  590. package/src/utils/recursive-walk.ts +75 -1
  591. package/src/utils/session-log-repair.ts +10 -9
  592. package/src/utils/zip.ts +27 -26
  593. package/lib/core/checkpoint.d.ts +0 -362
  594. package/lib/core/checkpoint.js +0 -1309
  595. package/src/core/checkpoint.test.ts +0 -665
  596. package/src/core/checkpoint.ts +0 -1614
@@ -5,6 +5,7 @@
5
5
  import { parseJsonSafe } from '../utils/json.js';
6
6
  import { CURRENT_SCHEMA_VERSION } from './versions.js';
7
7
  import { SECTION_IDS } from './config.js';
8
+ import { schemaMsg } from './messages.js';
8
9
  export const MANIFEST_FILE = 'manifest.json';
9
10
  export const CHECKSUMS_FILE = 'integrity/checksums.json';
10
11
  export const EXPORTER_NAME = 'DSH Config Manager';
@@ -38,7 +39,7 @@ export function parseManifest(raw) {
38
39
  const issues = validateManifest(parsed);
39
40
  const errors = issues.filter((i) => i.severity === 'error');
40
41
  if (errors.length > 0) {
41
- throw new Error(`manifest.json 无效: ${errors.map((e) => e.message).join('; ')}`);
42
+ throw new Error(schemaMsg('schema.manifestInvalid', { issues: errors.map((e) => e.message).join('; ') }));
42
43
  }
43
44
  return parsed;
44
45
  }
@@ -46,63 +47,63 @@ export function parseManifest(raw) {
46
47
  export function validateManifest(m) {
47
48
  const issues = [];
48
49
  if (m === null || typeof m !== 'object') {
49
- return [{ path: '$', message: 'manifest 必须是对象', severity: 'error' }];
50
+ return [{ path: '$', message: schemaMsg('schema.manifestMustBeObject'), severity: 'error' }];
50
51
  }
51
52
  const obj = m;
52
53
  if (typeof obj['schemaVersion'] !== 'number') {
53
- issues.push({ path: 'schemaVersion', message: 'schemaVersion 必须是数字', severity: 'error' });
54
+ issues.push({ path: 'schemaVersion', message: schemaMsg('schema.schemaVersionMustBeNumber'), severity: 'error' });
54
55
  }
55
56
  const exporter = obj['exporter'];
56
57
  if (!exporter || typeof exporter !== 'object') {
57
- issues.push({ path: 'exporter', message: 'exporter 缺失', severity: 'error' });
58
+ issues.push({ path: 'exporter', message: schemaMsg('schema.exporterMissing'), severity: 'error' });
58
59
  }
59
60
  else {
60
61
  if (typeof exporter['name'] !== 'string')
61
- issues.push({ path: 'exporter.name', message: 'exporter.name 必须是字符串', severity: 'error' });
62
+ issues.push({ path: 'exporter.name', message: schemaMsg('schema.exporterNameMustBeString'), severity: 'error' });
62
63
  if (typeof exporter['version'] !== 'string')
63
- issues.push({ path: 'exporter.version', message: 'exporter.version 必须是字符串', severity: 'error' });
64
+ issues.push({ path: 'exporter.version', message: schemaMsg('schema.exporterVersionMustBeString'), severity: 'error' });
64
65
  }
65
66
  const source = obj['source'];
66
67
  if (!source || typeof source !== 'object') {
67
- issues.push({ path: 'source', message: 'source 缺失', severity: 'error' });
68
+ issues.push({ path: 'source', message: schemaMsg('schema.sourceMissing'), severity: 'error' });
68
69
  }
69
70
  else {
70
71
  if (typeof source['dshVersion'] !== 'string')
71
- issues.push({ path: 'source.dshVersion', message: 'source.dshVersion 必须是字符串', severity: 'error' });
72
+ issues.push({ path: 'source.dshVersion', message: schemaMsg('schema.sourceDshVersionMustBeString'), severity: 'error' });
72
73
  if (typeof source['platform'] !== 'string')
73
- issues.push({ path: 'source.platform', message: 'source.platform 必须是字符串', severity: 'error' });
74
+ issues.push({ path: 'source.platform', message: schemaMsg('schema.sourcePlatformMustBeString'), severity: 'error' });
74
75
  if (typeof source['arch'] !== 'string')
75
- issues.push({ path: 'source.arch', message: 'source.arch 必须是字符串', severity: 'error' });
76
+ issues.push({ path: 'source.arch', message: schemaMsg('schema.sourceArchMustBeString'), severity: 'error' });
76
77
  }
77
78
  if (typeof obj['exportedAt'] !== 'string' || Number.isNaN(Date.parse(obj['exportedAt']))) {
78
- issues.push({ path: 'exportedAt', message: 'exportedAt 必须是合法 ISO-8601 时间', severity: 'error' });
79
+ issues.push({ path: 'exportedAt', message: schemaMsg('schema.exportedAtInvalid'), severity: 'error' });
79
80
  }
80
81
  const sections = obj['sections'];
81
82
  if (!sections || typeof sections !== 'object') {
82
- issues.push({ path: 'sections', message: 'sections 缺失', severity: 'error' });
83
+ issues.push({ path: 'sections', message: schemaMsg('schema.sectionsMissing'), severity: 'error' });
83
84
  }
84
85
  else {
85
86
  for (const key of Object.keys(sections)) {
86
87
  if (!SECTION_IDS.includes(key)) {
87
- issues.push({ path: `sections.${key}`, message: `未知分区 "${key}"`, severity: 'warning' });
88
+ issues.push({ path: `sections.${key}`, message: schemaMsg('schema.unknownSection', { section: key }), severity: 'warning' });
88
89
  }
89
90
  if (typeof sections[key] !== 'boolean') {
90
- issues.push({ path: `sections.${key}`, message: `sections.${key} 必须是布尔`, severity: 'error' });
91
+ issues.push({ path: `sections.${key}`, message: schemaMsg('schema.sectionFlagMustBeBoolean', { section: key }), severity: 'error' });
91
92
  }
92
93
  }
93
94
  }
94
95
  const security = obj['security'];
95
96
  if (!security || typeof security !== 'object') {
96
- issues.push({ path: 'security', message: 'security 缺失', severity: 'error' });
97
+ issues.push({ path: 'security', message: schemaMsg('schema.securityMissing'), severity: 'error' });
97
98
  }
98
99
  else {
99
100
  if (typeof security['containsSecrets'] !== 'boolean')
100
- issues.push({ path: 'security.containsSecrets', message: 'containsSecrets 必须是布尔', severity: 'error' });
101
+ issues.push({ path: 'security.containsSecrets', message: schemaMsg('schema.containsSecretsMustBeBoolean'), severity: 'error' });
101
102
  if (typeof security['encrypted'] !== 'boolean')
102
- issues.push({ path: 'security.encrypted', message: 'encrypted 必须是布尔', severity: 'error' });
103
+ issues.push({ path: 'security.encrypted', message: schemaMsg('schema.encryptedMustBeBoolean'), severity: 'error' });
103
104
  const enc = security['encryption'];
104
105
  if (enc !== null && (typeof enc !== 'object' || enc === undefined)) {
105
- issues.push({ path: 'security.encryption', message: 'encryption 必须是对象或 null', severity: 'error' });
106
+ issues.push({ path: 'security.encryption', message: schemaMsg('schema.encryptionMustBeObjectOrNull'), severity: 'error' });
106
107
  }
107
108
  }
108
109
  return issues;
@@ -0,0 +1,47 @@
1
+ import type { MsgParams } from '../core/msg-types.ts';
2
+ export declare const zh: {
3
+ readonly 'schema.sectionDataInvalid': '分区 {section} 数据无效: {issues}';
4
+ readonly 'schema.sectionDataMustBeObject': '分区 {section} 数据必须是对象';
5
+ readonly 'schema.sectionUnregistered': '未注册分区 {section}:拒绝校验(新增分区须在 schema/section-registry.ts 注册)';
6
+ readonly 'schema.namespacesMissing': '分区 {section} 缺少 namespaces 对象';
7
+ readonly 'schema.namespaceRecordMustBeObject': 'namespace 记录必须是对象';
8
+ readonly 'schema.revisionMustBeNumber': 'revision 必须是数字';
9
+ readonly 'schema.valueMissing': '缺少 value';
10
+ readonly 'schema.secretsMustBeArray': 'secrets 必须是数组';
11
+ readonly 'schema.objectMissing': '缺少 {key} 对象';
12
+ readonly 'schema.keyMustBeArray': '{key} 必须是数组';
13
+ readonly 'schema.patchFileEntryMustBeObject': 'patch 文件条目必须是对象';
14
+ readonly 'schema.patchFilePathUnsafe': 'patch 文件路径必须是安全的相对路径(不得为绝对路径或含 ..)';
15
+ readonly 'schema.patchFileContentMustBeBase64': 'patch 文件内容必须是 base64 字符串';
16
+ readonly 'schema.fileEntryMustBeObject': '文件条目必须是对象';
17
+ readonly 'schema.filePathUnsafe': '文件路径必须是安全的相对路径(不得为绝对路径或含 ..)';
18
+ readonly 'schema.sectionNoJsonPayload': '分区 {section} 无 JSON 载荷(凭据值走独立加密容器,不参与分区 JSON 校验)';
19
+ readonly 'schema.unhandledPayloadKind': '未处理的分区载荷形态 {payload}';
20
+ readonly 'schema.manifestInvalid': 'manifest.json 无效: {issues}';
21
+ readonly 'schema.manifestMustBeObject': 'manifest 必须是对象';
22
+ readonly 'schema.schemaVersionMustBeNumber': 'schemaVersion 必须是数字';
23
+ readonly 'schema.exporterMissing': 'exporter 缺失';
24
+ readonly 'schema.exporterNameMustBeString': 'exporter.name 必须是字符串';
25
+ readonly 'schema.exporterVersionMustBeString': 'exporter.version 必须是字符串';
26
+ readonly 'schema.sourceMissing': 'source 缺失';
27
+ readonly 'schema.sourceDshVersionMustBeString': 'source.dshVersion 必须是字符串';
28
+ readonly 'schema.sourcePlatformMustBeString': 'source.platform 必须是字符串';
29
+ readonly 'schema.sourceArchMustBeString': 'source.arch 必须是字符串';
30
+ readonly 'schema.exportedAtInvalid': 'exportedAt 必须是合法 ISO-8601 时间';
31
+ readonly 'schema.sectionsMissing': 'sections 缺失';
32
+ readonly 'schema.unknownSection': '未知分区 "{section}"';
33
+ readonly 'schema.sectionFlagMustBeBoolean': 'sections.{section} 必须是布尔';
34
+ readonly 'schema.securityMissing': 'security 缺失';
35
+ readonly 'schema.containsSecretsMustBeBoolean': 'containsSecrets 必须是布尔';
36
+ readonly 'schema.encryptedMustBeBoolean': 'encrypted 必须是布尔';
37
+ readonly 'schema.encryptionMustBeObjectOrNull': 'encryption 必须是对象或 null';
38
+ readonly 'schema.versionTooNew': 'schema v{version}(高于当前 {current},需升级插件)';
39
+ readonly 'schema.versionNeedsMigration': 'schema v{version}(旧版,将迁移到 v{current})';
40
+ readonly 'schema.versionCurrent': 'schema v{version}(当前版本)';
41
+ readonly 'schema.versionBelowMinimum': 'schema v{version}(低于最低支持 {minimum},不受支持)';
42
+ readonly 'schema.sectionDataVersionMismatch': '分区 {section} 的 version 必须为 {expected}(收到 {actual})';
43
+ readonly 'schema.sectionNotRegistered': '未注册分区「{section}」:拒绝按其它分区语义处理;新增分区必须在 src/schema/section-registry.ts 注册';
44
+ };
45
+ export declare const en: Record<keyof typeof zh, string>;
46
+ /** 本域翻译器:key 受目录约束(拼错键 = 编译错误),语言按 engineMsg 的活语言解析。 */
47
+ export declare function schemaMsg(key: keyof typeof zh, params?: MsgParams): string;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * schema 层的领域消息目录(zh 源 / en 镜像)—— 经 engineMsg 取「调用期」语言文案。
3
+ *
4
+ * 为什么是本域独立目录:src/schema/** 的写作用域不含 src/core/messages.ts(既有键有冻结指纹),
5
+ * 所以本域的键用 registerMessageCatalog 在**模块加载时**注册进引擎目录,查找顺序见
6
+ * src/core/engine-locale.ts(基础目录 → 注册目录 → 键名)。
7
+ *
8
+ * 纪律(与 src/core/messages.ts 同口径):
9
+ * - zh 值 = 迁移前的既有中文文案**逐字不变**(既有测试断言依赖);
10
+ * - en 类型为 Record<keyof typeof zh, string> —— 缺键/多键即编译错误;
11
+ * - {param} 插值与缺参保留由 engineMsg 负责;
12
+ * - 只追加键,不改既有键。
13
+ */
14
+ import { engineMsg, registerMessageCatalog } from '../core/engine-locale.js';
15
+ export const zh = {
16
+ // ---------- 分区 JSON 结构校验(config.ts) ----------
17
+ 'schema.sectionDataInvalid': '分区 {section} 数据无效: {issues}',
18
+ 'schema.sectionDataMustBeObject': '分区 {section} 数据必须是对象',
19
+ 'schema.sectionUnregistered': '未注册分区 {section}:拒绝校验(新增分区须在 schema/section-registry.ts 注册)',
20
+ 'schema.namespacesMissing': '分区 {section} 缺少 namespaces 对象',
21
+ 'schema.namespaceRecordMustBeObject': 'namespace 记录必须是对象',
22
+ 'schema.revisionMustBeNumber': 'revision 必须是数字',
23
+ 'schema.valueMissing': '缺少 value',
24
+ 'schema.secretsMustBeArray': 'secrets 必须是数组',
25
+ 'schema.objectMissing': '缺少 {key} 对象',
26
+ 'schema.keyMustBeArray': '{key} 必须是数组',
27
+ 'schema.patchFileEntryMustBeObject': 'patch 文件条目必须是对象',
28
+ 'schema.patchFilePathUnsafe': 'patch 文件路径必须是安全的相对路径(不得为绝对路径或含 ..)',
29
+ 'schema.patchFileContentMustBeBase64': 'patch 文件内容必须是 base64 字符串',
30
+ 'schema.fileEntryMustBeObject': '文件条目必须是对象',
31
+ 'schema.filePathUnsafe': '文件路径必须是安全的相对路径(不得为绝对路径或含 ..)',
32
+ 'schema.sectionNoJsonPayload': '分区 {section} 无 JSON 载荷(凭据值走独立加密容器,不参与分区 JSON 校验)',
33
+ 'schema.unhandledPayloadKind': '未处理的分区载荷形态 {payload}',
34
+ // ---------- manifest 结构校验(manifest.ts) ----------
35
+ 'schema.manifestInvalid': 'manifest.json 无效: {issues}',
36
+ 'schema.manifestMustBeObject': 'manifest 必须是对象',
37
+ 'schema.schemaVersionMustBeNumber': 'schemaVersion 必须是数字',
38
+ 'schema.exporterMissing': 'exporter 缺失',
39
+ 'schema.exporterNameMustBeString': 'exporter.name 必须是字符串',
40
+ 'schema.exporterVersionMustBeString': 'exporter.version 必须是字符串',
41
+ 'schema.sourceMissing': 'source 缺失',
42
+ 'schema.sourceDshVersionMustBeString': 'source.dshVersion 必须是字符串',
43
+ 'schema.sourcePlatformMustBeString': 'source.platform 必须是字符串',
44
+ 'schema.sourceArchMustBeString': 'source.arch 必须是字符串',
45
+ 'schema.exportedAtInvalid': 'exportedAt 必须是合法 ISO-8601 时间',
46
+ 'schema.sectionsMissing': 'sections 缺失',
47
+ 'schema.unknownSection': '未知分区 "{section}"',
48
+ 'schema.sectionFlagMustBeBoolean': 'sections.{section} 必须是布尔',
49
+ 'schema.securityMissing': 'security 缺失',
50
+ 'schema.containsSecretsMustBeBoolean': 'containsSecrets 必须是布尔',
51
+ 'schema.encryptedMustBeBoolean': 'encrypted 必须是布尔',
52
+ 'schema.encryptionMustBeObjectOrNull': 'encryption 必须是对象或 null',
53
+ // ---------- 版本描述(versions.ts) ----------
54
+ 'schema.versionTooNew': 'schema v{version}(高于当前 {current},需升级插件)',
55
+ 'schema.versionNeedsMigration': 'schema v{version}(旧版,将迁移到 v{current})',
56
+ 'schema.versionCurrent': 'schema v{version}(当前版本)',
57
+ 'schema.versionBelowMinimum': 'schema v{version}(低于最低支持 {minimum},不受支持)',
58
+ 'schema.sectionDataVersionMismatch': '分区 {section} 的 version 必须为 {expected}(收到 {actual})',
59
+ // ---------- 分区注册表(section-registry.ts) ----------
60
+ 'schema.sectionNotRegistered': '未注册分区「{section}」:拒绝按其它分区语义处理;新增分区必须在 src/schema/section-registry.ts 注册',
61
+ };
62
+ export const en = {
63
+ 'schema.sectionDataInvalid': 'Section {section} has invalid data: {issues}',
64
+ 'schema.sectionDataMustBeObject': 'Section {section} data must be an object',
65
+ 'schema.sectionUnregistered': 'Unregistered section {section}: refusing validation (register new sections in schema/section-registry.ts)',
66
+ 'schema.namespacesMissing': 'Section {section} is missing the namespaces object',
67
+ 'schema.namespaceRecordMustBeObject': 'Namespace record must be an object',
68
+ 'schema.revisionMustBeNumber': 'revision must be a number',
69
+ 'schema.valueMissing': 'missing value',
70
+ 'schema.secretsMustBeArray': 'secrets must be an array',
71
+ 'schema.objectMissing': 'missing {key} object',
72
+ 'schema.keyMustBeArray': '{key} must be an array',
73
+ 'schema.patchFileEntryMustBeObject': 'patch file entry must be an object',
74
+ 'schema.patchFilePathUnsafe': 'patch file path must be a safe relative path (no absolute paths, no ..)',
75
+ 'schema.patchFileContentMustBeBase64': 'patch file content must be a base64 string',
76
+ 'schema.fileEntryMustBeObject': 'file entry must be an object',
77
+ 'schema.filePathUnsafe': 'file path must be a safe relative path (no absolute paths, no ..)',
78
+ 'schema.sectionNoJsonPayload': 'Section {section} has no JSON payload (credential values use a separate encrypted container and are not part of section JSON validation)',
79
+ 'schema.unhandledPayloadKind': 'Unhandled section payload kind {payload}',
80
+ 'schema.manifestInvalid': 'manifest.json is invalid: {issues}',
81
+ 'schema.manifestMustBeObject': 'manifest must be an object',
82
+ 'schema.schemaVersionMustBeNumber': 'schemaVersion must be a number',
83
+ 'schema.exporterMissing': 'exporter is missing',
84
+ 'schema.exporterNameMustBeString': 'exporter.name must be a string',
85
+ 'schema.exporterVersionMustBeString': 'exporter.version must be a string',
86
+ 'schema.sourceMissing': 'source is missing',
87
+ 'schema.sourceDshVersionMustBeString': 'source.dshVersion must be a string',
88
+ 'schema.sourcePlatformMustBeString': 'source.platform must be a string',
89
+ 'schema.sourceArchMustBeString': 'source.arch must be a string',
90
+ 'schema.exportedAtInvalid': 'exportedAt must be a valid ISO-8601 time',
91
+ 'schema.sectionsMissing': 'sections is missing',
92
+ 'schema.unknownSection': 'Unknown section "{section}"',
93
+ 'schema.sectionFlagMustBeBoolean': 'sections.{section} must be a boolean',
94
+ 'schema.securityMissing': 'security is missing',
95
+ 'schema.containsSecretsMustBeBoolean': 'containsSecrets must be a boolean',
96
+ 'schema.encryptedMustBeBoolean': 'encrypted must be a boolean',
97
+ 'schema.encryptionMustBeObjectOrNull': 'encryption must be an object or null',
98
+ 'schema.versionTooNew': 'schema v{version} (newer than the current {current}; update the plugin)',
99
+ 'schema.versionNeedsMigration': 'schema v{version} (old version, will be migrated to v{current})',
100
+ 'schema.versionCurrent': 'schema v{version} (current version)',
101
+ 'schema.versionBelowMinimum': 'schema v{version} (below the minimum supported {minimum}; unsupported)',
102
+ 'schema.sectionDataVersionMismatch': 'Section {section} version must be {expected} (got {actual})',
103
+ 'schema.sectionNotRegistered': 'Unregistered section "{section}": refusing to treat it as another section; new sections must be registered in src/schema/section-registry.ts',
104
+ };
105
+ registerMessageCatalog({ id: 'schema', zh, en });
106
+ /** 本域翻译器:key 受目录约束(拼错键 = 编译错误),语言按 engineMsg 的活语言解析。 */
107
+ export function schemaMsg(key, params) {
108
+ return engineMsg(key, params);
109
+ }
110
+ //# sourceMappingURL=messages.js.map
@@ -16,7 +16,7 @@
16
16
  * 此前写死的注册表锚点已与实测不符、复核后纠正;实测命令见下):
17
17
  * - `schema/section-registry.ts` 的 `SECTION_REGISTRY: Record<SectionId, SectionMeta>`(报错落在该声明处)——
18
18
  * 缺 id → TS2741;该条目需逐项填 displayName / group / payload(zipPath 或 filePrefix)/ dataVersion /
19
- * applyOrder / portability / optInSync / defaultIncluded / **riskTier** / **configSnapshot**;
19
+ * applyOrder / portability / syncOptIn / defaultIncluded / **riskTier** / **configSnapshot**;
20
20
  * - `core/backup.ts` 的 `const unhandled: never = target.adapter` 穷尽 switch → TS2322;
21
21
  * - `client/common/section-labels.ts` 的 `SECTION_LABEL_KEY: Record<SectionId, ConfigManagerKey>` i18n 标签 → TS2741;
22
22
  * - `ui/export-flow.ts` 的 `CATEGORY_DESCRIPTIONS: Record<Exclude<SectionId,'secrets'>, string>` → TS2741;
@@ -42,8 +42,10 @@
42
42
  * `PORTABLE_SECTION_IDS` / … / sync/risk.ts 的 `SECTION_RISK_TIER`);
43
43
  * 同一事实只允许存在一份字面量(载荷版本收敛为 `SECTION_DATA_VERSION`,
44
44
  * 风险分级收敛为各条目的 `riskTier`);
45
- * e. **未注册分区不静默**:`sectionMetaOf` / `requireSectionMeta` 让运行期拿到未注册 id 时
46
- * 显式失败(`validateSectionData` 已按此实现),绝不落到某个 default 分支按其它分区语义处理
45
+ * e. **未注册分区不静默**:`sectionMetaOf`(本文件)与 `requireSectionMeta`(t7 起迁到
46
+ * `config.ts` —— 用户可见文案必须走消息目录,而本文件受「只 import 一个类型」的零依赖铁律约束)
47
+ * 让运行期拿到未注册 id 时显式失败(`validateSectionData` 已按此实现),
48
+ * 绝不落到某个 default 分支按其它分区语义处理
47
49
  * (历史缺陷在 `core/backup.ts` 的 `engineSnapshotEntry` default 分支;
48
50
  * 修复与回归用例见 `core/config-snapshot.ts:430` 附近与 `core/config-snapshot.test.ts`)。
49
51
  *
@@ -51,13 +53,15 @@
51
53
  * - 需要「分区集合」→ `SECTION_IDS`(按 applyOrder 升序,与历史数组逐项一致);
52
54
  * - 需要 ZIP 路径 → `jsonPathOf(id)`(null = 该分区无 JSON 载荷)或 `SECTION_JSON_PATHS`;
53
55
  * - 需要文件类目录前缀 → `filePrefixOf(id)`(null = 非文件类)或 `SECTION_FILE_PREFIXES`;
54
- * - 需要 portability → `sectionMeta(id).portability`;需要同步可选分区 → `OPT_IN_SYNC_SECTION_IDS`;
56
+ * - 需要 portability → `sectionMeta(id).portability`;需要同步可选分区 → `OPT_IN_SYNC_SECTION_IDS`
57
+ * (其中允许自动同步的子集 → `AUTO_SYNC_OPT_IN_SECTION_IDS`);
55
58
  * - 需要「快速导出默认勾选」→ `DEFAULT_INCLUDED_SECTION_IDS`;
56
59
  * - 需要灾备(配置状态快照)采集口径 → `CONFIG_SNAPSHOT_SECTION_IDS`;
57
60
  * - 需要风险等级 → `sectionMeta(id).riskTier`(sync 侧经 `riskTierOf(id)`;未注册 → undefined → 待审);
58
61
  * - 需要校验分区载荷 version → `versions.ts` 的 `isSupportedSectionDataVersion` /
59
62
  * `sectionDataVersionIssue`(唯一校验函数),或直接比对 `sectionMeta(id).dataVersion`;
60
- * - 需要「拿不到就显式报错」→ `requireSectionMeta(id)`(throw)/ `sectionMetaOf(value)`(null)。
63
+ * - 需要「拿不到就显式报错」→ `requireSectionMeta(id)`(throw;t7 起由 `config.ts` 导出)/
64
+ * `sectionMetaOf(value)`(null)。
61
65
  *
62
66
  * 注意:本模块的分区 id 联合仍在 `types.ts`(保持对既有 import 路径零破坏);本文件只依赖它的类型。
63
67
  */
@@ -70,6 +74,12 @@ export type SectionPortability = 'portable' | 'deviceSpecific' | 'platformSpecif
70
74
  * 这是**产品决策**,因此与其它分区事实一样必须逐分区显式表态(t34 起并入 SectionMeta)。
71
75
  */
72
76
  export type SectionRiskTier = 'low' | 'medium' | 'high';
77
+ /**
78
+ * 同步准入档位(见 \`SectionMeta.syncOptIn\`):
79
+ * 'off' = 不进同步通道;'manual' = 显式勾选且**只跟随手动 push/pull**;
80
+ * 'auto' = 显式勾选后手动与自动同步都带。
81
+ */
82
+ export type SectionSyncOptIn = 'off' | 'manual' | 'auto';
73
83
  /**
74
84
  * 分区载荷形态(决定 ZIP 内表示 + 结构校验方式)。
75
85
  * 判别联合 + 穷尽 switch = 新增载荷形态会在编译期被 `validateSectionData` 发现。
@@ -134,8 +144,16 @@ export interface SectionMeta {
134
144
  readonly applyOrder: number;
135
145
  /** 可移植性(同步/分享/市场据此过滤) */
136
146
  readonly portability: SectionPortability;
137
- /** 同步「可选分区」:永不默认进入同步通道,必须推/拉两侧显式放行(当前仅 sessions) */
138
- readonly optInSync: boolean;
147
+ /**
148
+ * 同步准入档位(非 portable 分区的显式准入;portable 分区恒为 'off',走默认通道)。
149
+ * - 'off' = 永不进入同步通道;
150
+ * - 'manual' = 必须用户在同步分区弹窗里显式勾选,且**只跟随用户驱动的手动 push/pull**;
151
+ * 自动同步永不带(内容隐私 / 设备相关,例如 sessions);
152
+ * - 'auto' = 用户显式勾选后,手动与自动同步都带(内容可跨机,只是命令 / 路径可能与
153
+ * 目标机不同,例如 mcp)。
154
+ * **必填**(Record<SectionId, SectionMeta> 强制):新增分区漏填即 tsc 报错。
155
+ */
156
+ readonly syncOptIn: SectionSyncOptIn;
139
157
  /** 快速导出(Quick Export)默认勾选(deviceSpecific 分区即使 true 也不会被推荐) */
140
158
  readonly defaultIncluded: boolean;
141
159
  /**
@@ -154,7 +172,7 @@ export interface SectionMeta {
154
172
  */
155
173
  readonly configSnapshot: boolean;
156
174
  }
157
- /** 分区载荷版本:当前 15 个分区统一为 1(唯一字面量;分区可独立升级时只改对应条目的引用) */
175
+ /** 分区载荷版本:当前 17 个分区统一为 1(唯一字面量;分区可独立升级时只改对应条目的引用) */
158
176
  export declare const SECTION_DATA_VERSION: 1;
159
177
  /**
160
178
  * 分区注册表(**Record<SectionId, SectionMeta>**:漏注册/写错 id → 编译失败)。
@@ -164,7 +182,9 @@ export declare const SECTION_DATA_VERSION: 1;
164
182
  * - `portability` / `defaultIncluded` ← 各 adapter 的 `portability` / `defaultIncluded`,
165
183
  * 以及 `ui/export-flow.ts` 的内置目录、`market/prepare.ts` 的 SECTION_PORTABILITY
166
184
  * (三者此前必须人工保持一致,现以本表为源);
167
- * - `optInSync` ← `sync/sync-selection.ts` 的 OPT_IN_SYNC_SECTIONS(当前仅 sessions);
185
+ * - `syncOptIn` ← **本表声明**(mcp='auto' / sessions='manual' / 其余 'off'),
186
+ * `sync/sync-selection.ts` 的 OPT_IN_SYNC_SECTIONS 与 `AUTO_SYNC_OPT_IN_SECTION_IDS` 都是它的派生视图
187
+ * (此前是两份手写字面量、零护栏 —— issue #78 收敛为单一事实源);
168
188
  * - `applyOrder` ← 历史 SECTION_IDS 数组顺序(1 起,连续)。
169
189
  */
170
190
  export declare const SECTION_REGISTRY: Record<SectionId, SectionMeta>;
@@ -174,11 +194,6 @@ export declare const SECTION_IDS: readonly SectionId[];
174
194
  export declare function sectionMetaOf(value: unknown): SectionMeta | null;
175
195
  /** 类型安全的元数据读取(id 已是 SectionId) */
176
196
  export declare function sectionMeta(id: SectionId): SectionMeta;
177
- /**
178
- * 拿不到元数据就**显式失败**(绝不让未注册分区按其它分区语义继续)。
179
- * core 侧修正「未知分区静默记成 settingsNamespace」时用它替代 default 分支。
180
- */
181
- export declare function requireSectionMeta(id: string): SectionMeta;
182
197
  /** 该 id 是否是已注册分区(运行期守卫;配合 manifest 的未知键告警使用) */
183
198
  export declare function isSectionId(value: unknown): value is SectionId;
184
199
  /** ZIP 内 JSON 分区路径(null = 该分区无 JSON 载荷:文件类分区 / secrets) */
@@ -193,8 +208,20 @@ export declare const SECTION_JSON_PATHS: Partial<Record<SectionId, string>>;
193
208
  export declare const SECTION_FILE_PREFIXES: Partial<Record<SectionId, string>>;
194
209
  /** 可移植分区(同步/分享默认候选) */
195
210
  export declare const PORTABLE_SECTION_IDS: readonly SectionId[];
196
- /** 同步「可选分区」:永不默认进入同步通道,必须推/拉两侧显式放行(当前仅 sessions) */
211
+ /**
212
+ * 同步「可选分区」:非 portable、必须推/拉两侧显式放行的分区(syncOptIn !== 'off')。
213
+ * 当前 = ['mcp', 'sessions']。**顺序按 applyOrder**(mcp=5 在 sessions=14 之前)。
214
+ */
197
215
  export declare const OPT_IN_SYNC_SECTION_IDS: readonly SectionId[];
216
+ /**
217
+ * 「可选分区」里**允许参与自动同步**的子集(syncOptIn === 'auto')。
218
+ *
219
+ * 为什么必须单独一档:可选分区的准入理由不同 ——
220
+ * - sessions 是**内容隐私 / 设备相关**(high 风险,自动同步绝不带,绝不悄悄下行会话);
221
+ * - mcp 只是**命令 / 路径可能与目标机不同**(medium 风险,用户勾了就该跟着自动同步走)。
222
+ * 用一个布尔没法表达这层差别,会退化成「勾了 mcp 顺带放行 sessions」。
223
+ */
224
+ export declare const AUTO_SYNC_OPT_IN_SECTION_IDS: readonly SectionId[];
198
225
  /** 快速导出默认勾选的分区(deviceSpecific 仍需 UI 就地警示,见 export-flow) */
199
226
  export declare const DEFAULT_INCLUDED_SECTION_IDS: readonly SectionId[];
200
227
  /**
@@ -1,4 +1,4 @@
1
- /** 分区载荷版本:当前 15 个分区统一为 1(唯一字面量;分区可独立升级时只改对应条目的引用) */
1
+ /** 分区载荷版本:当前 17 个分区统一为 1(唯一字面量;分区可独立升级时只改对应条目的引用) */
2
2
  export const SECTION_DATA_VERSION = 1;
3
3
  /**
4
4
  * 分区注册表(**Record<SectionId, SectionMeta>**:漏注册/写错 id → 编译失败)。
@@ -8,7 +8,9 @@ export const SECTION_DATA_VERSION = 1;
8
8
  * - `portability` / `defaultIncluded` ← 各 adapter 的 `portability` / `defaultIncluded`,
9
9
  * 以及 `ui/export-flow.ts` 的内置目录、`market/prepare.ts` 的 SECTION_PORTABILITY
10
10
  * (三者此前必须人工保持一致,现以本表为源);
11
- * - `optInSync` ← `sync/sync-selection.ts` 的 OPT_IN_SYNC_SECTIONS(当前仅 sessions);
11
+ * - `syncOptIn` ← **本表声明**(mcp='auto' / sessions='manual' / 其余 'off'),
12
+ * `sync/sync-selection.ts` 的 OPT_IN_SYNC_SECTIONS 与 `AUTO_SYNC_OPT_IN_SECTION_IDS` 都是它的派生视图
13
+ * (此前是两份手写字面量、零护栏 —— issue #78 收敛为单一事实源);
12
14
  * - `applyOrder` ← 历史 SECTION_IDS 数组顺序(1 起,连续)。
13
15
  */
14
16
  export const SECTION_REGISTRY = {
@@ -21,7 +23,7 @@ export const SECTION_REGISTRY = {
21
23
  applyOrder: 1,
22
24
  riskTier: 'low',
23
25
  portability: 'portable',
24
- optInSync: false,
26
+ syncOptIn: 'off',
25
27
  defaultIncluded: true,
26
28
  configSnapshot: true,
27
29
  },
@@ -34,7 +36,7 @@ export const SECTION_REGISTRY = {
34
36
  applyOrder: 2,
35
37
  riskTier: 'low',
36
38
  portability: 'portable',
37
- optInSync: false,
39
+ syncOptIn: 'off',
38
40
  defaultIncluded: true,
39
41
  configSnapshot: true,
40
42
  },
@@ -47,7 +49,7 @@ export const SECTION_REGISTRY = {
47
49
  applyOrder: 3,
48
50
  riskTier: 'low',
49
51
  portability: 'portable',
50
- optInSync: false,
52
+ syncOptIn: 'off',
51
53
  defaultIncluded: true,
52
54
  configSnapshot: true,
53
55
  },
@@ -63,7 +65,7 @@ export const SECTION_REGISTRY = {
63
65
  applyOrder: 4,
64
66
  riskTier: 'medium',
65
67
  portability: 'portable',
66
- optInSync: false,
68
+ syncOptIn: 'off',
67
69
  defaultIncluded: true,
68
70
  configSnapshot: true,
69
71
  },
@@ -76,7 +78,10 @@ export const SECTION_REGISTRY = {
76
78
  applyOrder: 5,
77
79
  riskTier: 'medium',
78
80
  portability: 'platformSpecific',
79
- optInSync: false,
81
+ // issue #78:MCP 行只写 patch 行(导入期按层写回),按包安装的 stdio server
82
+ // (npx / uvx / pipx)配置本身可跨机 —— 只是命令 / cwd 可能与目标机不同,
83
+ // 由导入分析期 warning 提示。用户显式勾选后,手动与自动同步都带。
84
+ syncOptIn: 'auto',
80
85
  defaultIncluded: true,
81
86
  configSnapshot: true,
82
87
  },
@@ -89,7 +94,7 @@ export const SECTION_REGISTRY = {
89
94
  applyOrder: 6,
90
95
  riskTier: 'low',
91
96
  portability: 'portable',
92
- optInSync: false,
97
+ syncOptIn: 'off',
93
98
  defaultIncluded: true,
94
99
  configSnapshot: true,
95
100
  },
@@ -102,7 +107,7 @@ export const SECTION_REGISTRY = {
102
107
  applyOrder: 7,
103
108
  riskTier: 'low',
104
109
  portability: 'portable',
105
- optInSync: false,
110
+ syncOptIn: 'off',
106
111
  defaultIncluded: true,
107
112
  configSnapshot: true,
108
113
  },
@@ -115,7 +120,7 @@ export const SECTION_REGISTRY = {
115
120
  applyOrder: 8,
116
121
  riskTier: 'low',
117
122
  portability: 'portable',
118
- optInSync: false,
123
+ syncOptIn: 'off',
119
124
  defaultIncluded: true,
120
125
  configSnapshot: true,
121
126
  },
@@ -128,7 +133,7 @@ export const SECTION_REGISTRY = {
128
133
  applyOrder: 9,
129
134
  riskTier: 'low',
130
135
  portability: 'portable',
131
- optInSync: false,
136
+ syncOptIn: 'off',
132
137
  defaultIncluded: true,
133
138
  configSnapshot: true,
134
139
  },
@@ -141,20 +146,20 @@ export const SECTION_REGISTRY = {
141
146
  applyOrder: 10,
142
147
  riskTier: 'medium',
143
148
  portability: 'platformSpecific',
144
- optInSync: false,
149
+ syncOptIn: 'off',
145
150
  defaultIncluded: true,
146
151
  configSnapshot: true,
147
152
  },
148
153
  pluginFiles: {
149
154
  id: 'pluginFiles',
150
- displayName: 'Plugin Files',
155
+ displayName: "Other Plugins' Loose Files",
151
156
  group: 'extensions',
152
157
  payload: { kind: 'files', filePrefix: 'plugin-files/' },
153
158
  dataVersion: SECTION_DATA_VERSION,
154
159
  applyOrder: 11,
155
160
  riskTier: 'high',
156
161
  portability: 'deviceSpecific',
157
- optInSync: false,
162
+ syncOptIn: 'off',
158
163
  defaultIncluded: false,
159
164
  configSnapshot: true,
160
165
  },
@@ -167,7 +172,7 @@ export const SECTION_REGISTRY = {
167
172
  applyOrder: 12,
168
173
  riskTier: 'high',
169
174
  portability: 'deviceSpecific',
170
- optInSync: false,
175
+ syncOptIn: 'off',
171
176
  defaultIncluded: true,
172
177
  configSnapshot: true,
173
178
  },
@@ -181,7 +186,7 @@ export const SECTION_REGISTRY = {
181
186
  applyOrder: 13,
182
187
  riskTier: 'high',
183
188
  portability: 'deviceSpecific',
184
- optInSync: false,
189
+ syncOptIn: 'off',
185
190
  defaultIncluded: false,
186
191
  configSnapshot: false,
187
192
  },
@@ -194,23 +199,52 @@ export const SECTION_REGISTRY = {
194
199
  applyOrder: 14,
195
200
  riskTier: 'high',
196
201
  portability: 'deviceSpecific',
197
- optInSync: true,
202
+ syncOptIn: 'manual',
198
203
  defaultIncluded: false,
199
204
  configSnapshot: false,
200
205
  },
201
206
  self: {
202
207
  id: 'self',
203
- displayName: 'Plugin Self Config',
208
+ displayName: "This Plugin's Own Config",
204
209
  group: 'extensions',
205
210
  payload: { kind: 'files', filePrefix: 'self/' },
206
211
  dataVersion: SECTION_DATA_VERSION,
207
212
  applyOrder: 15,
208
213
  riskTier: 'low',
209
214
  portability: 'portable',
210
- optInSync: false,
215
+ syncOptIn: 'off',
211
216
  defaultIncluded: true,
212
217
  configSnapshot: true,
213
218
  },
219
+ pluginData: {
220
+ id: 'pluginData',
221
+ displayName: "Other Plugins' Data",
222
+ group: 'extensions',
223
+ payload: { kind: 'files', filePrefix: 'plugin-data/' },
224
+ dataVersion: SECTION_DATA_VERSION,
225
+ applyOrder: 16,
226
+ riskTier: 'high',
227
+ // 第三方插件的数据目录不在 DSH 的三个核心存储里:路径是「机器的 home 布局」而非配置内容,
228
+ // 换机后可能整个目录不存在(未安装该插件)→ deviceSpecific + 不参与自动同步。
229
+ portability: 'deviceSpecific',
230
+ syncOptIn: 'off',
231
+ defaultIncluded: false,
232
+ // 体量由用户数据主导(可能几百 MB),与 sessions 同理不进「配置状态」采集口径
233
+ configSnapshot: false,
234
+ },
235
+ pluginAssets: {
236
+ id: 'pluginAssets',
237
+ displayName: "Other Plugins' Large Files",
238
+ group: 'extensions',
239
+ payload: { kind: 'files', filePrefix: 'plugin-assets/' },
240
+ dataVersion: SECTION_DATA_VERSION,
241
+ applyOrder: 17,
242
+ riskTier: 'high',
243
+ portability: 'deviceSpecific',
244
+ syncOptIn: 'off',
245
+ defaultIncluded: false,
246
+ configSnapshot: false,
247
+ },
214
248
  };
215
249
  /** 分区 id(按 applyOrder 升序)——历史上与 SECTION_IDS 数组逐项一致 */
216
250
  export const SECTION_IDS = Object.keys(SECTION_REGISTRY)
@@ -227,17 +261,6 @@ export function sectionMetaOf(value) {
227
261
  export function sectionMeta(id) {
228
262
  return SECTION_REGISTRY[id];
229
263
  }
230
- /**
231
- * 拿不到元数据就**显式失败**(绝不让未注册分区按其它分区语义继续)。
232
- * core 侧修正「未知分区静默记成 settingsNamespace」时用它替代 default 分支。
233
- */
234
- export function requireSectionMeta(id) {
235
- const meta = sectionMetaOf(id);
236
- if (meta === null) {
237
- throw new Error(`未注册分区「${id}」:拒绝按其它分区语义处理;新增分区必须在 src/schema/section-registry.ts 注册`);
238
- }
239
- return meta;
240
- }
241
264
  /** 该 id 是否是已注册分区(运行期守卫;配合 manifest 的未知键告警使用) */
242
265
  export function isSectionId(value) {
243
266
  return sectionMetaOf(value) !== null;
@@ -266,8 +289,20 @@ export const SECTION_FILE_PREFIXES = Object.fromEntries(SECTION_IDS
266
289
  .filter((entry) => entry[1] !== null));
267
290
  /** 可移植分区(同步/分享默认候选) */
268
291
  export const PORTABLE_SECTION_IDS = SECTION_IDS.filter((id) => SECTION_REGISTRY[id].portability === 'portable');
269
- /** 同步「可选分区」:永不默认进入同步通道,必须推/拉两侧显式放行(当前仅 sessions) */
270
- export const OPT_IN_SYNC_SECTION_IDS = SECTION_IDS.filter((id) => SECTION_REGISTRY[id].optInSync);
292
+ /**
293
+ * 同步「可选分区」:非 portable、必须推/拉两侧显式放行的分区(syncOptIn !== 'off')。
294
+ * 当前 = ['mcp', 'sessions']。**顺序按 applyOrder**(mcp=5 在 sessions=14 之前)。
295
+ */
296
+ export const OPT_IN_SYNC_SECTION_IDS = SECTION_IDS.filter((id) => SECTION_REGISTRY[id].syncOptIn !== 'off');
297
+ /**
298
+ * 「可选分区」里**允许参与自动同步**的子集(syncOptIn === 'auto')。
299
+ *
300
+ * 为什么必须单独一档:可选分区的准入理由不同 ——
301
+ * - sessions 是**内容隐私 / 设备相关**(high 风险,自动同步绝不带,绝不悄悄下行会话);
302
+ * - mcp 只是**命令 / 路径可能与目标机不同**(medium 风险,用户勾了就该跟着自动同步走)。
303
+ * 用一个布尔没法表达这层差别,会退化成「勾了 mcp 顺带放行 sessions」。
304
+ */
305
+ export const AUTO_SYNC_OPT_IN_SECTION_IDS = SECTION_IDS.filter((id) => SECTION_REGISTRY[id].syncOptIn === 'auto');
271
306
  /** 快速导出默认勾选的分区(deviceSpecific 仍需 UI 就地警示,见 export-flow) */
272
307
  export const DEFAULT_INCLUDED_SECTION_IDS = SECTION_IDS.filter((id) => SECTION_REGISTRY[id].defaultIncluded);
273
308
  /**
@@ -11,7 +11,7 @@ export type Platform = 'win32' | 'darwin' | 'linux' | 'freebsd' | 'openbsd' | 'a
11
11
  * 明确不实现的分区(keybindings/workflows/commands)不在此列;
12
12
  * rules 已由 agentInstructions(~/.dsh/AGENTS.md,dsh-agent-instructions 全局指令)承接。
13
13
  */
14
- export type SectionId = 'settings' | 'ui' | 'providers' | 'plugins' | 'mcp' | 'prompts' | 'skills' | 'agentPresets' | 'agentInstructions' | 'workspaces' | 'pluginFiles' | 'credentialsStatus' | 'secrets' | 'sessions' | 'self';
14
+ export type SectionId = 'settings' | 'ui' | 'providers' | 'plugins' | 'mcp' | 'prompts' | 'skills' | 'agentPresets' | 'agentInstructions' | 'workspaces' | 'pluginFiles' | 'credentialsStatus' | 'secrets' | 'sessions' | 'self' | 'pluginData' | 'pluginAssets';
15
15
  /** 加密备份的算法参数(非秘密:salt/iv/authTag 仅用于解密与完整性校验) */
16
16
  export interface EncryptionInfo {
17
17
  algorithm: 'aes-256-gcm';