dsh-config-manager 0.1.25 → 0.1.27

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 (47) hide show
  1. package/README.md +6 -2
  2. package/README.zh-CN.md +6 -2
  3. package/lib/client.d.ts +29 -0
  4. package/lib/client.js +272 -106
  5. package/lib/client.js.map +1 -1
  6. package/lib/core/analyzer.js +7 -0
  7. package/lib/core/analyzer.js.map +1 -1
  8. package/lib/core/messages.d.ts +2 -0
  9. package/lib/core/messages.js +4 -0
  10. package/lib/core/messages.js.map +1 -1
  11. package/lib/core/types.d.ts +2 -0
  12. package/lib/core/types.js.map +1 -1
  13. package/lib/index.js +62 -5
  14. package/lib/index.js.map +1 -1
  15. package/lib/ui/flow.d.ts +1 -1
  16. package/lib/ui/i18n.d.ts +3 -0
  17. package/lib/ui/i18n.js +7 -0
  18. package/lib/ui/i18n.js.map +1 -1
  19. package/lib/ui/import-wizard.d.ts +4 -0
  20. package/lib/ui/import-wizard.js +9 -0
  21. package/lib/ui/import-wizard.js.map +1 -1
  22. package/lib/ui/test-helpers.d.ts +2 -0
  23. package/lib/ui/test-helpers.js +1 -0
  24. package/lib/ui/test-helpers.js.map +1 -1
  25. package/lib/ui/types.d.ts +2 -0
  26. package/lib/ui/types.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/client/api.ts +26 -1
  29. package/src/client/import/ImportWizardView.tsx +100 -4
  30. package/src/client/locales.ts +20 -0
  31. package/src/client/run-store.ts +32 -7
  32. package/src/client/sync/SyncSettingsView.tsx +9 -4
  33. package/src/client/sync/sync-locales.ts +2 -0
  34. package/src/client/sync/sync-view.test.ts +40 -3
  35. package/src/client/sync/sync-view.ts +10 -8
  36. package/src/core/analyzer.ts +8 -0
  37. package/src/core/messages.ts +4 -0
  38. package/src/core/types.ts +2 -0
  39. package/src/index.ts +61 -5
  40. package/src/security/security.test.ts +59 -0
  41. package/src/sync/sync-session.test.ts +3 -2
  42. package/src/ui/flow.ts +1 -1
  43. package/src/ui/i18n.ts +8 -1
  44. package/src/ui/import-wizard.test.ts +23 -0
  45. package/src/ui/import-wizard.ts +10 -0
  46. package/src/ui/test-helpers.ts +4 -3
  47. package/src/ui/types.ts +2 -0
package/README.md CHANGED
@@ -32,7 +32,7 @@ DSH is your AI assistant workbench — it holds your settings: model configs, pl
32
32
  | 👀 | **Preview before import** | Full preview first — **never touches your config silently** |
33
33
  | ⚔️ | **Conflict handling** | Keep Current / Use Imported — you decide |
34
34
  | 🗺️ | **Path auto-mapping** | Detects dead absolute paths and lets you remap them |
35
- | 🔒 | **Secret safety** | API Keys are never exported; re-enter them after import |
35
+ | 🔒 | **Secret safety** | API Keys are never exported; encrypted backups restore them with the password, non-encrypted imports ask you to re-enter |
36
36
  | ↩️ | **Automatic rollback** | Failed import restores everything automatically |
37
37
  | 📸 | **Snapshot restore** | Undo an import: whole-file restore + uninstall added plugins (CLI & GUI) |
38
38
  | 🔄 | **Remote Sync** | Push/pull portable config via a private Git repo (secrets never sync) |
@@ -178,7 +178,8 @@ When the target already has a same-named item, you choose:
178
178
  |---|---|
179
179
  | Default backup | **No secret values at all** — only records which keys are needed |
180
180
  | Encrypted backup (optional) | AES-256-GCM with a password; the password is **never written to the file** |
181
- | After import | "3 secrets need re-entry" values stay in memory only |
181
+ | Encrypted backup import | The export-time password is required: enter verify credentials are restored; **no password, no import** |
182
+ | After non-encrypted import | "3 secrets need re-entry" — values stay in memory only |
182
183
 
183
184
  ### 🗂️ Profiles
184
185
 
@@ -260,6 +261,9 @@ No. A checksum mismatch rejects the import outright (protects against corruption
260
261
  **Q: Will re-importing duplicate things?**
261
262
  No. Items are deduplicated by stable IDs (plugin ID / MCP name / skill name…); existing items are skipped.
262
263
 
264
+ **Q: Does importing an encrypted backup require the password?**
265
+ Yes. The import wizard asks for the export-time encryption password and verifies it before the import can proceed; the password is never saved — memory only. A wrong or missing password blocks the import (credentials are restored from the backup instead of being re-entered when the password is correct).
266
+
263
267
  ---
264
268
 
265
269
  ## 📋 Known limitations (user-facing)
package/README.zh-CN.md CHANGED
@@ -32,7 +32,7 @@ DSH 是你的 AI 助手工作台,里面存着你的各种设置:模型配置
32
32
  | 👀 | **先预览再导入** | 导入前完整预览,**绝不偷偷改你的配置** |
33
33
  | ⚔️ | **冲突处理** | 遇到同名配置,让你自己选:保留现有的 / 用导入的 |
34
34
  | 🗺️ | **路径自动映射** | 换了电脑路径变了?自动检测并让你重新指定 |
35
- | 🔒 | **密钥安全** | API Key 默认不导出;导入后提醒你重新填写 |
35
+ | 🔒 | **密钥安全** | API Key 默认不导出;加密备份用密码解锁恢复,非加密导入后提醒重新填写 |
36
36
  | ↩️ | **自动回滚** | 导入失败自动恢复原样,不会弄坏现有配置 |
37
37
  | 📸 | **快照恢复** | 撤销一次导入:整文件还原 + 卸载新增插件(CLI 与 GUI 均支持) |
38
38
  | 🔄 | **远程同步** | 通过 Git 私有仓库推送 / 拉取可移植配置(密钥永不参与同步) |
@@ -177,7 +177,8 @@ dsh plugin --profile web add dsh-config-manager@latest --config.auto-install-pee
177
177
  |---|---|
178
178
  | 默认备份 | **不含任何密钥值**,只记录"哪些密钥需要填写" |
179
179
  | 加密备份(可选) | 设置密码后用 AES-256-GCM 加密,密码**绝不写入备份文件** |
180
- | 导入后 | 提示「3 个密钥需要重新填写」,输入后仅保存在内存中写入 |
180
+ | 加密备份导入 | 必须输入导出时的加密密码解锁:输入→验证密码→凭据自动恢复,**无密码无法导入** |
181
+ | 非加密导入后 | 提示「3 个密钥需要重新填写」,输入后仅保存在内存中写入 |
181
182
 
182
183
  ### 🗂️ 配置档案(Profiles)
183
184
 
@@ -259,6 +260,9 @@ dsh-config-manager restore --id <snapshot-id>
259
260
  **Q:重复导入会重复吗?**
260
261
  不会。按插件 ID / MCP 名称 / 技能名等稳定标识去重,重复导入自动跳过已有项。
261
262
 
263
+ **Q:加密备份导入时需要密码吗?**
264
+ 需要。导入向导会要求输入导出时设置的加密密码并验证通过后才能继续执行;密码仅存于内存、绝不保存。密码错误或缺失都会阻止导入(密码正确时凭据直接从备份解密恢复,无需重新填写)。
265
+
262
266
  ---
263
267
 
264
268
  ## 📋 已知限制(用户须知)
package/lib/client.d.ts CHANGED
@@ -115,6 +115,8 @@ interface ImportAnalysis {
115
115
  item: string;
116
116
  dependency: string;
117
117
  }[];
118
+ /** 备份是否加密(manifest.security.encrypted):加密备份的凭据必须用解密密码恢复 */
119
+ encrypted: boolean;
118
120
  }
119
121
  interface ImportDecisions {
120
122
  strategy: GlobalConflictStrategy;
@@ -472,6 +474,9 @@ declare const uiZh: {
472
474
  readonly 'sync.interval.6h': "6 小时";
473
475
  readonly 'sync.interval.12h': "12 小时";
474
476
  readonly 'sync.interval.24h': "24 小时";
477
+ readonly 'sync.duration.min': "{n} 分钟";
478
+ readonly 'sync.duration.hour': "{n} 小时";
479
+ readonly 'sync.duration.day': "{n} 天";
475
480
  readonly 'sync.hist.autosync': "自动同步";
476
481
  readonly 'sync.hist.directionPull': "下载";
477
482
  readonly 'sync.hist.directionPush': "上传";
@@ -526,6 +531,16 @@ interface UploadResponse {
526
531
  name: string;
527
532
  sizeBytes: number;
528
533
  }
534
+ /** decrypt-verify 端点响应:校验加密备份密码是否可解开 secrets.enc(零写入) */
535
+ interface DecryptVerifyResponse {
536
+ ok: boolean;
537
+ /** 该备份是否加密(password 非空时恒 true;用于 UI 双保险) */
538
+ encrypted: boolean;
539
+ /** 解密成功后将恢复的凭据数(普通备份为 0) */
540
+ secretCount: number;
541
+ /** 解密覆盖的凭据 ref 名(非值);UI 据此从补录阶段剔除已恢复项 */
542
+ refs: string[];
543
+ }
529
544
  /** restore 端点响应:dryRun=true 返回 plan;执行返回 report(与 CLI 一致的诚实报告) */
530
545
  interface RestoreResponse {
531
546
  dryRun: boolean;
@@ -573,11 +588,14 @@ declare class ConfigManagerApi {
573
588
  analyzeImport(zipPath: string): Promise<ImportAnalysis>;
574
589
  /** ImportPort.createImportPlan:用用户决策(冲突/路径映射/策略)生成最终计划(Dry Run 零写入) */
575
590
  createImportPlan(zipPath: string, decisions: ImportDecisions): Promise<ImportPlan>;
591
+ /** 验证加密备份的解密密码(只读零写入):成功返回将恢复的凭据数;密码错误抛 ConfigManagerApiError */
592
+ verifyDecrypt(zipPath: string, password: string): Promise<DecryptVerifyResponse>;
576
593
  /** ImportPort.executeImportPlan:快照→分阶段 apply→validate→commit/rollback */
577
594
  executeImportPlan(zipPath: string, plan: ImportPlan, opts: {
578
595
  confirm: boolean;
579
596
  secretInputs?: Record<string, string>;
580
597
  rollbackOnError: boolean;
598
+ decryptPassword?: string;
581
599
  }): Promise<ImportResult & {
582
600
  runId: string;
583
601
  }>;
@@ -950,12 +968,22 @@ declare const zh$1: {
950
968
  readonly 'import.preview.restart': "导入后需重启 DSH 生效";
951
969
  readonly 'import.confirm.execute': "确认导入";
952
970
  readonly 'import.confirm.warning': "导入将修改当前 DSH 配置;执行前会自动创建安全快照,失败时整体回滚。";
971
+ readonly 'import.confirm.encrypted': "将用备份密码解密并恢复 {count} 个凭据。";
953
972
  readonly 'import.rollbackOnError': "失败时整体回滚(推荐)";
954
973
  readonly 'import.importing': "正在导入…(插件安装较多时可能需要几分钟,请勿关闭页面)";
955
974
  readonly 'import.secrets.title': "补录密钥";
956
975
  readonly 'import.secrets.hint': "以下凭据未随备份导出(安全设计)。如需在目标 DSH 使用,请手动补录;留空将跳过。";
957
976
  readonly 'import.secrets.optional': "(可选)";
958
977
  readonly 'import.secrets.required': "(必需)";
978
+ readonly 'import.decrypt.badge': "加密备份";
979
+ readonly 'import.decrypt.title': "解密备份";
980
+ readonly 'import.decrypt.hint': "此备份包含加密的凭据,必须输入导出时设置的加密密码才能解锁并继续导入。";
981
+ readonly 'import.decrypt.passwordPlaceholder': "输入备份加密密码";
982
+ readonly 'import.decrypt.verify': "验证密码";
983
+ readonly 'import.decrypt.verifying': "验证中…";
984
+ readonly 'import.decrypt.verified': "密码正确,解密将恢复 {count} 个凭据";
985
+ readonly 'import.decrypt.verifiedEmpty': "密码正确(该备份没有可恢复的凭据)";
986
+ readonly 'import.decrypt.previewHint': "加密备份:下一步需输入导出时的加密密码才能解锁凭据。";
959
987
  readonly 'import.conflicts.title': "解决冲突";
960
988
  readonly 'import.conflicts.hint': "以下配置项在目标 DSH 已存在且与备份不同,请逐项决策。";
961
989
  readonly 'import.conflicts.keepCurrent': "保留当前";
@@ -1097,6 +1125,7 @@ declare const zh: {
1097
1125
  readonly 'autosync.status': "上次运行:{status}({time})";
1098
1126
  readonly 'autosync.statusNever': "从未运行";
1099
1127
  readonly 'autosync.nextRun': "下次约 {time} 后";
1128
+ readonly 'autosync.due': "已到同步时间,即将执行";
1100
1129
  readonly 'autosync.failCount': "连续失败 {n} 次";
1101
1130
  readonly 'autosync.running': "自动同步进行中…";
1102
1131
  readonly 'autosync.success': "成功";