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.
Files changed (253) hide show
  1. package/README.md +216 -0
  2. package/README.zh-CN.md +218 -0
  3. package/cordis.patch.yml +45 -0
  4. package/dsh.bundle.patch +21 -0
  5. package/dsh.client +39 -0
  6. package/lib/adapters/agent-presets.d.ts +13 -0
  7. package/lib/adapters/agent-presets.js +14 -0
  8. package/lib/adapters/agent-presets.js.map +1 -0
  9. package/lib/adapters/credentials.d.ts +36 -0
  10. package/lib/adapters/credentials.js +121 -0
  11. package/lib/adapters/credentials.js.map +1 -0
  12. package/lib/adapters/file-collection.d.ts +14 -0
  13. package/lib/adapters/file-collection.js +102 -0
  14. package/lib/adapters/file-collection.js.map +1 -0
  15. package/lib/adapters/index.d.ts +38 -0
  16. package/lib/adapters/index.js +46 -0
  17. package/lib/adapters/index.js.map +1 -0
  18. package/lib/adapters/mcp.d.ts +27 -0
  19. package/lib/adapters/mcp.js +175 -0
  20. package/lib/adapters/mcp.js.map +1 -0
  21. package/lib/adapters/plugin-files.d.ts +15 -0
  22. package/lib/adapters/plugin-files.js +91 -0
  23. package/lib/adapters/plugin-files.js.map +1 -0
  24. package/lib/adapters/plugins.d.ts +13 -0
  25. package/lib/adapters/plugins.js +177 -0
  26. package/lib/adapters/plugins.js.map +1 -0
  27. package/lib/adapters/prompts.d.ts +29 -0
  28. package/lib/adapters/prompts.js +228 -0
  29. package/lib/adapters/prompts.js.map +1 -0
  30. package/lib/adapters/providers.d.ts +33 -0
  31. package/lib/adapters/providers.js +143 -0
  32. package/lib/adapters/providers.js.map +1 -0
  33. package/lib/adapters/sessions.d.ts +14 -0
  34. package/lib/adapters/sessions.js +15 -0
  35. package/lib/adapters/sessions.js.map +1 -0
  36. package/lib/adapters/settings.d.ts +23 -0
  37. package/lib/adapters/settings.js +142 -0
  38. package/lib/adapters/settings.js.map +1 -0
  39. package/lib/adapters/skills.d.ts +13 -0
  40. package/lib/adapters/skills.js +14 -0
  41. package/lib/adapters/skills.js.map +1 -0
  42. package/lib/adapters/test-helpers.d.ts +99 -0
  43. package/lib/adapters/test-helpers.js +192 -0
  44. package/lib/adapters/test-helpers.js.map +1 -0
  45. package/lib/adapters/ui.d.ts +26 -0
  46. package/lib/adapters/ui.js +88 -0
  47. package/lib/adapters/ui.js.map +1 -0
  48. package/lib/adapters/workspaces.d.ts +12 -0
  49. package/lib/adapters/workspaces.js +92 -0
  50. package/lib/adapters/workspaces.js.map +1 -0
  51. package/lib/client.d.ts +377 -0
  52. package/lib/client.js +2598 -0
  53. package/lib/client.js.map +1 -0
  54. package/lib/core/analyzer.d.ts +35 -0
  55. package/lib/core/analyzer.js +563 -0
  56. package/lib/core/analyzer.js.map +1 -0
  57. package/lib/core/backup.d.ts +29 -0
  58. package/lib/core/backup.js +184 -0
  59. package/lib/core/backup.js.map +1 -0
  60. package/lib/core/exporter.d.ts +37 -0
  61. package/lib/core/exporter.js +222 -0
  62. package/lib/core/exporter.js.map +1 -0
  63. package/lib/core/importer.d.ts +42 -0
  64. package/lib/core/importer.js +25 -0
  65. package/lib/core/importer.js.map +1 -0
  66. package/lib/core/index.d.ts +12 -0
  67. package/lib/core/index.js +11 -0
  68. package/lib/core/index.js.map +1 -0
  69. package/lib/core/rollback.d.ts +9 -0
  70. package/lib/core/rollback.js +136 -0
  71. package/lib/core/rollback.js.map +1 -0
  72. package/lib/core/types.d.ts +331 -0
  73. package/lib/core/types.js +18 -0
  74. package/lib/core/types.js.map +1 -0
  75. package/lib/core/validator.d.ts +18 -0
  76. package/lib/core/validator.js +77 -0
  77. package/lib/core/validator.js.map +1 -0
  78. package/lib/index.d.ts +51 -0
  79. package/lib/index.js +875 -0
  80. package/lib/index.js.map +1 -0
  81. package/lib/migrations/index.d.ts +29 -0
  82. package/lib/migrations/index.js +56 -0
  83. package/lib/migrations/index.js.map +1 -0
  84. package/lib/migrations/v1-to-v2.d.ts +9 -0
  85. package/lib/migrations/v1-to-v2.js +10 -0
  86. package/lib/migrations/v1-to-v2.js.map +1 -0
  87. package/lib/profiles/index.d.ts +4 -0
  88. package/lib/profiles/index.js +5 -0
  89. package/lib/profiles/index.js.map +1 -0
  90. package/lib/profiles/profile-manager.d.ts +102 -0
  91. package/lib/profiles/profile-manager.js +522 -0
  92. package/lib/profiles/profile-manager.js.map +1 -0
  93. package/lib/schema/config.d.ts +28 -0
  94. package/lib/schema/config.js +136 -0
  95. package/lib/schema/config.js.map +1 -0
  96. package/lib/schema/manifest.d.ts +28 -0
  97. package/lib/schema/manifest.js +109 -0
  98. package/lib/schema/manifest.js.map +1 -0
  99. package/lib/schema/types.d.ts +169 -0
  100. package/lib/schema/types.js +8 -0
  101. package/lib/schema/types.js.map +1 -0
  102. package/lib/schema/versions.d.ts +27 -0
  103. package/lib/schema/versions.js +50 -0
  104. package/lib/schema/versions.js.map +1 -0
  105. package/lib/security/encryption.d.ts +41 -0
  106. package/lib/security/encryption.js +152 -0
  107. package/lib/security/encryption.js.map +1 -0
  108. package/lib/security/index.d.ts +16 -0
  109. package/lib/security/index.js +17 -0
  110. package/lib/security/index.js.map +1 -0
  111. package/lib/security/integrity.d.ts +30 -0
  112. package/lib/security/integrity.js +78 -0
  113. package/lib/security/integrity.js.map +1 -0
  114. package/lib/security/redaction.d.ts +26 -0
  115. package/lib/security/redaction.js +95 -0
  116. package/lib/security/redaction.js.map +1 -0
  117. package/lib/security/secret-scanner.d.ts +48 -0
  118. package/lib/security/secret-scanner.js +253 -0
  119. package/lib/security/secret-scanner.js.map +1 -0
  120. package/lib/security/zip-security.d.ts +27 -0
  121. package/lib/security/zip-security.js +154 -0
  122. package/lib/security/zip-security.js.map +1 -0
  123. package/lib/ui/conflict-view.d.ts +28 -0
  124. package/lib/ui/conflict-view.js +49 -0
  125. package/lib/ui/conflict-view.js.map +1 -0
  126. package/lib/ui/errors.d.ts +17 -0
  127. package/lib/ui/errors.js +76 -0
  128. package/lib/ui/errors.js.map +1 -0
  129. package/lib/ui/export-flow.d.ts +62 -0
  130. package/lib/ui/export-flow.js +79 -0
  131. package/lib/ui/export-flow.js.map +1 -0
  132. package/lib/ui/import-wizard.d.ts +67 -0
  133. package/lib/ui/import-wizard.js +169 -0
  134. package/lib/ui/import-wizard.js.map +1 -0
  135. package/lib/ui/path-mapping.d.ts +38 -0
  136. package/lib/ui/path-mapping.js +75 -0
  137. package/lib/ui/path-mapping.js.map +1 -0
  138. package/lib/ui/progress.d.ts +27 -0
  139. package/lib/ui/progress.js +76 -0
  140. package/lib/ui/progress.js.map +1 -0
  141. package/lib/ui/report.d.ts +21 -0
  142. package/lib/ui/report.js +146 -0
  143. package/lib/ui/report.js.map +1 -0
  144. package/lib/ui/test-helpers.d.ts +62 -0
  145. package/lib/ui/test-helpers.js +147 -0
  146. package/lib/ui/test-helpers.js.map +1 -0
  147. package/lib/ui/types.d.ts +129 -0
  148. package/lib/ui/types.js +21 -0
  149. package/lib/ui/types.js.map +1 -0
  150. package/lib/utils/hashing.d.ts +17 -0
  151. package/lib/utils/hashing.js +41 -0
  152. package/lib/utils/hashing.js.map +1 -0
  153. package/lib/utils/json.d.ts +24 -0
  154. package/lib/utils/json.js +76 -0
  155. package/lib/utils/json.js.map +1 -0
  156. package/lib/utils/logger.d.ts +39 -0
  157. package/lib/utils/logger.js +82 -0
  158. package/lib/utils/logger.js.map +1 -0
  159. package/lib/utils/paths.d.ts +31 -0
  160. package/lib/utils/paths.js +132 -0
  161. package/lib/utils/paths.js.map +1 -0
  162. package/lib/utils/zip.d.ts +54 -0
  163. package/lib/utils/zip.js +285 -0
  164. package/lib/utils/zip.js.map +1 -0
  165. package/package.json +109 -0
  166. package/src/adapters/agent-presets.ts +14 -0
  167. package/src/adapters/credentials.test.ts +90 -0
  168. package/src/adapters/credentials.ts +141 -0
  169. package/src/adapters/file-collection.ts +110 -0
  170. package/src/adapters/files.test.ts +113 -0
  171. package/src/adapters/index.ts +69 -0
  172. package/src/adapters/mcp.test.ts +96 -0
  173. package/src/adapters/mcp.ts +181 -0
  174. package/src/adapters/plugin-files.ts +96 -0
  175. package/src/adapters/plugins.test.ts +72 -0
  176. package/src/adapters/plugins.ts +176 -0
  177. package/src/adapters/prompts.test.ts +110 -0
  178. package/src/adapters/prompts.ts +226 -0
  179. package/src/adapters/providers.test.ts +125 -0
  180. package/src/adapters/providers.ts +161 -0
  181. package/src/adapters/roundtrip.test.ts +188 -0
  182. package/src/adapters/sessions.ts +15 -0
  183. package/src/adapters/settings.test.ts +93 -0
  184. package/src/adapters/settings.ts +165 -0
  185. package/src/adapters/skills.ts +14 -0
  186. package/src/adapters/test-helpers.ts +207 -0
  187. package/src/adapters/ui.test.ts +56 -0
  188. package/src/adapters/ui.ts +106 -0
  189. package/src/adapters/workspaces.test.ts +79 -0
  190. package/src/adapters/workspaces.ts +95 -0
  191. package/src/client/CLIENT_DEPENDENCIES.md +101 -0
  192. package/src/client/ConfigManagerSection.tsx +60 -0
  193. package/src/client/api.ts +270 -0
  194. package/src/client/client-types.ts +27 -0
  195. package/src/client/common/ErrorBanner.tsx +68 -0
  196. package/src/client/common/ProgressBar.tsx +49 -0
  197. package/src/client/common/ReportView.tsx +117 -0
  198. package/src/client/common/ui.tsx +165 -0
  199. package/src/client/config-manager.module.css +759 -0
  200. package/src/client/css-modules.d.ts +8 -0
  201. package/src/client/export/ExportView.tsx +222 -0
  202. package/src/client/import/ConflictList.tsx +72 -0
  203. package/src/client/import/ImportWizardView.tsx +406 -0
  204. package/src/client/import/PathMappingForm.tsx +77 -0
  205. package/src/client/index.ts +65 -0
  206. package/src/client/locales.ts +182 -0
  207. package/src/core/analyzer.ts +631 -0
  208. package/src/core/backup.ts +212 -0
  209. package/src/core/exporter.ts +246 -0
  210. package/src/core/importer.ts +66 -0
  211. package/src/core/index.ts +39 -0
  212. package/src/core/rollback.ts +140 -0
  213. package/src/core/smoke.test.ts +717 -0
  214. package/src/core/types.ts +343 -0
  215. package/src/core/validator.ts +84 -0
  216. package/src/index.ts +942 -0
  217. package/src/migrations/index.ts +71 -0
  218. package/src/migrations/v1-to-v2.ts +17 -0
  219. package/src/profiles/index.ts +8 -0
  220. package/src/profiles/profile-manager.test.ts +280 -0
  221. package/src/profiles/profile-manager.ts +606 -0
  222. package/src/schema/config.ts +137 -0
  223. package/src/schema/manifest.ts +124 -0
  224. package/src/schema/types.ts +179 -0
  225. package/src/schema/versions.ts +55 -0
  226. package/src/security/encryption.ts +180 -0
  227. package/src/security/index.ts +16 -0
  228. package/src/security/integrity.ts +102 -0
  229. package/src/security/redaction.ts +101 -0
  230. package/src/security/secret-scanner.ts +275 -0
  231. package/src/security/security.test.ts +796 -0
  232. package/src/security/zip-security.ts +180 -0
  233. package/src/ui/conflict-view.test.ts +62 -0
  234. package/src/ui/conflict-view.ts +65 -0
  235. package/src/ui/errors.test.ts +44 -0
  236. package/src/ui/errors.ts +95 -0
  237. package/src/ui/export-flow.test.ts +75 -0
  238. package/src/ui/export-flow.ts +128 -0
  239. package/src/ui/import-wizard.test.ts +128 -0
  240. package/src/ui/import-wizard.ts +208 -0
  241. package/src/ui/path-mapping.test.ts +67 -0
  242. package/src/ui/path-mapping.ts +103 -0
  243. package/src/ui/progress.test.ts +42 -0
  244. package/src/ui/progress.ts +90 -0
  245. package/src/ui/report.test.ts +93 -0
  246. package/src/ui/report.ts +140 -0
  247. package/src/ui/test-helpers.ts +177 -0
  248. package/src/ui/types.ts +193 -0
  249. package/src/utils/hashing.ts +53 -0
  250. package/src/utils/json.ts +77 -0
  251. package/src/utils/logger.ts +114 -0
  252. package/src/utils/paths.ts +122 -0
  253. package/src/utils/zip.ts +332 -0
@@ -0,0 +1,192 @@
1
+ /**
2
+ * 适配器测试基础设施(仿 src/core/smoke.test.ts 的内存 mock 门面)。
3
+ * 仅供 src/adapters/*.test.ts 使用,不参与生产构建语义。
4
+ */
5
+ import { normalizePath } from "../utils/paths.js";
6
+ import { createLogger } from "../utils/logger.js";
7
+ import { sha256Hex } from "../utils/hashing.js";
8
+ export class MemFs {
9
+ files = new Map();
10
+ homeDir;
11
+ constructor(homeDir) {
12
+ this.homeDir = homeDir;
13
+ }
14
+ key(p) {
15
+ return normalizePath(p.startsWith(this.homeDir) ? p : `${this.homeDir}/${p}`);
16
+ }
17
+ async readFile(relPath) {
18
+ const v = this.files.get(this.key(relPath));
19
+ if (v === undefined)
20
+ throw new Error(`ENOENT: ${relPath}`);
21
+ return v;
22
+ }
23
+ async writeFile(relPath, data) {
24
+ this.files.set(this.key(relPath), data);
25
+ }
26
+ async exists(relPath) {
27
+ return this.files.has(this.key(relPath));
28
+ }
29
+ async copy(from, to) {
30
+ const v = this.files.get(this.key(from));
31
+ if (v === undefined)
32
+ throw new Error(`ENOENT: ${from}`);
33
+ this.files.set(this.key(to), v);
34
+ }
35
+ async remove(relPath) {
36
+ this.files.delete(this.key(relPath));
37
+ }
38
+ async listRecursive(dir) {
39
+ const base = normalizePath(this.homeDir);
40
+ const prefix = normalizePath(dir) === '' ? base : `${base}/${normalizePath(dir)}`;
41
+ const out = [];
42
+ for (const k of this.files.keys()) {
43
+ if (k === prefix || k.startsWith(prefix + '/')) {
44
+ out.push(k.slice(base.length).replace(/^[\\/]+/, ''));
45
+ }
46
+ }
47
+ return out.sort();
48
+ }
49
+ async mkdir() { }
50
+ }
51
+ export class MemSettings {
52
+ ns = new Map();
53
+ async describe(namespace, _opts) {
54
+ const rec = this.ns.get(namespace);
55
+ if (!rec)
56
+ throw new Error(`namespace not found: ${namespace}`);
57
+ return { value: rec.value, base: rec.base, revision: rec.revision, applies: rec.applies, secrets: rec.secrets };
58
+ }
59
+ async replace(namespace, value, expectedRevision) {
60
+ const rec = this.ns.get(namespace);
61
+ if (expectedRevision !== undefined && rec && rec.revision !== expectedRevision) {
62
+ throw new Error(`SETTINGS_CONFLICT: ${namespace} revision ${rec.revision} !== ${expectedRevision}`);
63
+ }
64
+ this.ns.set(namespace, {
65
+ value, revision: (rec?.revision ?? 0) + 1, secrets: rec?.secrets ?? [], base: rec?.base, applies: rec?.applies,
66
+ });
67
+ }
68
+ async update(namespace, patch, expectedRevision) {
69
+ const rec = this.ns.get(namespace);
70
+ if (expectedRevision !== undefined && rec && rec.revision !== expectedRevision) {
71
+ throw new Error(`SETTINGS_CONFLICT: ${namespace} revision ${rec.revision} !== ${expectedRevision}`);
72
+ }
73
+ const merged = { ...rec?.value, ...patch };
74
+ this.ns.set(namespace, { value: merged, revision: (rec?.revision ?? 0) + 1, secrets: rec?.secrets ?? [] });
75
+ }
76
+ }
77
+ export class MemCredentials {
78
+ values = new Map();
79
+ async describe(ref) {
80
+ const v = this.values.get(ref);
81
+ return { configured: v !== undefined, source: v !== undefined ? 'file' : 'env', writable: true };
82
+ }
83
+ async set(ref, value) { this.values.set(ref, value); }
84
+ async unset(ref) { this.values.delete(ref); }
85
+ }
86
+ export class MemPlugins {
87
+ installed = new Map();
88
+ async listInstalled() {
89
+ return [...this.installed.values()];
90
+ }
91
+ async install(pkg) {
92
+ if (this.installed.has(pkg))
93
+ return { needsRestart: false };
94
+ this.installed.set(pkg, { name: pkg, version: '1.0.0', enabled: true });
95
+ return { needsRestart: true };
96
+ }
97
+ }
98
+ export class MemWorkspace {
99
+ records = new Map();
100
+ async listRecords() { return [...this.records.values()]; }
101
+ async writeRecord(r) { this.records.set(r.id, r); }
102
+ async removeRecord(id) { this.records.delete(id); }
103
+ }
104
+ export class MemPatch {
105
+ lines = new Map();
106
+ async readPatchLines(_file) {
107
+ return [...this.lines.values()];
108
+ }
109
+ async applyPatchChanges(_file, changes) {
110
+ for (const c of changes) {
111
+ if (c.action === 'remove')
112
+ this.lines.delete(c.lineId);
113
+ else
114
+ this.lines.set(c.lineId, { lineId: c.lineId, raw: c.raw });
115
+ }
116
+ }
117
+ }
118
+ export class MemSnapshotStore {
119
+ snapshots = new Map();
120
+ blobs = new Map();
121
+ async save(snapshot, blobs = new Map()) {
122
+ this.snapshots.set(snapshot.id, snapshot);
123
+ for (const [k, v] of blobs)
124
+ this.blobs.set(`${snapshot.id}/${k}`, v);
125
+ return snapshot.id;
126
+ }
127
+ async load(id) {
128
+ const s = this.snapshots.get(id);
129
+ if (!s)
130
+ throw new Error(`snapshot not found: ${id}`);
131
+ return s;
132
+ }
133
+ async readBlob(id, blobPath) {
134
+ const v = this.blobs.get(`${id}/${blobPath}`);
135
+ if (!v)
136
+ throw new Error(`blob not found: ${id}/${blobPath}`);
137
+ return v;
138
+ }
139
+ }
140
+ export class MockHostContext {
141
+ platform;
142
+ arch = 'x64';
143
+ homeDir;
144
+ dshVersion = '0.1.0-rc.6';
145
+ log;
146
+ settings = new MemSettings();
147
+ credentials = new MemCredentials();
148
+ plugins = new MemPlugins();
149
+ workspace = new MemWorkspace();
150
+ patchFile = new MemPatch();
151
+ fs;
152
+ constructor(platform, homeDir) {
153
+ this.platform = platform;
154
+ this.homeDir = homeDir;
155
+ this.fs = new MemFs(homeDir);
156
+ this.log = createLogger({ level: 'error', sink: () => { } });
157
+ }
158
+ }
159
+ export function makeContext(platform, homeDir) {
160
+ return new MockHostContext(platform, homeDir);
161
+ }
162
+ /** 构造最小合法 manifest(adapter 单测用;真实 manifest 由 exporter 生成) */
163
+ export function makeManifest(platform = 'win32') {
164
+ return {
165
+ schemaVersion: 1,
166
+ exporter: { name: 'dsh-config-manager-test', version: '0.0.0' },
167
+ source: { dshVersion: '0.1.0-rc.6', platform: platform, arch: 'x64' },
168
+ exportedAt: new Date('2026-08-14T12:00:00.000Z').toISOString(),
169
+ sections: {
170
+ settings: false, ui: false, providers: false, plugins: false, mcp: false, prompts: false,
171
+ skills: false, agentPresets: false, workspaces: false, pluginFiles: false,
172
+ credentialsStatus: false, secrets: false, sessions: false,
173
+ },
174
+ security: { containsSecrets: false, encrypted: false, encryption: null },
175
+ };
176
+ }
177
+ /** 构造 ImportContext(adapter 单测用;sections 键运行时即 SectionId 字符串) */
178
+ export function makeImportContext(target, sections, overrides = {}) {
179
+ return {
180
+ manifest: makeManifest(target.platform),
181
+ targetPlatform: target.platform,
182
+ target,
183
+ sections: sections,
184
+ pathMappings: [],
185
+ resolutions: {},
186
+ secretInputs: {},
187
+ log: target.log,
188
+ ...overrides,
189
+ };
190
+ }
191
+ export { sha256Hex };
192
+ //# sourceMappingURL=test-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-helpers.js","sourceRoot":"","sources":["../../src/adapters/test-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * ui 分区 adapter(设计 §3.3/§4.1/§4.3):
3
+ * 数据源 = settings.yaml 中「UI 类」namespace(pet / dsh-better-sidebar / remote-web-ui / ui-onboarding / skin 等)。
4
+ * localStorage 等 Host 不可迁移的 UI 状态以 uiMigrationNotes 纯说明形式导出(不含任何值)。
5
+ */
6
+ import type { UiSection } from '../schema/types.ts';
7
+ import type { ApplyResult, ConfigAdapter, ExportOptions, ExportSection, HostContext, ImportContext, PlanItem, ValidationResult } from '../core/types.ts';
8
+ import { type NamespaceProvider } from './settings.ts';
9
+ /** UI 类 namespace 前缀名单(设计 §4.1;随新插件扩展,只影响「某一 namespace 归哪一边」,不影响数据完整性) */
10
+ export declare const KNOWN_UI_NAMESPACE_PREFIXES: readonly string[];
11
+ /** namespace 名是否属于 UI 类(大小写不敏感前缀匹配) */
12
+ export declare function isUiNamespace(name: string): boolean;
13
+ /** localStorage 等 Host 无通道的 UI 状态说明(纯说明,不含值;研究报告 §2.2/§4.4) */
14
+ export declare const UI_MIGRATION_NOTES: UiSection['uiMigrationNotes'];
15
+ export declare class UiAdapter implements ConfigAdapter<UiSection> {
16
+ readonly id: "ui";
17
+ readonly displayName = "UI Preferences";
18
+ readonly defaultIncluded = true;
19
+ readonly portability: "portable";
20
+ private readonly namespaces;
21
+ constructor(namespaces?: string[] | NamespaceProvider);
22
+ export(ctx: HostContext, _options: ExportOptions): Promise<ExportSection<UiSection>>;
23
+ analyzeImport(data: UiSection, ctx: ImportContext): Promise<PlanItem[]>;
24
+ applyItem(item: PlanItem, ctx: ImportContext): Promise<ApplyResult>;
25
+ validate(data: UiSection): Promise<ValidationResult>;
26
+ }
@@ -0,0 +1,88 @@
1
+ import { collectNamespaceRecords, planNamespaceItems, applyNamespaceItem, resolveNamespaces } from "./settings.js";
2
+ /** UI 类 namespace 前缀名单(设计 §4.1;随新插件扩展,只影响「某一 namespace 归哪一边」,不影响数据完整性) */
3
+ export const KNOWN_UI_NAMESPACE_PREFIXES = [
4
+ 'pet',
5
+ 'dsh-better-sidebar',
6
+ 'remote-web-ui',
7
+ 'ui-onboarding',
8
+ 'dsh-client-ui',
9
+ 'skin',
10
+ 'theme',
11
+ 'layout',
12
+ 'sidebar',
13
+ 'appearance',
14
+ ];
15
+ /** namespace 名是否属于 UI 类(大小写不敏感前缀匹配) */
16
+ export function isUiNamespace(name) {
17
+ const lower = name.toLowerCase();
18
+ return KNOWN_UI_NAMESPACE_PREFIXES.some((p) => lower.startsWith(p.toLowerCase()));
19
+ }
20
+ /** localStorage 等 Host 无通道的 UI 状态说明(纯说明,不含值;研究报告 §2.2/§4.4) */
21
+ export const UI_MIGRATION_NOTES = [
22
+ {
23
+ plugin: 'dsh-task-board',
24
+ storage: 'localStorage',
25
+ key: 'dsh.taskBoard.v1',
26
+ migratable: false,
27
+ reason: '任务看板数据存于浏览器 localStorage,Host 侧无访问通道,需在目标机器重新配置',
28
+ },
29
+ {
30
+ plugin: 'dsh-aionui-panel',
31
+ storage: 'localStorage',
32
+ key: 'aionui-panel.*',
33
+ migratable: false,
34
+ reason: '面板宽度/折叠状态存于浏览器 localStorage,Host 侧无访问通道,需在目标机器重新配置',
35
+ },
36
+ {
37
+ plugin: 'dsh-client-ui-*',
38
+ storage: 'localStorage',
39
+ key: '*',
40
+ migratable: false,
41
+ reason: '浏览器端 UI 状态无法经 Host API 迁移',
42
+ },
43
+ ];
44
+ export class UiAdapter {
45
+ id = 'ui';
46
+ displayName = 'UI Preferences';
47
+ defaultIncluded = true;
48
+ portability = 'portable';
49
+ namespaces;
50
+ constructor(namespaces = []) {
51
+ this.namespaces = namespaces;
52
+ }
53
+ async export(ctx, _options) {
54
+ const warnings = [];
55
+ const all = await resolveNamespaces(this.namespaces, ctx);
56
+ const uiNames = all.filter((n) => isUiNamespace(n));
57
+ const namespaces = await collectNamespaceRecords(ctx, uiNames, warnings);
58
+ return {
59
+ sectionId: 'ui',
60
+ data: { version: 1, namespaces, uiMigrationNotes: UI_MIGRATION_NOTES },
61
+ counts: { namespaces: Object.keys(namespaces).length, notes: UI_MIGRATION_NOTES.length },
62
+ warnings,
63
+ };
64
+ }
65
+ async analyzeImport(data, ctx) {
66
+ return planNamespaceItems(data.namespaces, 'ui', ctx);
67
+ }
68
+ async applyItem(item, ctx) {
69
+ return applyNamespaceItem(item, 'ui', ctx);
70
+ }
71
+ async validate(data) {
72
+ const issues = [];
73
+ if (data === null || typeof data !== 'object') {
74
+ return { valid: false, issues: [{ path: '$', message: 'ui 数据必须是对象', severity: 'error' }] };
75
+ }
76
+ if (data.version !== 1) {
77
+ issues.push({ path: 'version', message: `version 必须为 1(收到 ${String(data.version)})`, severity: 'error' });
78
+ }
79
+ if (data.namespaces === null || typeof data.namespaces !== 'object') {
80
+ issues.push({ path: 'namespaces', message: '缺少 namespaces 对象', severity: 'error' });
81
+ }
82
+ if (data.uiMigrationNotes !== undefined && !Array.isArray(data.uiMigrationNotes)) {
83
+ issues.push({ path: 'uiMigrationNotes', message: 'uiMigrationNotes 必须是数组', severity: 'error' });
84
+ }
85
+ return { valid: issues.filter((i) => i.severity === 'error').length === 0, issues };
86
+ }
87
+ }
88
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/adapters/ui.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { WorkspacesSection } from '../schema/types.ts';
2
+ import type { ApplyResult, ConfigAdapter, ExportOptions, ExportSection, HostContext, ImportContext, PlanItem, ValidationResult } from '../core/types.ts';
3
+ export declare class WorkspacesAdapter implements ConfigAdapter<WorkspacesSection> {
4
+ readonly id: "workspaces";
5
+ readonly displayName = "Workspaces";
6
+ readonly defaultIncluded = true;
7
+ readonly portability: "platformSpecific";
8
+ export(ctx: HostContext, _options: ExportOptions): Promise<ExportSection<WorkspacesSection>>;
9
+ analyzeImport(data: WorkspacesSection, ctx: ImportContext): Promise<PlanItem[]>;
10
+ applyItem(item: PlanItem, ctx: ImportContext): Promise<ApplyResult>;
11
+ validate(data: WorkspacesSection): Promise<ValidationResult>;
12
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * workspaces 分区 adapter(设计 §3.3/§11):
3
+ * 数据源 = ~/.dsh/storages/workspace.json 的 tables.workspaces(经 ctx.workspace 门面)。
4
+ * workspace.path 为绝对路径 → 跨设备必须 PathMapping(analyzeImport 生成 PathMapping 项,
5
+ * 映射由引擎 PathMapper 先行应用到 sections,applyItem 拿到的已是映射后数据)。
6
+ */
7
+ import { isDeepStrictEqual } from 'node:util';
8
+ export class WorkspacesAdapter {
9
+ id = 'workspaces';
10
+ displayName = 'Workspaces';
11
+ defaultIncluded = true;
12
+ portability = 'platformSpecific';
13
+ async export(ctx, _options) {
14
+ const records = await ctx.workspace.listRecords();
15
+ return {
16
+ sectionId: 'workspaces',
17
+ data: { version: 1, workspaces: records },
18
+ counts: { workspaces: records.length },
19
+ warnings: [],
20
+ };
21
+ }
22
+ async analyzeImport(data, ctx) {
23
+ const items = [];
24
+ for (const rec of data.workspaces) {
25
+ const id = `workspace:${rec.id}`;
26
+ const existing = (await ctx.target.workspace.listRecords()).find((r) => r.id === rec.id);
27
+ if (!existing) {
28
+ items.push({
29
+ id, kind: 'Create', adapter: 'workspaces',
30
+ description: `创建工作区 ${rec.title ?? rec.id}(${rec.path})`, severity: 'info',
31
+ target: { adapter: 'workspaces', ref: rec.id },
32
+ });
33
+ }
34
+ else if (isDeepStrictEqual(existing, rec)) {
35
+ items.push({ id, kind: 'Skip', adapter: 'workspaces', description: `工作区 ${rec.id} 已一致`, severity: 'info' });
36
+ }
37
+ else {
38
+ items.push({
39
+ id, kind: 'Conflict', adapter: 'workspaces',
40
+ description: `工作区 ${rec.id} 与目标不同`,
41
+ detail: `current=${JSON.stringify(existing)} imported=${JSON.stringify(rec)}`.slice(0, 200),
42
+ severity: 'warning', target: { adapter: 'workspaces', ref: rec.id },
43
+ });
44
+ }
45
+ // 绝对路径 → 路径映射提示(oldPrefix 先用整条路径占位,newPrefix 由 UI 确认)
46
+ if (rec.path.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(rec.path)) {
47
+ items.push({
48
+ id: `${id}:path`, kind: 'PathMapping', adapter: 'workspaces',
49
+ description: `路径需映射: ${rec.path}`, severity: 'warning',
50
+ pathMapping: { oldPrefix: rec.path, newPrefix: '', appliesTo: ['workspaces'] },
51
+ target: { adapter: 'workspaces', ref: rec.id },
52
+ });
53
+ }
54
+ }
55
+ return items;
56
+ }
57
+ async applyItem(item, ctx) {
58
+ // PathMapping 项:数据已由 PathMapper 应用到 sections,无需额外写入
59
+ if (item.kind === 'PathMapping')
60
+ return { ok: true };
61
+ const ref = item.target?.ref;
62
+ if (!ref)
63
+ return { ok: false, message: '缺少 target.ref' };
64
+ const data = ctx.sections.get('workspaces');
65
+ const rec = data?.workspaces.find((r) => r.id === ref);
66
+ if (!rec)
67
+ return { ok: false, message: `导入数据缺少工作区 ${ref}` };
68
+ await ctx.target.workspace.writeRecord(rec);
69
+ return { ok: true };
70
+ }
71
+ async validate(data) {
72
+ const issues = [];
73
+ if (data === null || typeof data !== 'object') {
74
+ return { valid: false, issues: [{ path: '$', message: 'workspaces 数据必须是对象', severity: 'error' }] };
75
+ }
76
+ if (data.version !== 1) {
77
+ issues.push({ path: 'version', message: `version 必须为 1(收到 ${String(data.version)})`, severity: 'error' });
78
+ }
79
+ if (!Array.isArray(data.workspaces)) {
80
+ issues.push({ path: 'workspaces', message: 'workspaces 必须是数组', severity: 'error' });
81
+ }
82
+ else {
83
+ for (const w of data.workspaces) {
84
+ if (w === null || typeof w !== 'object' || typeof w.id !== 'string' || typeof w.path !== 'string') {
85
+ issues.push({ path: 'workspaces[]', message: 'workspace 记录必须含字符串 id 与 path', severity: 'error' });
86
+ }
87
+ }
88
+ }
89
+ return { valid: issues.filter((i) => i.severity === 'error').length === 0, issues };
90
+ }
91
+ }
92
+ //# sourceMappingURL=workspaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspaces.js","sourceRoot":"","sources":["../../src/adapters/workspaces.ts"],"names":[],"mappings":"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"}