dsh-config-manager 0.1.26 → 0.1.28

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 (43) hide show
  1. package/README.md +6 -2
  2. package/README.zh-CN.md +6 -2
  3. package/lib/client.d.ts +25 -0
  4. package/lib/client.js +250 -94
  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 +69 -9
  14. package/lib/index.js.map +1 -1
  15. package/lib/sync/autosync-scheduler.js +19 -2
  16. package/lib/sync/autosync-scheduler.js.map +1 -1
  17. package/lib/ui/flow.d.ts +1 -1
  18. package/lib/ui/import-wizard.d.ts +4 -0
  19. package/lib/ui/import-wizard.js +9 -0
  20. package/lib/ui/import-wizard.js.map +1 -1
  21. package/lib/ui/test-helpers.d.ts +2 -0
  22. package/lib/ui/test-helpers.js +1 -0
  23. package/lib/ui/test-helpers.js.map +1 -1
  24. package/lib/ui/types.d.ts +2 -0
  25. package/lib/ui/types.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/client/api.ts +26 -1
  28. package/src/client/import/ImportWizardView.tsx +100 -4
  29. package/src/client/locales.ts +20 -0
  30. package/src/client/run-store.ts +32 -7
  31. package/src/core/analyzer.ts +8 -0
  32. package/src/core/messages.ts +4 -0
  33. package/src/core/types.ts +2 -0
  34. package/src/index.ts +69 -10
  35. package/src/security/security.test.ts +59 -0
  36. package/src/sync/autosync-scheduler.test.ts +59 -0
  37. package/src/sync/autosync-scheduler.ts +19 -4
  38. package/src/sync/sync-session.test.ts +3 -2
  39. package/src/ui/flow.ts +1 -1
  40. package/src/ui/import-wizard.test.ts +23 -0
  41. package/src/ui/import-wizard.ts +10 -0
  42. package/src/ui/test-helpers.ts +4 -3
  43. 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;
@@ -529,6 +531,16 @@ interface UploadResponse {
529
531
  name: string;
530
532
  sizeBytes: number;
531
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
+ }
532
544
  /** restore 端点响应:dryRun=true 返回 plan;执行返回 report(与 CLI 一致的诚实报告) */
533
545
  interface RestoreResponse {
534
546
  dryRun: boolean;
@@ -576,11 +588,14 @@ declare class ConfigManagerApi {
576
588
  analyzeImport(zipPath: string): Promise<ImportAnalysis>;
577
589
  /** ImportPort.createImportPlan:用用户决策(冲突/路径映射/策略)生成最终计划(Dry Run 零写入) */
578
590
  createImportPlan(zipPath: string, decisions: ImportDecisions): Promise<ImportPlan>;
591
+ /** 验证加密备份的解密密码(只读零写入):成功返回将恢复的凭据数;密码错误抛 ConfigManagerApiError */
592
+ verifyDecrypt(zipPath: string, password: string): Promise<DecryptVerifyResponse>;
579
593
  /** ImportPort.executeImportPlan:快照→分阶段 apply→validate→commit/rollback */
580
594
  executeImportPlan(zipPath: string, plan: ImportPlan, opts: {
581
595
  confirm: boolean;
582
596
  secretInputs?: Record<string, string>;
583
597
  rollbackOnError: boolean;
598
+ decryptPassword?: string;
584
599
  }): Promise<ImportResult & {
585
600
  runId: string;
586
601
  }>;
@@ -953,12 +968,22 @@ declare const zh$1: {
953
968
  readonly 'import.preview.restart': "导入后需重启 DSH 生效";
954
969
  readonly 'import.confirm.execute': "确认导入";
955
970
  readonly 'import.confirm.warning': "导入将修改当前 DSH 配置;执行前会自动创建安全快照,失败时整体回滚。";
971
+ readonly 'import.confirm.encrypted': "将用备份密码解密并恢复 {count} 个凭据。";
956
972
  readonly 'import.rollbackOnError': "失败时整体回滚(推荐)";
957
973
  readonly 'import.importing': "正在导入…(插件安装较多时可能需要几分钟,请勿关闭页面)";
958
974
  readonly 'import.secrets.title': "补录密钥";
959
975
  readonly 'import.secrets.hint': "以下凭据未随备份导出(安全设计)。如需在目标 DSH 使用,请手动补录;留空将跳过。";
960
976
  readonly 'import.secrets.optional': "(可选)";
961
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': "加密备份:下一步需输入导出时的加密密码才能解锁凭据。";
962
987
  readonly 'import.conflicts.title': "解决冲突";
963
988
  readonly 'import.conflicts.hint': "以下配置项在目标 DSH 已存在且与备份不同,请逐项决策。";
964
989
  readonly 'import.conflicts.keepCurrent': "保留当前";