dsh-config-manager 0.1.52 → 0.1.54
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.
- package/README.md +26 -4
- package/lib/adapters/self.js +3 -0
- package/lib/adapters/self.js.map +1 -1
- package/lib/client.d.ts +240 -5
- package/lib/client.js +2619 -322
- package/lib/client.js.map +1 -1
- package/lib/core/backup.d.ts +3 -1
- package/lib/core/backup.js +5 -1
- package/lib/core/backup.js.map +1 -1
- package/lib/core/restore.d.ts +10 -0
- package/lib/core/restore.js +41 -0
- package/lib/core/restore.js.map +1 -1
- package/lib/core/run-registry.d.ts +2 -2
- package/lib/core/types.d.ts +4 -0
- package/lib/core/types.js.map +1 -1
- package/lib/index.js +415 -14
- package/lib/index.js.map +1 -1
- package/lib/market/types.d.ts +2 -0
- package/lib/sync/backup-files.d.ts +25 -4
- package/lib/sync/backup-files.js +82 -3
- package/lib/sync/backup-files.js.map +1 -1
- package/lib/sync/backup-schedule-config.d.ts +29 -3
- package/lib/sync/backup-schedule-config.js +50 -2
- package/lib/sync/backup-schedule-config.js.map +1 -1
- package/lib/sync/backup-scheduler.js +11 -3
- package/lib/sync/backup-scheduler.js.map +1 -1
- package/lib/sync/sync-engine.d.ts +30 -1
- package/lib/sync/sync-engine.js +63 -0
- package/lib/sync/sync-engine.js.map +1 -1
- package/lib/ui/backup-inspect.d.ts +53 -0
- package/lib/ui/backup-inspect.js +54 -0
- package/lib/ui/backup-inspect.js.map +1 -0
- package/lib/ui/backup-schedule.d.ts +14 -3
- package/lib/ui/backup-schedule.js +39 -4
- package/lib/ui/backup-schedule.js.map +1 -1
- package/lib/ui/conflict-view.d.ts +4 -0
- package/lib/ui/conflict-view.js +11 -0
- package/lib/ui/conflict-view.js.map +1 -1
- package/lib/ui/export-flow.d.ts +16 -0
- package/lib/ui/export-flow.js +15 -0
- package/lib/ui/export-flow.js.map +1 -1
- package/lib/ui/i18n.d.ts +3 -0
- package/lib/ui/i18n.js +6 -0
- package/lib/ui/i18n.js.map +1 -1
- package/lib/ui/next-steps.d.ts +56 -0
- package/lib/ui/next-steps.js +29 -0
- package/lib/ui/next-steps.js.map +1 -0
- package/lib/ui/profiles-view.d.ts +26 -0
- package/lib/ui/profiles-view.js +38 -0
- package/lib/ui/profiles-view.js.map +1 -0
- package/package.json +1 -1
- package/src/adapters/self.ts +3 -0
- package/src/client/ConfigManagerSection.tsx +61 -28
- package/src/client/about/AboutPanel.tsx +19 -1
- package/src/client/about/about-view.ts +21 -1
- package/src/client/api.ts +150 -1
- package/src/client/config-manager.module.css +209 -3
- package/src/client/export/ExportView.tsx +99 -4
- package/src/client/import/ConflictList.tsx +4 -3
- package/src/client/import/ImportWizardView.tsx +58 -1
- package/src/client/locales.ts +194 -0
- package/src/client/market/MarketPanel.tsx +46 -4
- package/src/client/market/MyConfigsView.tsx +15 -13
- package/src/client/market/market-locales.ts +16 -0
- package/src/client/market/market-view.test.ts +60 -4
- package/src/client/market/market-view.ts +73 -2
- package/src/client/profiles/ProfilesPanel.tsx +570 -0
- package/src/client/run-store.ts +74 -5
- package/src/client/snapshots/SnapshotsPanel.tsx +453 -49
- package/src/client/sync/SyncSettingsView.tsx +126 -16
- package/src/client/sync/sync-api.ts +6 -1
- package/src/client/sync/sync-locales.ts +12 -0
- package/src/client/sync/sync-push-preview.test.ts +68 -0
- package/src/client/sync/sync-view.ts +45 -1
- package/src/core/backup.ts +4 -1
- package/src/core/restore-manage.test.ts +94 -0
- package/src/core/restore.ts +46 -0
- package/src/core/run-registry.ts +2 -2
- package/src/core/types.ts +4 -0
- package/src/index.ts +396 -18
- package/src/market/types.ts +2 -0
- package/src/sync/backup-files.test.ts +64 -0
- package/src/sync/backup-files.ts +84 -6
- package/src/sync/backup-schedule-config.ts +66 -5
- package/src/sync/backup-scheduler.test.ts +49 -1
- package/src/sync/backup-scheduler.ts +11 -3
- package/src/sync/sync-engine.ts +86 -1
- package/src/ui/backup-inspect.test.ts +142 -0
- package/src/ui/backup-inspect.ts +100 -0
- package/src/ui/backup-schedule.test.ts +51 -0
- package/src/ui/backup-schedule.ts +49 -7
- package/src/ui/conflict-view.test.ts +24 -2
- package/src/ui/conflict-view.ts +12 -0
- package/src/ui/export-flow.test.ts +10 -1
- package/src/ui/export-flow.ts +24 -1
- package/src/ui/i18n.ts +6 -0
- package/src/ui/next-steps.test.ts +117 -0
- package/src/ui/next-steps.ts +62 -0
- package/src/ui/profiles-view.test.ts +77 -0
- package/src/ui/profiles-view.ts +55 -0
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Backup, restore, export, import, migrate and sync your complete DeepSeek Harness
|
|
|
7
7
|
- 🔄 **Backup & Restore** DeepSeek Harness configuration
|
|
8
8
|
- 📦 **Export / Import** complete DSH configuration
|
|
9
9
|
- 🚚 **Migrate** DSH to another machine
|
|
10
|
-
- ⏰ **Scheduled full backups** — automatic, on your own cadence (6h / 12h / 24h / 7d), secrets never included
|
|
10
|
+
- ⏰ **Scheduled full backups** — automatic, on your own cadence (6h / 12h / 24h / 7d / custom weekly), secrets never included
|
|
11
11
|
- 🔌 Backup installed **plugins** and plugin configuration
|
|
12
12
|
- 🧩 Backup **MCP servers** and **Skills**
|
|
13
13
|
- 🔐 Encrypted backups with optional credentials
|
|
@@ -56,7 +56,7 @@ Keep portable configuration synchronized between machines through a private Git
|
|
|
56
56
|
|
|
57
57
|
### Schedule automatic full backups
|
|
58
58
|
|
|
59
|
-
Turn on scheduled backups (6h / 12h / 24h / 7d) and DSH quietly keeps a fresh full backup of your configuration in the background — secrets are never included, so it stays safe on disk without a password.
|
|
59
|
+
Turn on scheduled backups (6h / 12h / 24h / 7d — or a **custom weekly weekday & time**) and DSH quietly keeps a fresh full backup of your configuration in the background — secrets are never included, so it stays safe on disk without a password. Consecutive failures are highlighted in red in the settings card.
|
|
60
60
|
|
|
61
61
|
### Discover & install configurations from the marketplace
|
|
62
62
|
|
|
@@ -79,7 +79,7 @@ Browse the built-in official market for ready-made configurations (model provide
|
|
|
79
79
|
| 🔄 | **Remote Sync** | Push/pull portable config via **Git private repo or WebDAV** (secrets never sync) |
|
|
80
80
|
| ⏰ | **Scheduled backups** | Full backup on a fixed cadence (6h / 12h / 24h / 7d) — set-and-forget, secrets never included |
|
|
81
81
|
| 🛒 | **Config Marketplace** | Browse & one-click install community configs — supply-chain warnings + per-section approval |
|
|
82
|
-
| 🗂️ | **Profiles** | Save multiple setups (Work / Personal) and switch anytime |
|
|
82
|
+
| 🗂️ | **Profiles** | Save multiple setups (Work / Personal) and switch anytime — preview + auto-backup + rollback |
|
|
83
83
|
| 🌐 | **Bilingual UI** | Interface, reports and error details follow the DSH app language (中文 / English) |
|
|
84
84
|
| 🤖 | **Agent tools** | Backup / snapshot / restore / sync right from an agent session |
|
|
85
85
|
|
|
@@ -186,11 +186,16 @@ Copy the ZIP to Machine B (import)
|
|
|
186
186
|
|
|
187
187
|
> Output: `dsh-config-<date>.zip` with manifest + per-category data + SHA-256 checksums.
|
|
188
188
|
|
|
189
|
+
**Export extras:**
|
|
190
|
+
- **Preview before export** — see what will be packaged (section count + estimated size, no secrets) before anything is written
|
|
191
|
+
- **Custom file name & note** — name the ZIP yourself (auto-naming is the default) and attach an optional note that shows in the **Backup Files** list (the note travels with the self section when you sync/backup the config)
|
|
192
|
+
|
|
189
193
|
### 📥 Import (safe flow)
|
|
190
194
|
|
|
191
195
|
- **Nothing is written before confirmation** — analyze & preview are zero-write
|
|
192
196
|
- **Backup before applying** — the target config is snapshotted automatically
|
|
193
197
|
- **Automatic rollback on failure** — full rollback or skip-and-continue, your choice
|
|
198
|
+
- **Next-steps checklist after import** — the result page lists what needs a DSH restart (per plugin/MCP), credentials to re-enter, and failed/skipped items you can retry
|
|
194
199
|
|
|
195
200
|
### 👀 Import Preview (dry run)
|
|
196
201
|
|
|
@@ -242,13 +247,15 @@ Push / pull your portable config between machines through **either of two channe
|
|
|
242
247
|
- **Switching channels starts fresh**: Git and WebDAV do **not** share snapshots or a common ancestor. When you switch transport, sync begins again from the new remote's empty baseline — push a fresh snapshot first.
|
|
243
248
|
- **WebDAV auth** uses HTTP Basic: the `username` is stored in the config and may be echoed back into the UI, while the `password` is read live from the DSH credentials slot `DSH_CONFIG_MANAGER_SYNC_WEBDAV_PASSWORD` — it never appears in any sync file or log.
|
|
244
249
|
- **Plugins auto-install**: when pulling diffs, plugins that are new in the backup are **installed automatically** on confirm — no manual per-item ticking in the diff list. Only **version-conflict** plugins still ask you to pick "Keep Current / Use Imported".
|
|
250
|
+
- **Push preview before uploading** — the Push button first shows a read-only preview of what will be sent (sections + per-section counts + changed-vs-baseline markers, first-baseline notice) and only writes the remote after you confirm.
|
|
245
251
|
|
|
246
252
|
### 🛒 Configuration Marketplace
|
|
247
253
|
|
|
248
254
|
Browse and install ready-made configurations (model providers, plugins, MCP servers, skills, agent presets…) shared by the community:
|
|
249
255
|
|
|
250
256
|
- **Built-in official market** — read-only, bound to the official public repo (official badge shown, not editable); first open auto-refreshes, manual refresh also available
|
|
251
|
-
- **Search & filter** — keyword search, category filter, source filter (Official / Community), sorting (recently updated / most starred / name A–Z), and a ⭐ badge showing the **source repo's** star count (queried anonymously, no token involved)
|
|
257
|
+
- **Search & filter** — keyword search (matches name / description / author / **categories**), category filter, **section filter** (items already downloaded list their sections; others are excluded with a hint), source filter (Official / Community), sorting (recently updated / most starred / name A–Z), and a ⭐ badge showing the **source repo's** star count (queried anonymously, no token involved)
|
|
258
|
+
- **Impact preview** — the detail view shows "what installing this will change" (items updated / identical / conflicts / secrets to re-enter / DSH restart needed) before you approve anything
|
|
252
259
|
- **Supply-chain warnings always shown** — source repo URL, "not officially reviewed", download time; **per-section approval** — high-risk sections (sessions / arbitrary files) are banned from listing outright, and every remaining section must be explicitly approved before the import is confirmed
|
|
253
260
|
- **Install reuses the safe import pipeline** — analyze → preview → auto-backup → apply → rollback; nothing is written before you confirm
|
|
254
261
|
- **"My Configs"** — sign in with GitHub (device flow), upload a config to **your own public repo** in one click, and an **auto listing PR** is opened against the official market repo; manage your listings (status badges: not listed / PR pending / listed), update in one click, install back locally, or delist (auto de-listing PR)
|
|
@@ -257,6 +264,11 @@ Browse and install ready-made configurations (model providers, plugins, MCP serv
|
|
|
257
264
|
|
|
258
265
|
Save multiple configurations (Work / Personal) and switch anytime; switching includes preview + auto-backup + rollback.
|
|
259
266
|
|
|
267
|
+
- **Save current config** — pick a name and store the current DSH configuration (settings / providers / plugins / skills / agent presets…; no secrets, file sections embedded)
|
|
268
|
+
- **Switch with safety** — preview first (zero writes) → confirm → automatic snapshot → staged apply; any failure rolls back fully
|
|
269
|
+
- **Manage** — rename / delete (confirmed) / import an exported profile.json
|
|
270
|
+
- Library is an independent tab: Settings → "Backup & Migration" → **Profiles**
|
|
271
|
+
|
|
260
272
|
### 📸 Snapshot restore (undo an import)
|
|
261
273
|
|
|
262
274
|
Every import creates a **safety snapshot** first. If something feels off afterwards, restore the target back to its pre-import state:
|
|
@@ -270,6 +282,16 @@ Every import creates a **safety snapshot** first. If something feels off afterwa
|
|
|
270
282
|
|
|
271
283
|
**GUI**: Settings → "Backup & Migration" → **Snapshots & Restore** tab → pick a snapshot → preview the plan (dry-run, zero writes) → confirm.
|
|
272
284
|
|
|
285
|
+
**Snapshot management:**
|
|
286
|
+
- **Retention is visible** — up to **10** snapshots are kept automatically (oldest pruned); the hint is shown in the list
|
|
287
|
+
- **Pin important snapshots** — a pinned snapshot is exempt from auto-pruning and can only be deleted manually
|
|
288
|
+
- **Manual delete** — remove any snapshot (danger, confirmed) when you no longer need that rollback point
|
|
289
|
+
|
|
290
|
+
**Backup Files management** (same tab → "Backup Files"):
|
|
291
|
+
- List every export ZIP (manual + scheduled) with source badge, size, time and your custom **note**
|
|
292
|
+
- **Search** by file name or note
|
|
293
|
+
- **Inspect / Compare** — read-only preview of what the backup contains (sections + per-section counts) and the diff against your current config (zero writes) before deciding to import
|
|
294
|
+
|
|
273
295
|
---
|
|
274
296
|
|
|
275
297
|
### 🚨 CLI — the first line of defense when DSH is broken
|
package/lib/adapters/self.js
CHANGED
|
@@ -33,6 +33,9 @@ export const SELF_CONFIG_FILES = [
|
|
|
33
33
|
'sync/ui-prefs.json',
|
|
34
34
|
'sync/backup-schedule.json',
|
|
35
35
|
'market/market-config.json',
|
|
36
|
+
// P0-④:导出产物备注清单(exports/.backup-notes.json)——随 self 分区迁移,
|
|
37
|
+
// 换机器后备份列表仍能看到手动导出时填写的备注
|
|
38
|
+
'exports/.backup-notes.json',
|
|
36
39
|
];
|
|
37
40
|
export class SelfAdapter extends FileCollectionAdapter {
|
|
38
41
|
id = 'self';
|
package/lib/adapters/self.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"self.js","sourceRoot":"","sources":["../../src/adapters/self.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,gEAAgE;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,uBAAuB;IACvB,yBAAyB;IACzB,0BAA0B;IAC1B,oBAAoB;IACpB,2BAA2B;IAC3B,2BAA2B;
|
|
1
|
+
{"version":3,"file":"self.js","sourceRoot":"","sources":["../../src/adapters/self.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,gEAAgE;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAAsB;IAClD,uBAAuB;IACvB,yBAAyB;IACzB,0BAA0B;IAC1B,oBAAoB;IACpB,2BAA2B;IAC3B,2BAA2B;IAC3B,0DAA0D;IAC1D,yBAAyB;IACzB,4BAA4B;CAC7B,CAAC;AAEF,MAAM,OAAO,WAAY,SAAQ,qBAAqB;IAC3C,EAAE,GAAG,MAAe,CAAC;IACrB,WAAW,GAAG,oBAAoB,CAAC;IACnC,eAAe,GAAG,IAAI,CAAC;IACvB,WAAW,GAAG,UAAmB,CAAC;IAC3C,kEAAkE;IACzD,OAAO,CAAS;IAEzB,YAAY,OAAO,GAAG,oBAAoB;QACxC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;iGAC6F;IACpF,KAAK,CAAC,MAAM,CAAC,GAAgB,EAAE,QAAuB;QAC7D,MAAM,KAAK,GAA0B,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;YACpC,oEAAoE;YACpE,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACnF,IAAI,IAAI,KAAK,IAAI;gBAAE,SAAS,CAAC,0BAA0B;YACvD,KAAK,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,EAAE;YAClB,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE;YAC3B,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE;YAC/B,QAAQ;SACT,CAAC;IACJ,CAAC;CACF"}
|
package/lib/client.d.ts
CHANGED
|
@@ -83,6 +83,8 @@ interface ExportOptions {
|
|
|
83
83
|
only?: SectionId[];
|
|
84
84
|
/** 导出文件路径(缺省自动生成 dsh-config-<date>.zip) */
|
|
85
85
|
outPath?: string;
|
|
86
|
+
/** 导出备注(P0-④:host 写入 exports/.backup-notes.json,随 self 分区迁移;非敏感) */
|
|
87
|
+
note?: string;
|
|
86
88
|
}
|
|
87
89
|
type PlanItemKind = 'Create' | 'Update' | 'Skip' | 'Conflict' | 'Install' | 'MissingSecret' | 'MissingDependency' | 'PathMapping' | 'Warning' | 'Error';
|
|
88
90
|
type ItemResolution = 'keepCurrent' | 'useImported' | 'review';
|
|
@@ -278,11 +280,40 @@ interface SnapshotMeta {
|
|
|
278
280
|
entryCount: number;
|
|
279
281
|
hostFileBackupCount: number;
|
|
280
282
|
beforePluginCount: number;
|
|
283
|
+
/** 置顶标记(P1-⑧):置顶快照不参与自动保留清理(最多保留 N 个时的淘汰豁免) */
|
|
284
|
+
pinned?: boolean;
|
|
285
|
+
}
|
|
286
|
+
//#endregion
|
|
287
|
+
//#region src/profiles/profile-manager.d.ts
|
|
288
|
+
interface ProfileMeta {
|
|
289
|
+
name: string;
|
|
290
|
+
createdAt: string;
|
|
291
|
+
updatedAt: string;
|
|
292
|
+
sections: SectionId[];
|
|
293
|
+
fileCount: number;
|
|
294
|
+
}
|
|
295
|
+
interface SwitchPreview {
|
|
296
|
+
items: PlanItem[];
|
|
297
|
+
missingSecrets: {
|
|
298
|
+
ref: string;
|
|
299
|
+
required: boolean;
|
|
300
|
+
}[];
|
|
301
|
+
needsRestart: boolean;
|
|
302
|
+
sectionsInProfile: SectionId[];
|
|
303
|
+
}
|
|
304
|
+
interface ProfileSwitchResult {
|
|
305
|
+
ok: boolean;
|
|
306
|
+
executed: ExecutedItem[];
|
|
307
|
+
needsRestart: boolean;
|
|
308
|
+
missingSecrets: string[];
|
|
309
|
+
warnings: string[];
|
|
310
|
+
rollback: RollbackReport | null;
|
|
311
|
+
snapshotId: string | null;
|
|
281
312
|
}
|
|
282
313
|
//#endregion
|
|
283
314
|
//#region src/core/run-registry.d.ts
|
|
284
|
-
/** run 类型:导出 / 导入 / 自动同步 / 一键同步逐项应用 / 定时备份 /
|
|
285
|
-
type RunKind = 'export' | 'import' | 'autosync' | 'sync-apply' | 'backup-schedule' | 'restore';
|
|
315
|
+
/** run 类型:导出 / 导入 / 自动同步 / 一键同步逐项应用 / 定时备份 / 快照恢复 / 配置档案切换。 */
|
|
316
|
+
type RunKind = 'export' | 'import' | 'autosync' | 'sync-apply' | 'backup-schedule' | 'restore' | 'profile-switch';
|
|
286
317
|
/** run 状态:进行中 / 完成 / 失败。 */
|
|
287
318
|
type RunStatus = 'running' | 'done' | 'failed';
|
|
288
319
|
/** 单个 run 的实时状态(/progress 返回体;纯 JSON 可序列化)。 */
|
|
@@ -313,8 +344,22 @@ interface RunState {
|
|
|
313
344
|
}
|
|
314
345
|
//#endregion
|
|
315
346
|
//#region src/sync/backup-schedule-config.d.ts
|
|
316
|
-
/** 定时备份间隔档位(全量备份无需太频繁;默认 24h
|
|
317
|
-
|
|
347
|
+
/** 定时备份间隔档位(全量备份无需太频繁;默认 24h)。
|
|
348
|
+
* - '6h' | '12h' | '24h' | '7d':固定间隔;
|
|
349
|
+
* - 'custom':每周固定时刻(见 customSchedule)。 */
|
|
350
|
+
type BackupInterval = '6h' | '12h' | '24h' | '7d' | 'custom';
|
|
351
|
+
/**
|
|
352
|
+
* 自定义(每周固定时刻)档配置:
|
|
353
|
+
* - dayOfWeek:0-6(0 = 周日,1 = 周一 … 6 = 周六);
|
|
354
|
+
* - hour:0-23;
|
|
355
|
+
* - minute:0-59。
|
|
356
|
+
* 语义 = 每周该时刻触发一次全量备份(错过的时间点不补跑——下次排期自然对齐)。
|
|
357
|
+
*/
|
|
358
|
+
interface BackupWeeklySchedule {
|
|
359
|
+
dayOfWeek: number;
|
|
360
|
+
hour: number;
|
|
361
|
+
minute: number;
|
|
362
|
+
}
|
|
318
363
|
/** 最近一次定时备份执行状态 */
|
|
319
364
|
type BackupRunStatus = 'success' | 'skipped' | 'failed';
|
|
320
365
|
//#endregion
|
|
@@ -330,15 +375,18 @@ interface BackupRunResult {
|
|
|
330
375
|
}
|
|
331
376
|
//#endregion
|
|
332
377
|
//#region src/ui/backup-schedule.d.ts
|
|
333
|
-
/** 设置草稿(表单编辑态:总开关 +
|
|
378
|
+
/** 设置草稿(表单编辑态:总开关 + 间隔档位 + 自定义周档)。 */
|
|
334
379
|
interface BackupScheduleDraft {
|
|
335
380
|
enabled: boolean;
|
|
336
381
|
interval: BackupInterval;
|
|
382
|
+
/** custom 档的每周固定时刻(仅 interval='custom' 时校验;其他档位忽略) */
|
|
383
|
+
customSchedule?: BackupWeeklySchedule;
|
|
337
384
|
}
|
|
338
385
|
/** 定时备份配置的浏览器侧视图(与 sync/backup-schedule-config.ts 的持久化面一致;无敏感字段)。 */
|
|
339
386
|
interface BackupScheduleStatus {
|
|
340
387
|
enabled: boolean;
|
|
341
388
|
interval: BackupInterval;
|
|
389
|
+
customSchedule?: BackupWeeklySchedule;
|
|
342
390
|
startupMinIntervalMs: number;
|
|
343
391
|
consecutiveFailures: number;
|
|
344
392
|
lastRunAt?: string;
|
|
@@ -361,6 +409,8 @@ interface BackupFileMeta {
|
|
|
361
409
|
mtimeMs: number;
|
|
362
410
|
/** 来源:auto = 定时备份;manual = 手动导出 */
|
|
363
411
|
source: BackupFileSource;
|
|
412
|
+
/** 用户备注(手动导出时可选填写;null = 无备注) */
|
|
413
|
+
note?: string | null;
|
|
364
414
|
}
|
|
365
415
|
//#endregion
|
|
366
416
|
//#region src/ui/i18n.d.ts
|
|
@@ -513,6 +563,9 @@ declare const uiZh: {
|
|
|
513
563
|
readonly 'sync.neverSyncedShort': "从未同步";
|
|
514
564
|
readonly 'sync.pushFailed': "推送失败";
|
|
515
565
|
readonly 'sync.pushOk': "推送成功(快照 {id})";
|
|
566
|
+
readonly 'sync.pushPreviewHeadline': "将推送 {total} 个分区({changed} 个有变化)";
|
|
567
|
+
readonly 'sync.pushPreviewHint': "以上为只读预览,不会写入远端。确认后点击「推送」才真正上传。";
|
|
568
|
+
readonly 'sync.pushPreviewEncrypted': "加密快照:载荷将整体加密,各分区相对基线的变化不可比对。";
|
|
516
569
|
readonly 'sync.pullFailed': "拉取失败";
|
|
517
570
|
readonly 'sync.pullOk': "远端快照 {id} 差异预览:共 {count} 项变更";
|
|
518
571
|
readonly 'sync.pullEmpty': "远端快照与本地一致(无变更)";
|
|
@@ -649,6 +702,23 @@ interface UploadResponse {
|
|
|
649
702
|
/** zip=普通备份;encrypted=整体加密备份容器(需先 decryptArchive 解锁才能按 ZIP 解析) */
|
|
650
703
|
containerType: 'zip' | 'encrypted';
|
|
651
704
|
}
|
|
705
|
+
/** P1-⑦/P2-⑬:备份内容查看 / 差异对比结果(只读;复用 analyze + plan 链路,零写入) */
|
|
706
|
+
interface BackupInspectResult {
|
|
707
|
+
analysis: ImportAnalysis;
|
|
708
|
+
plan: ImportPlan;
|
|
709
|
+
}
|
|
710
|
+
/** P2-⑫:导出前预览响应(不落盘 ZIP;各分区 counts + 估算大小) */
|
|
711
|
+
interface ExportPreviewResponse {
|
|
712
|
+
ok: boolean;
|
|
713
|
+
sections: {
|
|
714
|
+
section: SectionId;
|
|
715
|
+
count: number;
|
|
716
|
+
sizeBytes: number;
|
|
717
|
+
}[];
|
|
718
|
+
totalSections: number;
|
|
719
|
+
totalSizeBytes: number;
|
|
720
|
+
sectionsFailed: number;
|
|
721
|
+
}
|
|
652
722
|
/** decrypt-archive 端点响应:解锁整体加密容器后返回明文 ZIP 路径 + 解密覆盖的凭据 ref 名(非值) */
|
|
653
723
|
interface DecryptArchiveResponse {
|
|
654
724
|
zipPath: string;
|
|
@@ -721,6 +791,8 @@ declare class ConfigManagerApi {
|
|
|
721
791
|
status(): Promise<ServiceStatus>;
|
|
722
792
|
/** Star 引导弹窗状态(进入页面时判定是否展示 / 是否补记首次使用时间)。 */
|
|
723
793
|
starPromptStatus(): Promise<StarPromptStatus>;
|
|
794
|
+
/** P2-⑫:导出前只读预览(不落盘 ZIP)——「将打包 X 分区 / Y 条目 / 约 Z 大小」。 */
|
|
795
|
+
exportPreview(only?: SectionId[]): Promise<ExportPreviewResponse>;
|
|
724
796
|
/** 保存 Star 引导弹窗状态(局部更新:firstSeenAt / dismissed / clicked)。
|
|
725
797
|
* 纯偏好无 secret;失败由调用方静默降级(本次不弹/不记,下次再判)。 */
|
|
726
798
|
saveStarPrompt(patch: StarPromptPatch): Promise<StarPromptSaveResponse>;
|
|
@@ -765,6 +837,34 @@ declare class ConfigManagerApi {
|
|
|
765
837
|
snapshots(): Promise<SnapshotMeta[]>;
|
|
766
838
|
/** 快照恢复:dryRun=true 只取动作计划(零写入);false 执行并返回诚实报告 */
|
|
767
839
|
restoreSnapshot(snapshotId: string, dryRun: boolean): Promise<RestoreResponse>;
|
|
840
|
+
/** P1-⑧:手动删除单个快照(危险操作:该导入前回滚点不可恢复;`removed` 为是否实际删除)。 */
|
|
841
|
+
deleteSnapshot(snapshotId: string): Promise<{
|
|
842
|
+
removed: boolean;
|
|
843
|
+
}>;
|
|
844
|
+
/** P1-⑧:置顶/取消置顶快照(置顶快照豁免自动保留清理,只能手动删除)。 */
|
|
845
|
+
setSnapshotPinned(snapshotId: string, pinned: boolean): Promise<{
|
|
846
|
+
pinned: boolean;
|
|
847
|
+
}>;
|
|
848
|
+
/** 列出全部 Profile(name/createdAt/updatedAt/sections/fileCount)。 */
|
|
849
|
+
profilesList(): Promise<ProfileMeta[]>;
|
|
850
|
+
/** 保存当前 DSH 配置为新 Profile(天然不含秘密值)。 */
|
|
851
|
+
profileSave(name: string, sections?: SectionId[]): Promise<ProfileMeta>;
|
|
852
|
+
/** 删除 Profile(危险操作:该组配置快照不可恢复)。 */
|
|
853
|
+
profileDelete(name: string): Promise<void>;
|
|
854
|
+
/** 重命名 Profile(目录级移动)。 */
|
|
855
|
+
profileRename(name: string, newName: string): Promise<ProfileMeta>;
|
|
856
|
+
/** 切换前预览(只读,零写入):分析切换到该 Profile 会产生的计划项。 */
|
|
857
|
+
profileAnalyzeSwitch(name: string): Promise<SwitchPreview>;
|
|
858
|
+
/** 执行切换(confirm=true 安全阀;走快照 + 分阶段 apply + 失败回滚;响应含 runId)。 */
|
|
859
|
+
profileExecuteSwitch(name: string, opts: {
|
|
860
|
+
strategy?: 'merge' | 'replace' | 'skipExisting';
|
|
861
|
+
secretInputs?: Record<string, string>;
|
|
862
|
+
rollbackOnError?: boolean;
|
|
863
|
+
}): Promise<ProfileSwitchResult & {
|
|
864
|
+
runId: string;
|
|
865
|
+
}>;
|
|
866
|
+
/** 导入 Profile(content = profile.json 字符串;asName 可选覆盖目标名)。 */
|
|
867
|
+
profileImport(content: string, asName?: string): Promise<ProfileMeta>;
|
|
768
868
|
/** 读取定时备份配置(enabled / interval / 上次运行状态;无敏感字段)。 */
|
|
769
869
|
backupSchedule(): Promise<BackupScheduleStatus>;
|
|
770
870
|
/** 保存定时备份设置(enabled + interval);Host 校验后原子写 + 重排调度器。 */
|
|
@@ -780,6 +880,9 @@ declare class ConfigManagerApi {
|
|
|
780
880
|
deleteBackupFile(name: string): Promise<{
|
|
781
881
|
removed: boolean;
|
|
782
882
|
}>;
|
|
883
|
+
/** 「查看备份内容」:对 exports 目录内的备份文件做只读分析(reuse /analyze,零写入)。
|
|
884
|
+
* 返回分析 + 与当前配置的差异计划摘要("装/导这个备份会动你什么")。 */
|
|
885
|
+
inspectBackup(zipPath: string): Promise<BackupInspectResult>;
|
|
783
886
|
}
|
|
784
887
|
//#endregion
|
|
785
888
|
//#region src/sync/sync-engine.d.ts
|
|
@@ -809,6 +912,26 @@ interface SyncPullReport {
|
|
|
809
912
|
needsReview: boolean;
|
|
810
913
|
message?: string;
|
|
811
914
|
}
|
|
915
|
+
/** P0-②:push 前只读预览 ——「将推送什么」的单分区摘要(不写远端、不落盘)。 */
|
|
916
|
+
interface SyncPushPreviewSection {
|
|
917
|
+
/** 分区 id(将进入快照的 portable 分区) */
|
|
918
|
+
section: SectionId;
|
|
919
|
+
/** 分区内条目计数(adapter.export 的 counts 聚合;无计数时为 0) */
|
|
920
|
+
count: number;
|
|
921
|
+
/** 相对上次基线(sync-state)是否变化:true = 本次会更新该分区;false = 与基线一致 */
|
|
922
|
+
changed: boolean;
|
|
923
|
+
}
|
|
924
|
+
/** P0-②:push 前预览结果(零写入)。 */
|
|
925
|
+
interface SyncPushPreview {
|
|
926
|
+
ok: boolean;
|
|
927
|
+
/** 将推送的分区清单(含计数与变化标记) */
|
|
928
|
+
sections: SyncPushPreviewSection[];
|
|
929
|
+
/** 远端现有快照数(0 = 首次推送将创建首个基线) */
|
|
930
|
+
remoteSnapshotCount: number;
|
|
931
|
+
/** 加密快照:载荷将整体加密(分区计数与基线比较不可得) */
|
|
932
|
+
encrypted: boolean;
|
|
933
|
+
message?: string;
|
|
934
|
+
}
|
|
812
935
|
//#endregion
|
|
813
936
|
//#region src/client/sync/sync-api.d.ts
|
|
814
937
|
/** 远程同步通道类型:git(默认)或 webdav */
|
|
@@ -1126,6 +1249,8 @@ declare class SyncApi {
|
|
|
1126
1249
|
status(): Promise<SyncStatusResponse>;
|
|
1127
1250
|
/** 推送:导出 portable 分区 → 提交到私有 Git 仓库 → 更新 sync-state */
|
|
1128
1251
|
push(payload: SyncPushPayload): Promise<SyncPushReport>;
|
|
1252
|
+
/** P0-②:push 前只读预览(「将推送什么」,零写入远端)——body.preview=true 触发 */
|
|
1253
|
+
pushPreview(payload: SyncPushPayload): Promise<SyncPushPreview>;
|
|
1129
1254
|
/** 拉取差异预览:拉取远端最新快照 → 只读分析(绝不执行导入) */
|
|
1130
1255
|
pull(payload: SyncPullPayload): Promise<SyncPullReport>;
|
|
1131
1256
|
/** GitHub OAuth device flow:发起登录,返回一次性用户码 + 授权页 URL + flowId */
|
|
@@ -1241,6 +1366,8 @@ interface MarketListItem {
|
|
|
1241
1366
|
stars?: number;
|
|
1242
1367
|
/** 本地缓存状态:cached | fresh | none(UI 徽章) */
|
|
1243
1368
|
cacheState: 'cached' | 'fresh' | 'none';
|
|
1369
|
+
/** 分区清单(P2-⑭:已缓存条目从 L2 manifest 合并;未缓存条目缺省 = 未知,列表分区筛选时排除) */
|
|
1370
|
+
sections?: SectionId[];
|
|
1244
1371
|
}
|
|
1245
1372
|
/** POST /market/download 响应:条目详情 + 校验结果(dry-run 预览) */
|
|
1246
1373
|
interface MarketItemDetail {
|
|
@@ -1527,12 +1654,14 @@ interface ConfigManagerSectionInjected {
|
|
|
1527
1654
|
declare const zh$2: {
|
|
1528
1655
|
readonly 'section.label': "备份与迁移";
|
|
1529
1656
|
readonly 'section.description': "导出 / 导入 / 迁移 DSH 配置(备份不含密钥,加密备份可选)";
|
|
1657
|
+
readonly 'view.transfer': "导出与导入";
|
|
1530
1658
|
readonly 'view.export': "导出备份";
|
|
1531
1659
|
readonly 'view.import': "导入恢复";
|
|
1532
1660
|
readonly 'view.snapshots': "备份与快照";
|
|
1533
1661
|
readonly 'view.sync': "远程同步";
|
|
1534
1662
|
readonly 'view.market': "配置市场";
|
|
1535
1663
|
readonly 'view.about': "关于";
|
|
1664
|
+
readonly 'view.profiles': "配置文件";
|
|
1536
1665
|
readonly 'common.close': "关闭";
|
|
1537
1666
|
readonly 'common.cancel': "取消";
|
|
1538
1667
|
readonly 'common.back': "上一步";
|
|
@@ -1558,6 +1687,10 @@ declare const zh$2: {
|
|
|
1558
1687
|
readonly 'export.includeSecrets': "导出密钥";
|
|
1559
1688
|
readonly 'export.includeSecretsHint': "把真实密钥(凭据值)写入备份。密钥必须以加密形式保存:勾选时会自动选中「加密备份」;取消「加密备份」会同时取消「导出密钥」。";
|
|
1560
1689
|
readonly 'export.run': "开始导出";
|
|
1690
|
+
readonly 'export.preview': "预览将导出内容";
|
|
1691
|
+
readonly 'export.previewing': "正在统计…";
|
|
1692
|
+
readonly 'export.previewSummary': "将打包 {sections} 个分区,约 {size}(不含密钥)";
|
|
1693
|
+
readonly 'export.previewSkipped': "{count} 个分区导出失败已跳过";
|
|
1561
1694
|
readonly 'export.running': "正在导出…";
|
|
1562
1695
|
readonly 'export.download': "下载备份文件";
|
|
1563
1696
|
readonly 'export.saved': "已保存到下载目录:{name}";
|
|
@@ -1565,6 +1698,13 @@ declare const zh$2: {
|
|
|
1565
1698
|
readonly 'export.group.unknown': "其他";
|
|
1566
1699
|
readonly 'export.included': "已包含";
|
|
1567
1700
|
readonly 'export.excluded': "未包含";
|
|
1701
|
+
readonly 'export.naming': "文件名与备注(可选)";
|
|
1702
|
+
readonly 'export.fileName': "自定义文件名";
|
|
1703
|
+
readonly 'export.fileNameHint': "留空自动命名(dsh-config-<日期>.zip);无需手动输入 .zip 后缀,保存时自动补全。仅允许字母数字、空格、- _ .。";
|
|
1704
|
+
readonly 'export.fileNameInvalid': "文件名不合法:仅允许字母数字、空格、- _ .,不能包含路径分隔符。";
|
|
1705
|
+
readonly 'export.note': "备注";
|
|
1706
|
+
readonly 'export.notePlaceholder': "例如:迁移前的完整备份 / 2026-08 存档";
|
|
1707
|
+
readonly 'export.noteHint': "备注保存在本机备份列表中(随配置备份迁移),便于区分多个导出产物。";
|
|
1568
1708
|
readonly 'import.select.title': "选择备份文件";
|
|
1569
1709
|
readonly 'import.select.hint': "选择本机导出的 dsh-config-*.zip 备份文件开始导入。分析阶段只读,不会修改任何配置。";
|
|
1570
1710
|
readonly 'import.select.browse': "选择 ZIP 文件";
|
|
@@ -1634,11 +1774,19 @@ declare const zh$2: {
|
|
|
1634
1774
|
readonly 'snapshots.status': "状态";
|
|
1635
1775
|
readonly 'snapshots.entries': "条目";
|
|
1636
1776
|
readonly 'snapshots.plugins': "插件";
|
|
1777
|
+
readonly 'snapshots.actions': "操作";
|
|
1778
|
+
readonly 'snapshots.retentionHint': "最多自动保留 {count} 个快照(超出清理最旧的);置顶的快照不参与自动清理,只能手动删除。";
|
|
1779
|
+
readonly 'snapshots.pin': "置顶";
|
|
1780
|
+
readonly 'snapshots.unpin': "取消置顶";
|
|
1781
|
+
readonly 'snapshots.delete': "删除";
|
|
1782
|
+
readonly 'snapshots.deleteConfirmTitle': "删除快照";
|
|
1783
|
+
readonly 'snapshots.deleteConfirm': "确认删除 {time} 创建的快照?该导入前回滚点将被永久删除,不可恢复。";
|
|
1637
1784
|
readonly 'snapshots.status.pending': "进行中";
|
|
1638
1785
|
readonly 'snapshots.status.done': "已完成";
|
|
1639
1786
|
readonly 'snapshots.status.rolled-back': "已回滚";
|
|
1640
1787
|
readonly 'snapshots.status.unknown': "未知";
|
|
1641
1788
|
readonly 'snapshots.planTitle': "恢复计划预览";
|
|
1789
|
+
readonly 'snapshots.viewPlan': "查看恢复计划";
|
|
1642
1790
|
readonly 'snapshots.noActions': "该快照无可用恢复动作(或全部跳过)。";
|
|
1643
1791
|
readonly 'snapshots.execute': "执行恢复";
|
|
1644
1792
|
readonly 'snapshots.executing': "恢复执行中…";
|
|
@@ -1659,6 +1807,15 @@ declare const zh$2: {
|
|
|
1659
1807
|
readonly 'backupSchedule.interval.12h': "每 12 小时";
|
|
1660
1808
|
readonly 'backupSchedule.interval.24h': "每 24 小时";
|
|
1661
1809
|
readonly 'backupSchedule.interval.7d': "每 7 天";
|
|
1810
|
+
readonly 'backupSchedule.interval.custom': "自定义(每周固定时刻)";
|
|
1811
|
+
readonly 'backupSchedule.customHint': "每周在选定星期与时刻各执行一次全量备份(错过的时间点不补跑)";
|
|
1812
|
+
readonly 'backupSchedule.weekday.sunday': "周日";
|
|
1813
|
+
readonly 'backupSchedule.weekday.monday': "周一";
|
|
1814
|
+
readonly 'backupSchedule.weekday.tuesday': "周二";
|
|
1815
|
+
readonly 'backupSchedule.weekday.wednesday': "周三";
|
|
1816
|
+
readonly 'backupSchedule.weekday.thursday': "周四";
|
|
1817
|
+
readonly 'backupSchedule.weekday.friday': "周五";
|
|
1818
|
+
readonly 'backupSchedule.weekday.saturday': "周六";
|
|
1662
1819
|
readonly 'backupSchedule.save': "保存设置";
|
|
1663
1820
|
readonly 'backupSchedule.saved': "设置已保存";
|
|
1664
1821
|
readonly 'backupSchedule.runNow': "立即备份";
|
|
@@ -1668,6 +1825,7 @@ declare const zh$2: {
|
|
|
1668
1825
|
readonly 'backupSchedule.status.success': "成功";
|
|
1669
1826
|
readonly 'backupSchedule.status.skipped': "已跳过";
|
|
1670
1827
|
readonly 'backupSchedule.status.failed': "失败";
|
|
1828
|
+
readonly 'backupSchedule.consecutiveFailures': "定时备份连续失败 {count} 次,请检查配置(磁盘空间 / 权限 / 分区导出错误)";
|
|
1671
1829
|
readonly 'backupSchedule.loading': "加载定时备份设置…";
|
|
1672
1830
|
readonly 'backupSchedule.error': "定时备份设置加载失败";
|
|
1673
1831
|
readonly 'backupFiles.title': "备份文件";
|
|
@@ -1682,6 +1840,19 @@ declare const zh$2: {
|
|
|
1682
1840
|
readonly 'backupFiles.delete': "删除";
|
|
1683
1841
|
readonly 'backupFiles.deleteConfirmTitle': "删除备份文件";
|
|
1684
1842
|
readonly 'backupFiles.deleteConfirm': "确认删除备份文件「{name}」?此操作不可恢复。";
|
|
1843
|
+
readonly 'backupFiles.searchPlaceholder': "按文件名或备注搜索…";
|
|
1844
|
+
readonly 'backupFiles.searchEmpty': "没有匹配的备份文件";
|
|
1845
|
+
readonly 'backupFiles.inspect': "查看 / 对比";
|
|
1846
|
+
readonly 'backupFiles.inspectLoading': "正在分析备份内容…";
|
|
1847
|
+
readonly 'backupFiles.inspectEmpty': "该备份无法分析(文件损坏或格式不支持)";
|
|
1848
|
+
readonly 'backupFiles.inspectSections': "包含的分区";
|
|
1849
|
+
readonly 'backupFiles.inspectDiff': "与此备份的差异(只读预览)";
|
|
1850
|
+
readonly 'backupFiles.inspectItems': "变更明细";
|
|
1851
|
+
readonly 'backupFiles.inspectGroup.conflicts': "冲突(需决策)";
|
|
1852
|
+
readonly 'backupFiles.inspectGroup.changes': "变更(将写入)";
|
|
1853
|
+
readonly 'backupFiles.inspectGroup.paths': "路径映射(需处理)";
|
|
1854
|
+
readonly 'backupFiles.inspectGroup.skipped': "已一致(无需处理)";
|
|
1855
|
+
readonly 'backupFiles.inspectGroup.others': "其他";
|
|
1685
1856
|
readonly 'report.export.title': "导出完成";
|
|
1686
1857
|
readonly 'report.import.title': "导入结果";
|
|
1687
1858
|
readonly 'report.rollback.title': "回滚报告";
|
|
@@ -1689,6 +1860,14 @@ declare const zh$2: {
|
|
|
1689
1860
|
readonly 'report.action.viewDetails': "查看详情";
|
|
1690
1861
|
readonly 'report.action.done': "完成";
|
|
1691
1862
|
readonly 'report.needsRestart': "插件 / MCP 变更将在重启 DSH 后生效。";
|
|
1863
|
+
readonly 'nextSteps.title': "接下来需要处理";
|
|
1864
|
+
readonly 'nextSteps.done': "全部完成,无需额外处理";
|
|
1865
|
+
readonly 'nextSteps.restart.title': "重启 DSH 后生效({count})";
|
|
1866
|
+
readonly 'nextSteps.restart.hint': "以下变更需要重启 DSH 才会生效:";
|
|
1867
|
+
readonly 'nextSteps.secrets.title': "补录凭据({count})";
|
|
1868
|
+
readonly 'nextSteps.secrets.hint': "以下凭据未随备份导出,需在本机手动补录:";
|
|
1869
|
+
readonly 'nextSteps.unresolved.title': "失败 / 已跳过({count})";
|
|
1870
|
+
readonly 'nextSteps.unresolved.hint': "以下项未成功应用,可在结果页点击「重试」:";
|
|
1692
1871
|
readonly 'error.title': "操作失败";
|
|
1693
1872
|
readonly 'error.hint': "错误消息已自动脱敏,不会泄露任何密钥信息。";
|
|
1694
1873
|
readonly 'starPrompt.title': "喜欢 Config Manager 吗?";
|
|
@@ -1708,6 +1887,49 @@ declare const zh$2: {
|
|
|
1708
1887
|
readonly 'about.authorLabel': "作者";
|
|
1709
1888
|
readonly 'about.loading': "正在获取版本信息…";
|
|
1710
1889
|
readonly 'about.retryStatus': "重新获取";
|
|
1890
|
+
readonly 'about.cli.title': "CLI 救援工具";
|
|
1891
|
+
readonly 'about.cli.hint': "GUI 运行在 DSH 内部——DSH 无法启动时,独立安装的 CLI(dsh-config-manager)是第一救援手段:列快照 / 离线恢复 / 一键重装 DSH,全程无需 DSH 运行。安装一次即可在任何机器上用:";
|
|
1892
|
+
readonly 'about.cli.docs': "CLI 使用文档";
|
|
1893
|
+
readonly 'profiles.title': "配置档案";
|
|
1894
|
+
readonly 'profiles.subtitle': "把当前 DSH 配置保存为多套档案(Work / Personal / …),随时切换;切换含预览 + 自动快照 + 失败回滚。";
|
|
1895
|
+
readonly 'profiles.save.title': "保存当前配置为档案";
|
|
1896
|
+
readonly 'profiles.save.hint': "输入档案名并保存:内容复用导出管道(不含密钥),文件类分区(技能/预设)一并内嵌。";
|
|
1897
|
+
readonly 'profiles.save.placeholder': "例如 Work / Personal / Minimal";
|
|
1898
|
+
readonly 'profiles.save.action': "保存档案";
|
|
1899
|
+
readonly 'profiles.save.saving': "保存中…";
|
|
1900
|
+
readonly 'profiles.nameInvalid': "档案名不合法:仅允许字母数字与常见字符,禁止路径分隔符(/ \\)与 ..";
|
|
1901
|
+
readonly 'profiles.name': "档案名";
|
|
1902
|
+
readonly 'profiles.sections': "分区";
|
|
1903
|
+
readonly 'profiles.updatedAt': "更新时间";
|
|
1904
|
+
readonly 'profiles.loading': "加载档案中…";
|
|
1905
|
+
readonly 'profiles.empty': "暂无档案。先保存一份当前配置即可开始。";
|
|
1906
|
+
readonly 'profiles.switch': "切换";
|
|
1907
|
+
readonly 'profiles.previewHint': "点击查看切换预览(只读)";
|
|
1908
|
+
readonly 'profiles.rename': "重命名";
|
|
1909
|
+
readonly 'profiles.delete': "删除";
|
|
1910
|
+
readonly 'profiles.renameTitle': "重命名档案";
|
|
1911
|
+
readonly 'profiles.renameMessage': "将档案「{name}」重命名为:";
|
|
1912
|
+
readonly 'profiles.deleteTitle': "删除档案";
|
|
1913
|
+
readonly 'profiles.deleteMessage': "确认删除档案「{name}」?该组配置快照将被永久删除,不可恢复。";
|
|
1914
|
+
readonly 'profiles.import.title': "导入档案";
|
|
1915
|
+
readonly 'profiles.import.hint': "导入导出的 profile.json 文件(本机或他机导出的档案,含文件类分区内嵌数据)。";
|
|
1916
|
+
readonly 'profiles.import.choose': "选择 JSON 文件";
|
|
1917
|
+
readonly 'profiles.switchPreviewTitle': "切换预览:{name}";
|
|
1918
|
+
readonly 'profiles.previewing': "正在分析切换计划…";
|
|
1919
|
+
readonly 'profiles.previewSummary': "切换影响";
|
|
1920
|
+
readonly 'profiles.previewWillChange': "将变更 {count} 项";
|
|
1921
|
+
readonly 'profiles.previewUnchanged': "已一致 {count} 项";
|
|
1922
|
+
readonly 'profiles.previewConflicts': "冲突 {count}";
|
|
1923
|
+
readonly 'profiles.previewSecrets': "需补录密钥 {count}";
|
|
1924
|
+
readonly 'profiles.previewRestart': "需重启 DSH 生效";
|
|
1925
|
+
readonly 'profiles.previewNote': "以上为只读预览(零写入)。确认后会自动创建快照并执行,失败时整体回滚。";
|
|
1926
|
+
readonly 'profiles.previewSections': "档案包含的分区";
|
|
1927
|
+
readonly 'profiles.previewItems': "变更明细";
|
|
1928
|
+
readonly 'profiles.switchConfirm': "确认切换";
|
|
1929
|
+
readonly 'profiles.switching': "切换中…(自动快照 + 分阶段应用)";
|
|
1930
|
+
readonly 'profiles.switchDone': "切换完成:{count} 项已应用";
|
|
1931
|
+
readonly 'profiles.switchFailed': "切换失败(部分项未应用)";
|
|
1932
|
+
readonly 'profiles.switchRolledBack': "切换失败,已整体回滚";
|
|
1711
1933
|
};
|
|
1712
1934
|
/** 字典键联合(注册处 compile-time 校验) */
|
|
1713
1935
|
type ConfigManagerKey = keyof typeof zh$2;
|
|
@@ -1808,6 +2030,11 @@ declare const zh$1: {
|
|
|
1808
2030
|
readonly 'syncflow.rollingBack': "正在回滚…";
|
|
1809
2031
|
readonly 'syncflow.rollbackDone': "已回滚到应用前";
|
|
1810
2032
|
readonly 'syncflow.needsRestart': "部分改动需要重启 DSH 后生效";
|
|
2033
|
+
readonly 'syncflow.pushPreviewTitle': "确认推送";
|
|
2034
|
+
readonly 'syncflow.pushPreviewSections': "将推送的分区";
|
|
2035
|
+
readonly 'syncflow.pushConfirm': "确认推送";
|
|
2036
|
+
readonly 'syncflow.pushing': "正在推送…";
|
|
2037
|
+
readonly 'syncflow.pushFirstBaseline': "远端暂无快照:本次将创建首个同步基线";
|
|
1811
2038
|
readonly 'mode.title': "同步模式";
|
|
1812
2039
|
readonly 'mode.hint': "选择推送时导出哪些分区:默认 = 推荐分区一键推送(快速导出);高级 = 自定义勾选(自定义导出)。";
|
|
1813
2040
|
readonly 'mode.default': "默认(快速导出)";
|
|
@@ -1913,6 +2140,8 @@ declare const zh: {
|
|
|
1913
2140
|
readonly 'list.noItems': "该市场暂无条目。";
|
|
1914
2141
|
readonly 'list.searchPlaceholder': "搜索名称 / 作者 / 描述…";
|
|
1915
2142
|
readonly 'list.categoriesAll': "全部类别";
|
|
2143
|
+
readonly 'list.sectionsAll': "全部分区";
|
|
2144
|
+
readonly 'list.sectionsUnknown': "另有 {count} 个条目未下载,无法按分区匹配";
|
|
1916
2145
|
readonly 'list.sourceAll': "全部来源";
|
|
1917
2146
|
readonly 'list.sourceOfficial': "官方配置";
|
|
1918
2147
|
readonly 'list.sourcePersonal': "个人配置";
|
|
@@ -1935,6 +2164,12 @@ declare const zh: {
|
|
|
1935
2164
|
readonly 'detail.emptySections': "该条目未包含任何可导入分区";
|
|
1936
2165
|
readonly 'detail.needReview': "需要人工确认";
|
|
1937
2166
|
readonly 'detail.previewHint': "以下为只读 dry-run 预览(零写入)。确认导入将复用现有安全管道(快照 + 校验 + 失败回滚)。";
|
|
2167
|
+
readonly 'detail.impact.willChange': "将变更 {count} 项";
|
|
2168
|
+
readonly 'detail.impact.unchanged': "已一致 {count} 项";
|
|
2169
|
+
readonly 'detail.impact.conflicts': "冲突 {count}";
|
|
2170
|
+
readonly 'detail.impact.secrets': "需补录密钥 {count}";
|
|
2171
|
+
readonly 'detail.impact.paths': "路径映射 {count}";
|
|
2172
|
+
readonly 'detail.impact.restart': "需重启 DSH 生效";
|
|
1938
2173
|
readonly 'detail.import': "确认导入";
|
|
1939
2174
|
readonly 'detail.back': "返回列表";
|
|
1940
2175
|
readonly 'detail.approval.title': "逐分区批准导入";
|