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,143 @@
1
+ /**
2
+ * providers 分区 adapter(设计 §3.3/§13.1):
3
+ * 数据源 = settings.yaml 的 llm-deepseek / llm-pi-ai section(providers 与 models 天然同 section,不拆文件)。
4
+ *
5
+ * 导入走 settings 写通道(replace llm-* namespace + 乐观锁):
6
+ * 每项携带 raw(该 namespace 的完整 redacted 值)用于整体写回,apiKey 值经 credentials 状态占位(不导出值)。
7
+ */
8
+ import { isDeepStrictEqual } from 'node:util';
9
+ import { resolveNamespaces } from "./settings.js";
10
+ export const DEFAULT_PROVIDER_NAMESPACES = ['llm-deepseek', 'llm-pi-ai'];
11
+ /** 无 raw 时的兜底重建:只取 ProviderEntry 已知字段 */
12
+ function stripEntry(entry) {
13
+ const out = {};
14
+ for (const key of ['apiKeyEnv', 'displayName', 'baseURL', 'models', 'modelOverrides', 'reasoning', 'transport', 'retryPolicy']) {
15
+ if (entry[key] !== undefined)
16
+ out[key] = entry[key];
17
+ }
18
+ return out;
19
+ }
20
+ export class ProvidersAdapter {
21
+ id = 'providers';
22
+ displayName = 'Providers & Models';
23
+ defaultIncluded = true;
24
+ portability = 'portable';
25
+ namespaces;
26
+ constructor(namespaces = DEFAULT_PROVIDER_NAMESPACES) {
27
+ this.namespaces = namespaces;
28
+ }
29
+ async export(ctx, _options) {
30
+ const providers = {};
31
+ const warnings = [];
32
+ for (const ns of await resolveNamespaces(this.namespaces, ctx)) {
33
+ let info;
34
+ try {
35
+ info = await ctx.settings.describe(ns, { redactSecrets: true });
36
+ }
37
+ catch (err) {
38
+ warnings.push(`provider namespace ${ns} 读取失败(可能未配置): ${err instanceof Error ? err.message : String(err)}`);
39
+ continue;
40
+ }
41
+ const value = (info.value ?? {});
42
+ // llm-pi-ai 形态:value.providers = { route: {...} };llm-deepseek 形态:value 即单 provider 配置
43
+ const routes = value.providers !== null && typeof value.providers === 'object'
44
+ ? Object.entries(value.providers)
45
+ : [[ns, value]];
46
+ for (const [route, pv] of routes) {
47
+ // 每个 route 独立深拷贝 secrets / pv / raw:同一 namespace 的多 route 若共享引用,
48
+ // m4 强化版 createSecretScanner 的 visited 循环检测会误判「检测到循环引用」(见 providers.test.ts)。
49
+ providers[route] = {
50
+ route,
51
+ namespace: ns,
52
+ revision: info.revision,
53
+ secrets: structuredClone(info.secrets),
54
+ ...structuredClone(pv),
55
+ raw: structuredClone(value),
56
+ };
57
+ }
58
+ }
59
+ return {
60
+ sectionId: 'providers',
61
+ data: { version: 1, providers },
62
+ counts: { providers: Object.keys(providers).length },
63
+ warnings,
64
+ };
65
+ }
66
+ async analyzeImport(data, ctx) {
67
+ const items = [];
68
+ for (const [route, entry] of Object.entries(data.providers)) {
69
+ const id = `provider:${route}`;
70
+ let current = null;
71
+ try {
72
+ current = await ctx.target.settings.describe(entry.namespace, { redactSecrets: true });
73
+ }
74
+ catch {
75
+ current = null;
76
+ }
77
+ if (current === null) {
78
+ items.push({
79
+ id, kind: 'Create', adapter: 'providers',
80
+ description: `创建 Provider ${route}(namespace ${entry.namespace})`, severity: 'info',
81
+ target: { adapter: 'providers', ref: entry.namespace },
82
+ });
83
+ }
84
+ else if (isDeepStrictEqual(current.value, entry.raw ?? stripEntry(entry))) {
85
+ items.push({ id, kind: 'Skip', adapter: 'providers', description: `Provider ${route} 已一致`, severity: 'info' });
86
+ }
87
+ else {
88
+ items.push({
89
+ id, kind: 'Conflict', adapter: 'providers',
90
+ description: `Provider ${route} 与目标不同`,
91
+ detail: `namespace=${entry.namespace} current=${JSON.stringify(current.value)} imported=${JSON.stringify(entry.raw ?? stripEntry(entry))}`.slice(0, 200),
92
+ severity: 'warning', target: { adapter: 'providers', ref: entry.namespace },
93
+ });
94
+ }
95
+ }
96
+ return items;
97
+ }
98
+ async applyItem(item, ctx) {
99
+ const route = item.id.replace(/^provider:/, '');
100
+ const data = ctx.sections.get('providers');
101
+ const entry = data?.providers[route];
102
+ if (!entry)
103
+ return { ok: false, message: `导入数据缺少 provider ${route}` };
104
+ const value = entry.raw ?? stripEntry(entry);
105
+ let expected;
106
+ try {
107
+ expected = (await ctx.target.settings.describe(entry.namespace, { redactSecrets: true })).revision;
108
+ }
109
+ catch {
110
+ expected = undefined; // 目标 namespace 不存在(Create)
111
+ }
112
+ await ctx.target.settings.replace(entry.namespace, value, expected);
113
+ return { ok: true };
114
+ }
115
+ async validate(data) {
116
+ const issues = [];
117
+ if (data === null || typeof data !== 'object') {
118
+ return { valid: false, issues: [{ path: '$', message: 'providers 数据必须是对象', severity: 'error' }] };
119
+ }
120
+ if (data.version !== 1) {
121
+ issues.push({ path: 'version', message: `version 必须为 1(收到 ${String(data.version)})`, severity: 'error' });
122
+ }
123
+ if (data.providers === null || typeof data.providers !== 'object') {
124
+ issues.push({ path: 'providers', message: '缺少 providers 对象', severity: 'error' });
125
+ }
126
+ else {
127
+ for (const [route, entry] of Object.entries(data.providers)) {
128
+ if (entry === null || typeof entry !== 'object') {
129
+ issues.push({ path: `providers.${route}`, message: 'provider 记录必须是对象', severity: 'error' });
130
+ continue;
131
+ }
132
+ if (typeof entry.namespace !== 'string' || entry.namespace === '') {
133
+ issues.push({ path: `providers.${route}.namespace`, message: '缺少来源 namespace', severity: 'error' });
134
+ }
135
+ if (typeof entry.revision !== 'number') {
136
+ issues.push({ path: `providers.${route}.revision`, message: 'revision 必须是数字', severity: 'error' });
137
+ }
138
+ }
139
+ }
140
+ return { valid: issues.filter((i) => i.severity === 'error').length === 0, issues };
141
+ }
142
+ }
143
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/adapters/providers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * sessions 分区 adapter(默认关,设计 §3.3/§15):
3
+ * 数据源 = ~/.dsh/sessions/<projectKey>/<sessionId>/…(zstd jsonl,含敏感信息)。
4
+ * defaultIncluded=false:Quick Export 不包含,用户显式勾选才导出(v1 文件级复制)。
5
+ * 研究报告 §4.9:DSH 无会话批量导出 API,逐会话文件复制是唯一通道。
6
+ */
7
+ import { FileCollectionAdapter } from './file-collection.ts';
8
+ export declare class SessionsAdapter extends FileCollectionAdapter {
9
+ readonly id: "sessions";
10
+ readonly displayName = "Sessions";
11
+ readonly defaultIncluded = false;
12
+ readonly portability: "deviceSpecific";
13
+ readonly baseDir = "sessions";
14
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * sessions 分区 adapter(默认关,设计 §3.3/§15):
3
+ * 数据源 = ~/.dsh/sessions/<projectKey>/<sessionId>/…(zstd jsonl,含敏感信息)。
4
+ * defaultIncluded=false:Quick Export 不包含,用户显式勾选才导出(v1 文件级复制)。
5
+ * 研究报告 §4.9:DSH 无会话批量导出 API,逐会话文件复制是唯一通道。
6
+ */
7
+ import { FileCollectionAdapter } from "./file-collection.js";
8
+ export class SessionsAdapter extends FileCollectionAdapter {
9
+ id = 'sessions';
10
+ displayName = 'Sessions';
11
+ defaultIncluded = false;
12
+ portability = 'deviceSpecific';
13
+ baseDir = 'sessions';
14
+ }
15
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/adapters/sessions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,OAAO,eAAgB,SAAQ,qBAAqB;IAC/C,EAAE,GAAG,UAAmB,CAAC;IACzB,WAAW,GAAG,UAAU,CAAC;IACzB,eAAe,GAAG,KAAK,CAAC;IACxB,WAAW,GAAG,gBAAyB,CAAC;IACxC,OAAO,GAAG,UAAU,CAAC;CAC/B"}
@@ -0,0 +1,23 @@
1
+ import type { NamespaceRecord, SettingsSection } from '../schema/types.ts';
2
+ import type { ApplyResult, ConfigAdapter, ExportOptions, ExportSection, HostContext, ImportContext, PlanItem, ValidationResult } from '../core/types.ts';
3
+ /** namespace 清单提供者:宿主从 settings.yaml 顶层 key / 插件注册表获得 */
4
+ export type NamespaceProvider = (ctx: HostContext) => Promise<string[]> | string[];
5
+ export declare function resolveNamespaces(namespaces: string[] | NamespaceProvider, ctx: HostContext): Promise<string[]>;
6
+ /** 批量读取 namespace 的 redacted 记录(settings/ui 共用;单项失败跳过并告警) */
7
+ export declare function collectNamespaceRecords(ctx: HostContext, names: string[], warnings: string[]): Promise<Record<string, NamespaceRecord>>;
8
+ /** 对比导入记录与目标当前值:不存在 → Create;一致 → Skip;不同 → Conflict(纯计算,零写入) */
9
+ export declare function planNamespaceItems(data: Record<string, NamespaceRecord>, adapter: 'settings' | 'ui', ctx: ImportContext): Promise<PlanItem[]>;
10
+ /** 写入单个 namespace(settings/ui 共用):读时锁 + expectedRevision 乐观锁,防覆盖并发修改 */
11
+ export declare function applyNamespaceItem(item: PlanItem, sectionId: 'settings' | 'ui', ctx: ImportContext): Promise<ApplyResult>;
12
+ export declare class SettingsAdapter implements ConfigAdapter<SettingsSection> {
13
+ readonly id: "settings";
14
+ readonly displayName = "Settings";
15
+ readonly defaultIncluded = true;
16
+ readonly portability: "portable";
17
+ private readonly namespaces;
18
+ constructor(namespaces?: string[] | NamespaceProvider);
19
+ export(ctx: HostContext, _options: ExportOptions): Promise<ExportSection<SettingsSection>>;
20
+ analyzeImport(data: SettingsSection, ctx: ImportContext): Promise<PlanItem[]>;
21
+ applyItem(item: PlanItem, ctx: ImportContext): Promise<ApplyResult>;
22
+ validate(data: SettingsSection): Promise<ValidationResult>;
23
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * settings 分区 adapter(设计 §3.3/§4.1/§4.2):
3
+ * 数据源 = ~/.dsh/settings.yaml 中「非 UI 类」namespace(经 ctx.settings.describe({redactSecrets:true}))。
4
+ *
5
+ * 说明:DSH settings 服务没有「枚举全部 namespace」的 API(研究报告 §3.2),
6
+ * 因此 namespace 清单由宿主注入(真实实现可从 settings.yaml 顶层 key 解析)。
7
+ * 默认只导出名单内且不属于 UI 类(isUiNamespace)的 namespace,与 ui adapter 互斥并集 = 全部设置。
8
+ */
9
+ import { isDeepStrictEqual } from 'node:util';
10
+ import { isUiNamespace } from "./ui.js";
11
+ export async function resolveNamespaces(namespaces, ctx) {
12
+ return typeof namespaces === 'function' ? namespaces(ctx) : namespaces;
13
+ }
14
+ /** 批量读取 namespace 的 redacted 记录(settings/ui 共用;单项失败跳过并告警) */
15
+ export async function collectNamespaceRecords(ctx, names, warnings) {
16
+ const namespaces = {};
17
+ for (const name of names) {
18
+ try {
19
+ const info = await ctx.settings.describe(name, { redactSecrets: true });
20
+ namespaces[name] = {
21
+ value: info.value,
22
+ base: info.base,
23
+ revision: info.revision,
24
+ applies: info.applies,
25
+ secrets: info.secrets,
26
+ };
27
+ }
28
+ catch (err) {
29
+ warnings.push(`设置 namespace ${name} 读取失败: ${err instanceof Error ? err.message : String(err)}`);
30
+ }
31
+ }
32
+ return namespaces;
33
+ }
34
+ /** 对比导入记录与目标当前值:不存在 → Create;一致 → Skip;不同 → Conflict(纯计算,零写入) */
35
+ export async function planNamespaceItems(data, adapter, ctx) {
36
+ const items = [];
37
+ for (const [name, rec] of Object.entries(data)) {
38
+ let current = null;
39
+ try {
40
+ current = await ctx.target.settings.describe(name, { redactSecrets: true });
41
+ }
42
+ catch {
43
+ current = null;
44
+ }
45
+ const id = `${adapter}:${name}`;
46
+ if (current === null) {
47
+ items.push({
48
+ id, kind: 'Create', adapter, description: `创建设置 ${name}`, severity: 'info',
49
+ target: { adapter, ref: name },
50
+ });
51
+ }
52
+ else if (isDeepStrictEqual(current.value, rec.value)) {
53
+ items.push({ id, kind: 'Skip', adapter, description: `设置 ${name} 已一致`, severity: 'info' });
54
+ }
55
+ else {
56
+ items.push({
57
+ id, kind: 'Conflict', adapter, description: `设置 ${name} 与目标不同`,
58
+ detail: `current=${JSON.stringify(current.value)} imported=${JSON.stringify(rec.value)}`.slice(0, 200),
59
+ severity: 'warning', target: { adapter, ref: name },
60
+ });
61
+ }
62
+ }
63
+ return items;
64
+ }
65
+ /** 写入单个 namespace(settings/ui 共用):读时锁 + expectedRevision 乐观锁,防覆盖并发修改 */
66
+ export async function applyNamespaceItem(item, sectionId, ctx) {
67
+ const ref = item.target?.ref;
68
+ if (!ref)
69
+ return { ok: false, message: '缺少 target.ref' };
70
+ const data = ctx.sections.get(sectionId);
71
+ const rec = data?.namespaces?.[ref];
72
+ if (!rec)
73
+ return { ok: false, message: `导入数据缺少 namespace ${ref}` };
74
+ // 写入前读当前 revision 作为 expectedRevision(读时锁):目标不存在(Create)则不带锁提交
75
+ let expected;
76
+ try {
77
+ expected = (await ctx.target.settings.describe(ref, { redactSecrets: true })).revision;
78
+ }
79
+ catch {
80
+ expected = undefined;
81
+ }
82
+ await ctx.target.settings.replace(ref, rec.value, expected);
83
+ return { ok: true };
84
+ }
85
+ export class SettingsAdapter {
86
+ id = 'settings';
87
+ displayName = 'Settings';
88
+ defaultIncluded = true;
89
+ portability = 'portable';
90
+ namespaces;
91
+ constructor(namespaces = []) {
92
+ this.namespaces = namespaces;
93
+ }
94
+ async export(ctx, _options) {
95
+ const warnings = [];
96
+ const all = await resolveNamespaces(this.namespaces, ctx);
97
+ const nonUi = all.filter((n) => !isUiNamespace(n));
98
+ if (nonUi.length === 0)
99
+ warnings.push('未配置 settings namespace 清单,settings 分区为空');
100
+ const namespaces = await collectNamespaceRecords(ctx, nonUi, warnings);
101
+ return {
102
+ sectionId: 'settings',
103
+ data: { version: 1, namespaces },
104
+ counts: { namespaces: Object.keys(namespaces).length },
105
+ warnings,
106
+ };
107
+ }
108
+ async analyzeImport(data, ctx) {
109
+ return planNamespaceItems(data.namespaces, 'settings', ctx);
110
+ }
111
+ async applyItem(item, ctx) {
112
+ return applyNamespaceItem(item, 'settings', ctx);
113
+ }
114
+ async validate(data) {
115
+ const issues = [];
116
+ if (data === null || typeof data !== 'object') {
117
+ return { valid: false, issues: [{ path: '$', message: 'settings 数据必须是对象', severity: 'error' }] };
118
+ }
119
+ if (data.version !== 1) {
120
+ issues.push({ path: 'version', message: `version 必须为 1(收到 ${String(data.version)})`, severity: 'error' });
121
+ }
122
+ if (data.namespaces === null || typeof data.namespaces !== 'object') {
123
+ issues.push({ path: 'namespaces', message: '缺少 namespaces 对象', severity: 'error' });
124
+ }
125
+ else {
126
+ for (const [name, rec] of Object.entries(data.namespaces)) {
127
+ if (rec === null || typeof rec !== 'object') {
128
+ issues.push({ path: `namespaces.${name}`, message: 'namespace 记录必须是对象', severity: 'error' });
129
+ continue;
130
+ }
131
+ if (typeof rec.revision !== 'number') {
132
+ issues.push({ path: `namespaces.${name}.revision`, message: 'revision 必须是数字', severity: 'error' });
133
+ }
134
+ if (!('value' in rec)) {
135
+ issues.push({ path: `namespaces.${name}.value`, message: '缺少 value', severity: 'error' });
136
+ }
137
+ }
138
+ }
139
+ return { valid: issues.filter((i) => i.severity === 'error').length === 0, issues };
140
+ }
141
+ }
142
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/adapters/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * skills 分区 adapter(设计 §3.3):
3
+ * 数据源 = ~/.dsh/skills/(flat .md + 目录 bundle;dsh-skill-filesystem 发现)。
4
+ * 仅迁移用户主目录技能;~/.agents/skills、项目级技能默认不迁(研究报告 §2.2)。
5
+ */
6
+ import { FileCollectionAdapter } from './file-collection.ts';
7
+ export declare class SkillsAdapter extends FileCollectionAdapter {
8
+ readonly id: "skills";
9
+ readonly displayName = "Skills";
10
+ readonly defaultIncluded = true;
11
+ readonly portability: "portable";
12
+ readonly baseDir = "skills";
13
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * skills 分区 adapter(设计 §3.3):
3
+ * 数据源 = ~/.dsh/skills/(flat .md + 目录 bundle;dsh-skill-filesystem 发现)。
4
+ * 仅迁移用户主目录技能;~/.agents/skills、项目级技能默认不迁(研究报告 §2.2)。
5
+ */
6
+ import { FileCollectionAdapter } from "./file-collection.js";
7
+ export class SkillsAdapter extends FileCollectionAdapter {
8
+ id = 'skills';
9
+ displayName = 'Skills';
10
+ defaultIncluded = true;
11
+ portability = 'portable';
12
+ baseDir = 'skills';
13
+ }
14
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/adapters/skills.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,OAAO,aAAc,SAAQ,qBAAqB;IAC7C,EAAE,GAAG,QAAiB,CAAC;IACvB,WAAW,GAAG,QAAQ,CAAC;IACvB,eAAe,GAAG,IAAI,CAAC;IACvB,WAAW,GAAG,UAAmB,CAAC;IAClC,OAAO,GAAG,QAAQ,CAAC;CAC7B"}
@@ -0,0 +1,99 @@
1
+ import { type Logger } from '../utils/logger.ts';
2
+ import { sha256Hex } from '../utils/hashing.ts';
3
+ import type { CredentialsFacade, FileSystemFacade, HostContext, ImportContext, NamespaceInfo, PatchFileFacade, PluginInfo, PluginsFacade, SettingsFacade, Snapshot, SnapshotStore, WorkspaceFacade } from '../core/types.ts';
4
+ import type { Manifest, WorkspaceRecord } from '../schema/types.ts';
5
+ export declare class MemFs implements FileSystemFacade {
6
+ files: Map<string, Uint8Array<ArrayBufferLike>>;
7
+ private readonly homeDir;
8
+ constructor(homeDir: string);
9
+ private key;
10
+ readFile(relPath: string): Promise<Uint8Array>;
11
+ writeFile(relPath: string, data: Uint8Array): Promise<void>;
12
+ exists(relPath: string): Promise<boolean>;
13
+ copy(from: string, to: string): Promise<void>;
14
+ remove(relPath: string): Promise<void>;
15
+ listRecursive(dir: string): Promise<string[]>;
16
+ mkdir(): Promise<void>;
17
+ }
18
+ export declare class MemSettings implements SettingsFacade {
19
+ ns: Map<string, {
20
+ value: unknown;
21
+ base?: unknown;
22
+ revision: number;
23
+ applies?: string[];
24
+ secrets: {
25
+ path: string[];
26
+ set: boolean;
27
+ }[];
28
+ }>;
29
+ describe(namespace: string, _opts?: {
30
+ redactSecrets?: boolean;
31
+ }): Promise<NamespaceInfo>;
32
+ replace(namespace: string, value: unknown, expectedRevision?: number): Promise<void>;
33
+ update?(namespace: string, patch: unknown, expectedRevision?: number): Promise<void>;
34
+ }
35
+ export declare class MemCredentials implements CredentialsFacade {
36
+ values: Map<string, string>;
37
+ describe(ref: string): Promise<{
38
+ configured: boolean;
39
+ source?: string;
40
+ writable?: boolean;
41
+ }>;
42
+ set(ref: string, value: string): Promise<void>;
43
+ unset(ref: string): Promise<void>;
44
+ }
45
+ export declare class MemPlugins implements PluginsFacade {
46
+ installed: Map<string, PluginInfo>;
47
+ listInstalled(): Promise<PluginInfo[]>;
48
+ install(pkg: string): Promise<{
49
+ needsRestart: boolean;
50
+ }>;
51
+ }
52
+ export declare class MemWorkspace implements WorkspaceFacade {
53
+ records: Map<string, WorkspaceRecord>;
54
+ listRecords(): Promise<WorkspaceRecord[]>;
55
+ writeRecord(r: WorkspaceRecord): Promise<void>;
56
+ removeRecord(id: string): Promise<void>;
57
+ }
58
+ export declare class MemPatch implements PatchFileFacade {
59
+ lines: Map<string, {
60
+ lineId: string;
61
+ raw: unknown;
62
+ }>;
63
+ readPatchLines(_file: string): Promise<{
64
+ lineId: string;
65
+ raw: unknown;
66
+ }[]>;
67
+ applyPatchChanges(_file: string, changes: {
68
+ lineId: string;
69
+ raw: unknown;
70
+ action: 'insert' | 'update' | 'remove';
71
+ }[]): Promise<void>;
72
+ }
73
+ export declare class MemSnapshotStore implements SnapshotStore {
74
+ snapshots: Map<string, Snapshot>;
75
+ blobs: Map<string, Uint8Array<ArrayBufferLike>>;
76
+ save(snapshot: Snapshot, blobs?: Map<string, Uint8Array>): Promise<string>;
77
+ load(id: string): Promise<Snapshot>;
78
+ readBlob(id: string, blobPath: string): Promise<Uint8Array>;
79
+ }
80
+ export declare class MockHostContext implements HostContext {
81
+ platform: string;
82
+ arch: string;
83
+ homeDir: string;
84
+ dshVersion: string;
85
+ log: Logger;
86
+ settings: MemSettings;
87
+ credentials: MemCredentials;
88
+ plugins: MemPlugins;
89
+ workspace: MemWorkspace;
90
+ patchFile: MemPatch;
91
+ fs: MemFs;
92
+ constructor(platform: string, homeDir: string);
93
+ }
94
+ export declare function makeContext(platform: string, homeDir: string): MockHostContext;
95
+ /** 构造最小合法 manifest(adapter 单测用;真实 manifest 由 exporter 生成) */
96
+ export declare function makeManifest(platform?: string): Manifest;
97
+ /** 构造 ImportContext(adapter 单测用;sections 键运行时即 SectionId 字符串) */
98
+ export declare function makeImportContext(target: HostContext, sections: ReadonlyMap<string, unknown>, overrides?: Partial<ImportContext>): ImportContext;
99
+ export { sha256Hex };