dsh-config-manager 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/lib/client.d.ts +84 -10
  2. package/lib/client.js +777 -145
  3. package/lib/client.js.map +1 -1
  4. package/lib/core/messages.d.ts +3 -0
  5. package/lib/core/messages.js +6 -0
  6. package/lib/core/messages.js.map +1 -1
  7. package/lib/index.d.ts +6 -0
  8. package/lib/index.js +125 -17
  9. package/lib/index.js.map +1 -1
  10. package/lib/sync/autosync-scheduler.js +25 -0
  11. package/lib/sync/autosync-scheduler.js.map +1 -1
  12. package/lib/sync/layout.js +5 -0
  13. package/lib/sync/layout.js.map +1 -1
  14. package/lib/sync/snapshot-crypto.d.ts +8 -0
  15. package/lib/sync/snapshot-crypto.js +37 -0
  16. package/lib/sync/snapshot-crypto.js.map +1 -0
  17. package/lib/sync/sync-config.d.ts +21 -4
  18. package/lib/sync/sync-config.js +86 -8
  19. package/lib/sync/sync-config.js.map +1 -1
  20. package/lib/sync/sync-engine.d.ts +24 -1
  21. package/lib/sync/sync-engine.js +74 -26
  22. package/lib/sync/sync-engine.js.map +1 -1
  23. package/lib/sync/sync-selection.d.ts +4 -0
  24. package/lib/sync/sync-selection.js +10 -1
  25. package/lib/sync/sync-selection.js.map +1 -1
  26. package/lib/sync/transport.d.ts +20 -5
  27. package/lib/sync/transport.js +16 -3
  28. package/lib/sync/transport.js.map +1 -1
  29. package/lib/sync/webdav/webdav-transport.d.ts +1 -1
  30. package/lib/sync/webdav/webdav-transport.js +6 -1
  31. package/lib/sync/webdav/webdav-transport.js.map +1 -1
  32. package/lib/ui/import-wizard.d.ts +3 -1
  33. package/lib/ui/import-wizard.js +5 -1
  34. package/lib/ui/import-wizard.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/client/ConfigManagerSection.tsx +37 -12
  37. package/src/client/about/AboutPanel.tsx +118 -0
  38. package/src/client/about/about-view.test.ts +91 -0
  39. package/src/client/about/about-view.ts +104 -0
  40. package/src/client/api.ts +50 -15
  41. package/src/client/common/ui.tsx +26 -2
  42. package/src/client/config-manager.module.css +27 -0
  43. package/src/client/export/ExportView.tsx +9 -7
  44. package/src/client/import/ImportWizardView.tsx +13 -4
  45. package/src/client/import/import-file-select.test.ts +52 -0
  46. package/src/client/import/import-file-select.ts +14 -0
  47. package/src/client/index.ts +4 -3
  48. package/src/client/locales.ts +31 -0
  49. package/src/client/sync/SyncSettingsView.tsx +302 -19
  50. package/src/client/sync/history-model.test.ts +1 -0
  51. package/src/client/sync/history-model.ts +1 -0
  52. package/src/client/sync/sync-api.test.ts +45 -0
  53. package/src/client/sync/sync-api.ts +41 -5
  54. package/src/client/sync/sync-locales.ts +34 -0
  55. package/src/core/messages.ts +6 -0
  56. package/src/index.sync.test.ts +37 -2
  57. package/src/index.ts +129 -20
  58. package/src/sync/ancestor.test.ts +7 -4
  59. package/src/sync/autosync-scheduler.test.ts +47 -0
  60. package/src/sync/autosync-scheduler.ts +25 -0
  61. package/src/sync/git/git-transport.test.ts +2 -2
  62. package/src/sync/layout.test.ts +13 -7
  63. package/src/sync/layout.ts +5 -0
  64. package/src/sync/snapshot-crypto.test.ts +57 -0
  65. package/src/sync/snapshot-crypto.ts +45 -0
  66. package/src/sync/sync-config.test.ts +96 -12
  67. package/src/sync/sync-config.ts +87 -9
  68. package/src/sync/sync-engine.test.ts +133 -7
  69. package/src/sync/sync-engine.ts +88 -27
  70. package/src/sync/sync-selection.test.ts +21 -3
  71. package/src/sync/sync-selection.ts +11 -1
  72. package/src/sync/transport.test.ts +4 -3
  73. package/src/sync/transport.ts +32 -7
  74. package/src/sync/webdav/webdav-transport.ts +7 -2
  75. package/src/ui/import-wizard.test.ts +37 -0
  76. package/src/ui/import-wizard.ts +4 -1
package/lib/client.d.ts CHANGED
@@ -574,6 +574,10 @@ interface DownloadResult {
574
574
  streamed: boolean;
575
575
  bytes: number;
576
576
  }
577
+ /** 下载选项:saveDialog=true 才弹系统保存对话框(需用户手势);缺省自动下载到浏览器下载目录 */
578
+ interface DownloadOptions {
579
+ saveDialog?: boolean;
580
+ }
577
581
  /**
578
582
  * Config Manager 浏览器半的唯一数据入口。
579
583
  * 同时实现 `ExportPort`(export-flow 用)与 `ImportPort`(import-wizard 用)。
@@ -594,10 +598,13 @@ declare class ConfigManagerApi {
594
598
  * 带 AbortController 超时:宿主若卡死,客户端得到明确错误而不是永远停在进度条。 */
595
599
  export(options: ExportOptions): Promise<ExportResponse>;
596
600
  /**
597
- * 把导出的 ZIP 下载到本机。优先 File System Access API 流式落盘
598
- * (不占整文件内存),不可用时回退内存 Blob(dsh-ssh downloadFile 同款策略)。
601
+ * 把导出的 ZIP 下载到本机。
602
+ * - 默认(saveDialog 缺省/false):读取为 Blob 后用 <a download> 触发浏览器
603
+ * 静默下载到「下载」目录,无需用户额外操作(导出完成即可自动调用);
604
+ * - saveDialog: true:优先 File System Access API 流式落盘(不占整文件内存),
605
+ * 用户可在系统保存对话框中选择位置;不可用/取消时回退 Blob 下载。
599
606
  */
600
- download(zipPath: string, onProgress?: (received: number, total: number) => void): Promise<DownloadResult>;
607
+ download(zipPath: string, opts?: DownloadOptions, onProgress?: (received: number, total: number) => void): Promise<DownloadResult>;
601
608
  /** 上传用户选择的 ZIP 到 Host 受控临时目录,返回可引用的 zipPath(dsh-ssh 同款原始字节上传) */
602
609
  upload(file: File): Promise<UploadResponse>;
603
610
  /** ImportPort.analyzeImport:零写入分析(校验/兼容性/差异/路径/秘密检测) */
@@ -663,14 +670,15 @@ type SyncTransportType = 'git' | 'webdav';
663
670
  /** GET /sync/status 响应:配置/凭据/上次同步的只读事实(无任何 secret 值) */
664
671
  interface SyncStatusResponse {
665
672
  ok: boolean;
666
- /** 是否已保存过仓库/通道配置(sync-config.json) */
673
+ /** 是否已保存过仓库/通道配置(sync-config.json;任一通道配置过即为 true) */
667
674
  configured: boolean;
668
- /** git 通道:上次使用的仓库地址(不含 token,可回显) */
675
+ /** git 通道:已配置的仓库地址(不含 token,可回显;与当前通道无关,配置过即返回) */
669
676
  repoUrl?: string;
670
677
  /** git 通道:DSH credentials 中是否已存在 token(describe 只报状态,值永不返回) */
671
678
  credentialConfigured: boolean;
672
679
  credentialWritable: boolean;
673
- /** webdav 通道:配置状态(url 可回显,username 非敏感;password 值永不返回) */
680
+ /** webdav 通道:配置状态(url 可回显,username 非敏感;password 值永不返回;
681
+ * 与当前通道无关,配置过即返回,供 git ↔ webdav 切换时回填表单) */
674
682
  webdav?: WebDavStatusResponse;
675
683
  /** sync-state.lastSyncAt;'' = 从未同步 */
676
684
  lastSyncAt?: string;
@@ -692,6 +700,10 @@ interface SyncSelectionPayload {
692
700
  mode: 'default' | 'advanced';
693
701
  /** 高级模式勾选分区;default 模式可为空数组 */
694
702
  sections: SectionId[];
703
+ /** 手动推送默认加密快照(密码每次推送输入,不持久化) */
704
+ encrypt?: boolean;
705
+ /** 手动推送默认导出真实凭据值(必须同时 encrypt) */
706
+ includeSecrets?: boolean;
695
707
  }
696
708
  /** webdav 通道状态字段(无任何 secret 值;password 只报 passwordConfigured 布尔) */
697
709
  interface WebDavStatusResponse {
@@ -704,6 +716,19 @@ interface WebDavStatusResponse {
704
716
  /** DSH credentials 中是否已存在密码(值永不返回) */
705
717
  passwordConfigured: boolean;
706
718
  }
719
+ /** POST /sync/config 响应:保存成功后的轻量凭据状态(无 secret 值;UI 直接合并刷新徽章)。 */
720
+ interface SyncConfigSaveResponse {
721
+ ok: boolean;
722
+ configured: boolean;
723
+ transport: SyncTransportType;
724
+ /** git 通道:token 是否已配置(值永不返回) */
725
+ credentialConfigured: boolean;
726
+ /** webdav 通道:username/password 是否已配置(值永不返回;git 通道为 undefined) */
727
+ webdav?: {
728
+ usernameConfigured: boolean;
729
+ passwordConfigured: boolean;
730
+ };
731
+ }
707
732
  /** 可同步分区条目(status.syncSections 项)。只含 portable —— 与 SyncEngine 同步通道一致。 */
708
733
  interface SyncSectionInfo {
709
734
  id: SectionId;
@@ -716,7 +741,8 @@ interface SyncSectionInfo {
716
741
  * 扁平形状与 Host parseSyncBody 一致:git 携带 repoUrl/token;
717
742
  * webdav 携带 url/username/password(顶层,不嵌套 webdav 对象)。
718
743
  * git 可执行文件固定使用系统 PATH 中的 git,不再接受自定义路径。
719
- * sections 可选(高级/自定义导出模式):只推送勾选分区;缺省 = 默认模式全部推荐分区。 */
744
+ * sections 可选(高级/自定义导出模式):只推送勾选分区;缺省 = 默认模式全部推荐分区。
745
+ * encrypt/encryptPassword/includeSecrets:加密快照(含可选密钥导出;密码仅内存传输,绝不落盘)。 */
720
746
  interface SyncPushPayload {
721
747
  /** 通道类型;缺省 'git' */
722
748
  transport?: SyncTransportType;
@@ -728,11 +754,20 @@ interface SyncPushPayload {
728
754
  password?: string;
729
755
  /** 仅同步指定分区(缺省 = 全部 portable 推荐分区;即「默认/快速导出」vs「高级/自定义导出」) */
730
756
  sections?: SectionId[];
731
- }
732
- /** pull 请求体(strategy 缺省 merge:冲突保留待决策;snapshotId 缺省 = 最新) */
757
+ /** 加密快照(sections 载荷整体加密;开启时必须提供 encryptPassword) */
758
+ encrypt?: boolean;
759
+ /** 加密密码(仅本次请求体内存传输,Host 绝不落盘/落日志;encrypt=true 时必填) */
760
+ encryptPassword?: string;
761
+ /** 导出真实凭据值(必须同时 encrypt=true,否则 Host 拒绝:密钥绝不明文进同步通道) */
762
+ includeSecrets?: boolean;
763
+ }
764
+ /** pull 请求体(strategy 缺省 merge:冲突保留待决策;snapshotId 缺省 = 最新;
765
+ * decryptPassword 可选:拉取加密快照时提供,仅内存传输)。 */
733
766
  interface SyncPullPayload extends SyncPushPayload {
734
767
  strategy?: 'merge' | 'replace' | 'skipExisting';
735
768
  snapshotId?: string;
769
+ /** 解密密码(拉取/一键同步遇到加密快照时提供;仅内存传输,绝不落盘) */
770
+ decryptPassword?: string;
736
771
  }
737
772
  /** GET /sync/snapshots-list 响应:远端历史快照列表(按 createdAt 倒序)。 */
738
773
  interface SyncSnapshotsListResponse {
@@ -948,6 +983,9 @@ declare class SyncApi {
948
983
  /** 保存同步分区选择(POST /sync/selection):模式 + 勾选分区持久化到 Host。
949
984
  * 自动同步调度器与手动 push 共用此配置(刷新/重启后仍然生效)。 */
950
985
  saveSelection(payload: SyncSelectionPayload): Promise<SyncSelectionPayload>;
986
+ /** 保存同步通道配置(POST /sync/config):url/username/password(git: repoUrl/token)持久化。
987
+ * password/token 经 Host 写入 DSH credentials(值永不回传);返回凭据布尔供 UI 刷新徽章。 */
988
+ saveConfig(payload: SyncPushPayload): Promise<SyncConfigSaveResponse>;
951
989
  /** 一键回滚:按 restoreId 调用 backup→rollback */
952
990
  rollback(payload: {
953
991
  restoreId: string;
@@ -1097,6 +1135,7 @@ declare const zh$2: {
1097
1135
  readonly 'view.snapshots': "快照恢复";
1098
1136
  readonly 'view.sync': "远程同步";
1099
1137
  readonly 'view.market': "配置市场";
1138
+ readonly 'view.about': "关于";
1100
1139
  readonly 'common.close': "关闭";
1101
1140
  readonly 'common.cancel': "取消";
1102
1141
  readonly 'common.back': "上一步";
@@ -1124,6 +1163,7 @@ declare const zh$2: {
1124
1163
  readonly 'export.run': "开始导出";
1125
1164
  readonly 'export.running': "正在导出…";
1126
1165
  readonly 'export.download': "下载备份文件";
1166
+ readonly 'export.saved': "已保存到下载目录:{name}";
1127
1167
  readonly 'export.selectionWarnings': "以下分区为设备相关数据,跨设备导入时可能不适用:";
1128
1168
  readonly 'export.group.unknown': "其他";
1129
1169
  readonly 'export.included': "已包含";
@@ -1220,6 +1260,19 @@ declare const zh$2: {
1220
1260
  readonly 'report.needsRestart': "插件 / MCP 变更将在重启 DSH 后生效。";
1221
1261
  readonly 'error.title': "操作失败";
1222
1262
  readonly 'error.hint': "错误消息已自动脱敏,不会泄露任何密钥信息。";
1263
+ readonly 'about.title': "关于 DSH Config Manager";
1264
+ readonly 'about.subtitle': "插件信息、作者与反馈入口";
1265
+ readonly 'about.official': "官方";
1266
+ readonly 'about.version': "版本 {version}";
1267
+ readonly 'about.dshVersion': "DSH {version}";
1268
+ readonly 'about.links': "相关链接";
1269
+ readonly 'about.star': "⭐ 在 GitHub 上点赞";
1270
+ readonly 'about.repo': "GitHub 仓库";
1271
+ readonly 'about.docs': "使用文档";
1272
+ readonly 'about.issues': "反馈问题";
1273
+ readonly 'about.authorLabel': "作者";
1274
+ readonly 'about.loading': "正在获取版本信息…";
1275
+ readonly 'about.retryStatus': "重新获取";
1223
1276
  };
1224
1277
  /** 字典键联合(注册处 compile-time 校验) */
1225
1278
  type ConfigManagerKey = keyof typeof zh$2;
@@ -1241,6 +1294,9 @@ declare const zh$1: {
1241
1294
  readonly 'config.tokenHint': "将安全写入 DSH credentials(引用名 {ref}),不会写入同步文件或日志。留空表示沿用已保存的凭据。";
1242
1295
  readonly 'config.tokenSaved': "凭据已配置";
1243
1296
  readonly 'config.tokenPlaceholder': "ghp_…(可选)";
1297
+ readonly 'config.save': "保存配置";
1298
+ readonly 'config.saving': "保存中…";
1299
+ readonly 'config.saveHint': "表单改动会自动保存(密码/token 安全写入 DSH credentials,不会写入同步文件或日志);也可点击按钮立即保存。";
1244
1300
  readonly 'channel.title': "同步通道";
1245
1301
  readonly 'channel.hint': "选择远程同步通道:Git 私有仓库或 WebDAV 服务器。";
1246
1302
  readonly 'channel.git': "Git 私有仓库";
@@ -1324,6 +1380,18 @@ declare const zh$1: {
1324
1380
  readonly 'mode.sectionPortable': "可移植";
1325
1381
  readonly 'mode.sectionRecommended': "推荐";
1326
1382
  readonly 'mode.persistHint': "模式与分区选择已保存到本机:自动同步和手动推送都会使用此配置(重启后仍生效)。";
1383
+ readonly 'mode.security': "加密与密钥导出(安全选项)";
1384
+ readonly 'mode.encrypt': "加密备份";
1385
+ readonly 'mode.encryptHint': "用密码加密同步快照(AES-256-GCM)。密码仅本次推送使用、绝不落盘;自动同步无法解密加密快照,会自动跳过并在同步历史中提示。";
1386
+ readonly 'mode.password': "加密密码";
1387
+ readonly 'mode.passwordConfirm': "确认密码";
1388
+ readonly 'mode.passwordMismatch': "两次输入的密码不一致";
1389
+ readonly 'mode.passwordRequired': "加密必须设置密码";
1390
+ readonly 'mode.includeSecrets': "导出密钥";
1391
+ readonly 'mode.includeSecretsHint': "把真实凭据值写入加密快照(勾选时自动选中加密;密钥绝不进入未加密快照)。";
1392
+ readonly 'mode.encryptAutosyncNotice': "加密快照仅通过手动推送/拉取使用;自动同步无密码,遇到加密快照会跳过并在历史中提示。";
1393
+ readonly 'mode.decryptPassword': "解密密码(加密快照拉取/同步用,可选)";
1394
+ readonly 'mode.decryptPasswordHint': "拉取或一键同步遇到加密快照时输入;不输入则加密快照无法读取(自动同步会跳过并在历史中提示)。";
1327
1395
  readonly 'autosync.title': "自动同步";
1328
1396
  readonly 'autosync.description': "开启后,DSH 在后台保持配置一致:本地配置有改动时自动上传,检测到远端有新快照时才自动拉取合并;定时器仅作兜底轮询,无变化不重复动作。仅在无冲突且无需人工干预时才自动写入本地。";
1329
1397
  readonly 'autosync.enable': "启用自动同步";
@@ -1469,6 +1537,12 @@ interface MarketPanelProps {
1469
1537
  t: TranslateNS<'config-manager-market'>;
1470
1538
  }
1471
1539
  //#endregion
1540
+ //#region src/client/about/AboutPanel.d.ts
1541
+ interface AboutPanelProps {
1542
+ api: ConfigManagerApi;
1543
+ t: TranslateNS<'config-manager'>;
1544
+ }
1545
+ //#endregion
1472
1546
  //#region src/client/index.d.ts
1473
1547
  declare module '@deepseek-ai/dsh-client-ui-slots' {
1474
1548
  interface LocaleNamespaceMap {
@@ -1488,7 +1562,7 @@ declare const inject: string[];
1488
1562
  */
1489
1563
  declare function apply(ctx: ClientContext): void;
1490
1564
  //#endregion
1491
- export { type ConfigManagerApiError, type ConfigManagerKey, type ConfigManagerSectionProps, type DownloadResult, type ExportViewProps, type ImportWizardViewProps, type MarketKey, type MarketPanelProps, type ServiceStatus, type SyncKey, type SyncSettingsViewProps, type UploadResponse, apply, inject };
1565
+ export { type AboutPanelProps, type ConfigManagerApiError, type ConfigManagerKey, type ConfigManagerSectionProps, type DownloadResult, type ExportViewProps, type ImportWizardViewProps, type MarketKey, type MarketPanelProps, type ServiceStatus, type SyncKey, type SyncSettingsViewProps, type UploadResponse, apply, inject };
1492
1566
 
1493
1567
  return module.exports;
1494
1568
  }