dsh-config-manager 0.1.0
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 +216 -0
- package/README.zh-CN.md +218 -0
- package/cordis.patch.yml +45 -0
- package/dsh.bundle.patch +21 -0
- package/dsh.client +39 -0
- package/lib/adapters/agent-presets.d.ts +13 -0
- package/lib/adapters/agent-presets.js +14 -0
- package/lib/adapters/agent-presets.js.map +1 -0
- package/lib/adapters/credentials.d.ts +36 -0
- package/lib/adapters/credentials.js +121 -0
- package/lib/adapters/credentials.js.map +1 -0
- package/lib/adapters/file-collection.d.ts +14 -0
- package/lib/adapters/file-collection.js +102 -0
- package/lib/adapters/file-collection.js.map +1 -0
- package/lib/adapters/index.d.ts +38 -0
- package/lib/adapters/index.js +46 -0
- package/lib/adapters/index.js.map +1 -0
- package/lib/adapters/mcp.d.ts +27 -0
- package/lib/adapters/mcp.js +175 -0
- package/lib/adapters/mcp.js.map +1 -0
- package/lib/adapters/plugin-files.d.ts +15 -0
- package/lib/adapters/plugin-files.js +91 -0
- package/lib/adapters/plugin-files.js.map +1 -0
- package/lib/adapters/plugins.d.ts +13 -0
- package/lib/adapters/plugins.js +177 -0
- package/lib/adapters/plugins.js.map +1 -0
- package/lib/adapters/prompts.d.ts +29 -0
- package/lib/adapters/prompts.js +228 -0
- package/lib/adapters/prompts.js.map +1 -0
- package/lib/adapters/providers.d.ts +33 -0
- package/lib/adapters/providers.js +143 -0
- package/lib/adapters/providers.js.map +1 -0
- package/lib/adapters/sessions.d.ts +14 -0
- package/lib/adapters/sessions.js +15 -0
- package/lib/adapters/sessions.js.map +1 -0
- package/lib/adapters/settings.d.ts +23 -0
- package/lib/adapters/settings.js +142 -0
- package/lib/adapters/settings.js.map +1 -0
- package/lib/adapters/skills.d.ts +13 -0
- package/lib/adapters/skills.js +14 -0
- package/lib/adapters/skills.js.map +1 -0
- package/lib/adapters/test-helpers.d.ts +99 -0
- package/lib/adapters/test-helpers.js +192 -0
- package/lib/adapters/test-helpers.js.map +1 -0
- package/lib/adapters/ui.d.ts +26 -0
- package/lib/adapters/ui.js +88 -0
- package/lib/adapters/ui.js.map +1 -0
- package/lib/adapters/workspaces.d.ts +12 -0
- package/lib/adapters/workspaces.js +92 -0
- package/lib/adapters/workspaces.js.map +1 -0
- package/lib/client.d.ts +377 -0
- package/lib/client.js +2598 -0
- package/lib/client.js.map +1 -0
- package/lib/core/analyzer.d.ts +35 -0
- package/lib/core/analyzer.js +563 -0
- package/lib/core/analyzer.js.map +1 -0
- package/lib/core/backup.d.ts +29 -0
- package/lib/core/backup.js +184 -0
- package/lib/core/backup.js.map +1 -0
- package/lib/core/exporter.d.ts +37 -0
- package/lib/core/exporter.js +222 -0
- package/lib/core/exporter.js.map +1 -0
- package/lib/core/importer.d.ts +42 -0
- package/lib/core/importer.js +25 -0
- package/lib/core/importer.js.map +1 -0
- package/lib/core/index.d.ts +12 -0
- package/lib/core/index.js +11 -0
- package/lib/core/index.js.map +1 -0
- package/lib/core/rollback.d.ts +9 -0
- package/lib/core/rollback.js +136 -0
- package/lib/core/rollback.js.map +1 -0
- package/lib/core/types.d.ts +331 -0
- package/lib/core/types.js +18 -0
- package/lib/core/types.js.map +1 -0
- package/lib/core/validator.d.ts +18 -0
- package/lib/core/validator.js +77 -0
- package/lib/core/validator.js.map +1 -0
- package/lib/index.d.ts +51 -0
- package/lib/index.js +875 -0
- package/lib/index.js.map +1 -0
- package/lib/migrations/index.d.ts +29 -0
- package/lib/migrations/index.js +56 -0
- package/lib/migrations/index.js.map +1 -0
- package/lib/migrations/v1-to-v2.d.ts +9 -0
- package/lib/migrations/v1-to-v2.js +10 -0
- package/lib/migrations/v1-to-v2.js.map +1 -0
- package/lib/profiles/index.d.ts +4 -0
- package/lib/profiles/index.js +5 -0
- package/lib/profiles/index.js.map +1 -0
- package/lib/profiles/profile-manager.d.ts +102 -0
- package/lib/profiles/profile-manager.js +522 -0
- package/lib/profiles/profile-manager.js.map +1 -0
- package/lib/schema/config.d.ts +28 -0
- package/lib/schema/config.js +136 -0
- package/lib/schema/config.js.map +1 -0
- package/lib/schema/manifest.d.ts +28 -0
- package/lib/schema/manifest.js +109 -0
- package/lib/schema/manifest.js.map +1 -0
- package/lib/schema/types.d.ts +169 -0
- package/lib/schema/types.js +8 -0
- package/lib/schema/types.js.map +1 -0
- package/lib/schema/versions.d.ts +27 -0
- package/lib/schema/versions.js +50 -0
- package/lib/schema/versions.js.map +1 -0
- package/lib/security/encryption.d.ts +41 -0
- package/lib/security/encryption.js +152 -0
- package/lib/security/encryption.js.map +1 -0
- package/lib/security/index.d.ts +16 -0
- package/lib/security/index.js +17 -0
- package/lib/security/index.js.map +1 -0
- package/lib/security/integrity.d.ts +30 -0
- package/lib/security/integrity.js +78 -0
- package/lib/security/integrity.js.map +1 -0
- package/lib/security/redaction.d.ts +26 -0
- package/lib/security/redaction.js +95 -0
- package/lib/security/redaction.js.map +1 -0
- package/lib/security/secret-scanner.d.ts +48 -0
- package/lib/security/secret-scanner.js +253 -0
- package/lib/security/secret-scanner.js.map +1 -0
- package/lib/security/zip-security.d.ts +27 -0
- package/lib/security/zip-security.js +154 -0
- package/lib/security/zip-security.js.map +1 -0
- package/lib/ui/conflict-view.d.ts +28 -0
- package/lib/ui/conflict-view.js +49 -0
- package/lib/ui/conflict-view.js.map +1 -0
- package/lib/ui/errors.d.ts +17 -0
- package/lib/ui/errors.js +76 -0
- package/lib/ui/errors.js.map +1 -0
- package/lib/ui/export-flow.d.ts +62 -0
- package/lib/ui/export-flow.js +79 -0
- package/lib/ui/export-flow.js.map +1 -0
- package/lib/ui/import-wizard.d.ts +67 -0
- package/lib/ui/import-wizard.js +169 -0
- package/lib/ui/import-wizard.js.map +1 -0
- package/lib/ui/path-mapping.d.ts +38 -0
- package/lib/ui/path-mapping.js +75 -0
- package/lib/ui/path-mapping.js.map +1 -0
- package/lib/ui/progress.d.ts +27 -0
- package/lib/ui/progress.js +76 -0
- package/lib/ui/progress.js.map +1 -0
- package/lib/ui/report.d.ts +21 -0
- package/lib/ui/report.js +146 -0
- package/lib/ui/report.js.map +1 -0
- package/lib/ui/test-helpers.d.ts +62 -0
- package/lib/ui/test-helpers.js +147 -0
- package/lib/ui/test-helpers.js.map +1 -0
- package/lib/ui/types.d.ts +129 -0
- package/lib/ui/types.js +21 -0
- package/lib/ui/types.js.map +1 -0
- package/lib/utils/hashing.d.ts +17 -0
- package/lib/utils/hashing.js +41 -0
- package/lib/utils/hashing.js.map +1 -0
- package/lib/utils/json.d.ts +24 -0
- package/lib/utils/json.js +76 -0
- package/lib/utils/json.js.map +1 -0
- package/lib/utils/logger.d.ts +39 -0
- package/lib/utils/logger.js +82 -0
- package/lib/utils/logger.js.map +1 -0
- package/lib/utils/paths.d.ts +31 -0
- package/lib/utils/paths.js +132 -0
- package/lib/utils/paths.js.map +1 -0
- package/lib/utils/zip.d.ts +54 -0
- package/lib/utils/zip.js +285 -0
- package/lib/utils/zip.js.map +1 -0
- package/package.json +109 -0
- package/src/adapters/agent-presets.ts +14 -0
- package/src/adapters/credentials.test.ts +90 -0
- package/src/adapters/credentials.ts +141 -0
- package/src/adapters/file-collection.ts +110 -0
- package/src/adapters/files.test.ts +113 -0
- package/src/adapters/index.ts +69 -0
- package/src/adapters/mcp.test.ts +96 -0
- package/src/adapters/mcp.ts +181 -0
- package/src/adapters/plugin-files.ts +96 -0
- package/src/adapters/plugins.test.ts +72 -0
- package/src/adapters/plugins.ts +176 -0
- package/src/adapters/prompts.test.ts +110 -0
- package/src/adapters/prompts.ts +226 -0
- package/src/adapters/providers.test.ts +125 -0
- package/src/adapters/providers.ts +161 -0
- package/src/adapters/roundtrip.test.ts +188 -0
- package/src/adapters/sessions.ts +15 -0
- package/src/adapters/settings.test.ts +93 -0
- package/src/adapters/settings.ts +165 -0
- package/src/adapters/skills.ts +14 -0
- package/src/adapters/test-helpers.ts +207 -0
- package/src/adapters/ui.test.ts +56 -0
- package/src/adapters/ui.ts +106 -0
- package/src/adapters/workspaces.test.ts +79 -0
- package/src/adapters/workspaces.ts +95 -0
- package/src/client/CLIENT_DEPENDENCIES.md +101 -0
- package/src/client/ConfigManagerSection.tsx +60 -0
- package/src/client/api.ts +270 -0
- package/src/client/client-types.ts +27 -0
- package/src/client/common/ErrorBanner.tsx +68 -0
- package/src/client/common/ProgressBar.tsx +49 -0
- package/src/client/common/ReportView.tsx +117 -0
- package/src/client/common/ui.tsx +165 -0
- package/src/client/config-manager.module.css +759 -0
- package/src/client/css-modules.d.ts +8 -0
- package/src/client/export/ExportView.tsx +222 -0
- package/src/client/import/ConflictList.tsx +72 -0
- package/src/client/import/ImportWizardView.tsx +406 -0
- package/src/client/import/PathMappingForm.tsx +77 -0
- package/src/client/index.ts +65 -0
- package/src/client/locales.ts +182 -0
- package/src/core/analyzer.ts +631 -0
- package/src/core/backup.ts +212 -0
- package/src/core/exporter.ts +246 -0
- package/src/core/importer.ts +66 -0
- package/src/core/index.ts +39 -0
- package/src/core/rollback.ts +140 -0
- package/src/core/smoke.test.ts +717 -0
- package/src/core/types.ts +343 -0
- package/src/core/validator.ts +84 -0
- package/src/index.ts +942 -0
- package/src/migrations/index.ts +71 -0
- package/src/migrations/v1-to-v2.ts +17 -0
- package/src/profiles/index.ts +8 -0
- package/src/profiles/profile-manager.test.ts +280 -0
- package/src/profiles/profile-manager.ts +606 -0
- package/src/schema/config.ts +137 -0
- package/src/schema/manifest.ts +124 -0
- package/src/schema/types.ts +179 -0
- package/src/schema/versions.ts +55 -0
- package/src/security/encryption.ts +180 -0
- package/src/security/index.ts +16 -0
- package/src/security/integrity.ts +102 -0
- package/src/security/redaction.ts +101 -0
- package/src/security/secret-scanner.ts +275 -0
- package/src/security/security.test.ts +796 -0
- package/src/security/zip-security.ts +180 -0
- package/src/ui/conflict-view.test.ts +62 -0
- package/src/ui/conflict-view.ts +65 -0
- package/src/ui/errors.test.ts +44 -0
- package/src/ui/errors.ts +95 -0
- package/src/ui/export-flow.test.ts +75 -0
- package/src/ui/export-flow.ts +128 -0
- package/src/ui/import-wizard.test.ts +128 -0
- package/src/ui/import-wizard.ts +208 -0
- package/src/ui/path-mapping.test.ts +67 -0
- package/src/ui/path-mapping.ts +103 -0
- package/src/ui/progress.test.ts +42 -0
- package/src/ui/progress.ts +90 -0
- package/src/ui/report.test.ts +93 -0
- package/src/ui/report.ts +140 -0
- package/src/ui/test-helpers.ts +177 -0
- package/src/ui/types.ts +193 -0
- package/src/utils/hashing.ts +53 -0
- package/src/utils/json.ts +77 -0
- package/src/utils/logger.ts +114 -0
- package/src/utils/paths.ts +122 -0
- package/src/utils/zip.ts +332 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rollback(规范 §17 / 设计 §8.2):导入失败时逆序执行快照条目的补偿动作。
|
|
3
|
+
*
|
|
4
|
+
* 诚实原则:
|
|
5
|
+
* - 尽力回滚:单项失败不停止其余补偿,最终如实报告 full / partial;
|
|
6
|
+
* - credential 值 DSH 永不回读 → existed=true 的凭据无法自动恢复原值,
|
|
7
|
+
* 如实标记 failed + manualHint(人工补录);
|
|
8
|
+
* - settings 回滚仍走 expectedRevision 乐观锁,避免覆盖导入后用户的新修改。
|
|
9
|
+
*/
|
|
10
|
+
import { resolveFileTarget } from './backup.ts';
|
|
11
|
+
import type {
|
|
12
|
+
ConfigAdapter, HostContext, RollbackReport, Snapshot, SnapshotEntry, SnapshotStore,
|
|
13
|
+
} from './types.ts';
|
|
14
|
+
|
|
15
|
+
export interface RollbackOptions {
|
|
16
|
+
ctx: HostContext;
|
|
17
|
+
snapshot: Snapshot;
|
|
18
|
+
store?: SnapshotStore;
|
|
19
|
+
adapters?: ConfigAdapter[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** 逆序补偿单条快照条目;返回 null=成功,否则为失败原因 */
|
|
23
|
+
async function compensateOne(
|
|
24
|
+
entry: SnapshotEntry,
|
|
25
|
+
ctx: HostContext,
|
|
26
|
+
store: SnapshotStore | undefined,
|
|
27
|
+
): Promise<{ reason: string; manualHint?: string } | null> {
|
|
28
|
+
switch (entry.kind) {
|
|
29
|
+
case 'settingsNamespace': {
|
|
30
|
+
try {
|
|
31
|
+
if (!entry.existed) {
|
|
32
|
+
// 原目标不存在该 namespace:若导入已创建它,DSH settings 无删除语义 → 无法恢复「不存在」
|
|
33
|
+
let current: unknown = null;
|
|
34
|
+
try {
|
|
35
|
+
current = await ctx.settings.describe(entry.ref);
|
|
36
|
+
} catch {
|
|
37
|
+
current = null;
|
|
38
|
+
}
|
|
39
|
+
if (current === null) return null; // 本来就没有且未创建 → 无需恢复
|
|
40
|
+
return {
|
|
41
|
+
reason: '该 namespace 由导入创建,DSH settings 无删除语义',
|
|
42
|
+
manualHint: `namespace "${entry.ref}" 需人工删除或合并`,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
// 用当前 revision 作乐观锁基准:读时即锁,冲突则如实失败(不覆盖并发修改)
|
|
46
|
+
const current = await ctx.settings.describe(entry.ref);
|
|
47
|
+
await ctx.settings.replace(entry.ref, entry.before, current.revision);
|
|
48
|
+
return null;
|
|
49
|
+
} catch (err) {
|
|
50
|
+
return { reason: err instanceof Error ? err.message : String(err), manualHint: `settings namespace "${entry.ref}" 需人工核对` };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
case 'credential': {
|
|
54
|
+
if (entry.existed) {
|
|
55
|
+
// 值不可回读:无法自动恢复原值
|
|
56
|
+
return {
|
|
57
|
+
reason: 'DSH 不回读凭据值,无法自动恢复',
|
|
58
|
+
manualHint: `凭据 "${entry.ref}" 请人工重新填写`,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
await ctx.credentials.unset(entry.ref);
|
|
63
|
+
return null;
|
|
64
|
+
} catch (err) {
|
|
65
|
+
return { reason: err instanceof Error ? err.message : String(err) };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
case 'patchLine': {
|
|
69
|
+
try {
|
|
70
|
+
const file = entry.ref.split('\u0000')[0] ?? 'cordis.patch.yml';
|
|
71
|
+
const lineId = entry.ref.includes('\u0000') ? entry.ref.split('\u0000')[1]! : entry.ref;
|
|
72
|
+
await ctx.patchFile.applyPatchChanges(file, [
|
|
73
|
+
{ lineId, raw: entry.before, action: entry.before === null ? 'remove' : 'update' },
|
|
74
|
+
]);
|
|
75
|
+
return null;
|
|
76
|
+
} catch (err) {
|
|
77
|
+
return { reason: err instanceof Error ? err.message : String(err), manualHint: `patch 行 "${entry.ref}" 需人工核对` };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
case 'file': {
|
|
81
|
+
try {
|
|
82
|
+
const abs = resolveFileTarget(ctx, entry.adapter, entry.ref);
|
|
83
|
+
if (entry.existed && entry.copiedTo && store) {
|
|
84
|
+
const data = await store.readBlob(entry.snapshotId ?? '', entry.copiedTo);
|
|
85
|
+
await ctx.fs.writeFile(abs, data);
|
|
86
|
+
} else if (!entry.existed) {
|
|
87
|
+
// 原文件不存在 → 删除导入写入的文件
|
|
88
|
+
if (await ctx.fs.exists(abs)) await ctx.fs.remove(abs);
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
} catch (err) {
|
|
92
|
+
return { reason: err instanceof Error ? err.message : String(err), manualHint: `文件 "${entry.ref}" 需人工恢复` };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
case 'workspaceRecord': {
|
|
96
|
+
try {
|
|
97
|
+
if (entry.before === null) {
|
|
98
|
+
await ctx.workspace.removeRecord?.(entry.ref);
|
|
99
|
+
} else {
|
|
100
|
+
await ctx.workspace.writeRecord(entry.before as never);
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
} catch (err) {
|
|
104
|
+
return { reason: err instanceof Error ? err.message : String(err), manualHint: `workspace "${entry.ref}" 需人工核对` };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
default:
|
|
108
|
+
return { reason: `未知快照条目类型 ${entry.kind}` };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** 回滚:逆序补偿全部条目;返回诚实报告(full / partial) */
|
|
113
|
+
export async function rollback(opts: RollbackOptions): Promise<RollbackReport> {
|
|
114
|
+
const { ctx, snapshot, store, adapters } = opts;
|
|
115
|
+
const restored: string[] = [];
|
|
116
|
+
const failed: RollbackReport['failed'] = [];
|
|
117
|
+
|
|
118
|
+
// 逆序遍历;adapter 自带的 rollback? 优先,否则引擎通用补偿
|
|
119
|
+
const entries = [...snapshot.entries].reverse();
|
|
120
|
+
for (const entry of entries) {
|
|
121
|
+
const adapter = adapters?.find((a) => a.id === entry.adapter);
|
|
122
|
+
let error: { reason: string; manualHint?: string } | null = null;
|
|
123
|
+
if (adapter?.rollback) {
|
|
124
|
+
try {
|
|
125
|
+
await adapter.rollback([entry], ctx);
|
|
126
|
+
} catch (err) {
|
|
127
|
+
error = { reason: err instanceof Error ? err.message : String(err) };
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
error = await compensateOne(entry, ctx, store);
|
|
131
|
+
}
|
|
132
|
+
if (error === null) {
|
|
133
|
+
restored.push(`${entry.adapter}:${entry.ref}`);
|
|
134
|
+
} else {
|
|
135
|
+
failed.push({ item: `${entry.adapter}:${entry.ref}`, reason: error.reason, manualHint: error.manualHint });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return { full: failed.length === 0, restored, failed };
|
|
140
|
+
}
|