@logictan/dsh-config-manager 0.1.60

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 (429) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/cordis.patch.yml +21 -0
  4. package/lib/adapters/agent-instructions.d.ts +13 -0
  5. package/lib/adapters/agent-instructions.js +46 -0
  6. package/lib/adapters/agent-presets.d.ts +13 -0
  7. package/lib/adapters/agent-presets.js +14 -0
  8. package/lib/adapters/credentials.d.ts +37 -0
  9. package/lib/adapters/credentials.js +122 -0
  10. package/lib/adapters/file-collection.d.ts +15 -0
  11. package/lib/adapters/file-collection.js +127 -0
  12. package/lib/adapters/index.d.ts +57 -0
  13. package/lib/adapters/index.js +55 -0
  14. package/lib/adapters/link-report.d.ts +16 -0
  15. package/lib/adapters/link-report.js +47 -0
  16. package/lib/adapters/mcp.d.ts +28 -0
  17. package/lib/adapters/mcp.js +178 -0
  18. package/lib/adapters/plugin-files.d.ts +18 -0
  19. package/lib/adapters/plugin-files.js +142 -0
  20. package/lib/adapters/plugins.d.ts +41 -0
  21. package/lib/adapters/plugins.js +603 -0
  22. package/lib/adapters/pnpm-workspace.d.ts +26 -0
  23. package/lib/adapters/pnpm-workspace.js +147 -0
  24. package/lib/adapters/prompts.d.ts +30 -0
  25. package/lib/adapters/prompts.js +231 -0
  26. package/lib/adapters/providers.d.ts +34 -0
  27. package/lib/adapters/providers.js +155 -0
  28. package/lib/adapters/self.d.ts +17 -0
  29. package/lib/adapters/self.js +71 -0
  30. package/lib/adapters/sessions.d.ts +14 -0
  31. package/lib/adapters/sessions.js +15 -0
  32. package/lib/adapters/settings.d.ts +28 -0
  33. package/lib/adapters/settings.js +165 -0
  34. package/lib/adapters/skills.d.ts +13 -0
  35. package/lib/adapters/skills.js +14 -0
  36. package/lib/adapters/test-helpers.d.ts +125 -0
  37. package/lib/adapters/test-helpers.js +236 -0
  38. package/lib/adapters/ui.d.ts +27 -0
  39. package/lib/adapters/ui.js +89 -0
  40. package/lib/adapters/workspaces.d.ts +13 -0
  41. package/lib/adapters/workspaces.js +106 -0
  42. package/lib/client.d.ts +1026 -0
  43. package/lib/client.js +10047 -0
  44. package/lib/core/analyzer.d.ts +99 -0
  45. package/lib/core/analyzer.js +934 -0
  46. package/lib/core/backup.d.ts +138 -0
  47. package/lib/core/backup.js +513 -0
  48. package/lib/core/boot-rescue.d.ts +146 -0
  49. package/lib/core/boot-rescue.js +618 -0
  50. package/lib/core/cache-cleaner.d.ts +31 -0
  51. package/lib/core/cache-cleaner.js +95 -0
  52. package/lib/core/config-lifecycle.d.ts +180 -0
  53. package/lib/core/config-lifecycle.js +481 -0
  54. package/lib/core/config-snapshot.d.ts +135 -0
  55. package/lib/core/config-snapshot.js +424 -0
  56. package/lib/core/config-state.d.ts +70 -0
  57. package/lib/core/config-state.js +177 -0
  58. package/lib/core/consult-source.d.ts +58 -0
  59. package/lib/core/consult-source.js +260 -0
  60. package/lib/core/crash-report.d.ts +84 -0
  61. package/lib/core/crash-report.js +317 -0
  62. package/lib/core/exporter.d.ts +68 -0
  63. package/lib/core/exporter.js +375 -0
  64. package/lib/core/ghost-sweep.d.ts +19 -0
  65. package/lib/core/ghost-sweep.js +52 -0
  66. package/lib/core/importer.d.ts +60 -0
  67. package/lib/core/importer.js +29 -0
  68. package/lib/core/index.d.ts +14 -0
  69. package/lib/core/index.js +14 -0
  70. package/lib/core/journal.d.ts +197 -0
  71. package/lib/core/journal.js +418 -0
  72. package/lib/core/local-plugin-host.d.ts +35 -0
  73. package/lib/core/local-plugin-host.js +120 -0
  74. package/lib/core/local-plugin-pack.d.ts +135 -0
  75. package/lib/core/local-plugin-pack.js +278 -0
  76. package/lib/core/messages.d.ts +310 -0
  77. package/lib/core/messages.js +621 -0
  78. package/lib/core/migration-consult.d.ts +117 -0
  79. package/lib/core/migration-consult.js +363 -0
  80. package/lib/core/migration-history.d.ts +153 -0
  81. package/lib/core/migration-history.js +411 -0
  82. package/lib/core/model-tools.d.ts +50 -0
  83. package/lib/core/model-tools.js +148 -0
  84. package/lib/core/msg-types.d.ts +8 -0
  85. package/lib/core/msg-types.js +6 -0
  86. package/lib/core/phase3-child-crash.d.ts +1 -0
  87. package/lib/core/phase3-child-crash.js +87 -0
  88. package/lib/core/phase3-host.d.ts +138 -0
  89. package/lib/core/phase3-host.js +359 -0
  90. package/lib/core/phase3-prod-child.d.ts +1 -0
  91. package/lib/core/phase3-prod-child.js +35 -0
  92. package/lib/core/phase4-crash-child.d.ts +1 -0
  93. package/lib/core/phase4-crash-child.js +103 -0
  94. package/lib/core/plugin-cli.d.ts +150 -0
  95. package/lib/core/plugin-cli.js +497 -0
  96. package/lib/core/reconcile.d.ts +120 -0
  97. package/lib/core/reconcile.js +389 -0
  98. package/lib/core/recovery-orchestrator.d.ts +94 -0
  99. package/lib/core/recovery-orchestrator.js +327 -0
  100. package/lib/core/restore.d.ts +162 -0
  101. package/lib/core/restore.js +703 -0
  102. package/lib/core/rollback.d.ts +12 -0
  103. package/lib/core/rollback.js +145 -0
  104. package/lib/core/run-registry.d.ts +85 -0
  105. package/lib/core/run-registry.js +157 -0
  106. package/lib/core/startup-barrier.d.ts +53 -0
  107. package/lib/core/startup-barrier.js +77 -0
  108. package/lib/core/types.d.ts +515 -0
  109. package/lib/core/types.js +27 -0
  110. package/lib/core/undo.d.ts +73 -0
  111. package/lib/core/undo.js +87 -0
  112. package/lib/core/validator.d.ts +18 -0
  113. package/lib/core/validator.js +77 -0
  114. package/lib/core/verify-recovery.d.ts +21 -0
  115. package/lib/core/verify-recovery.js +256 -0
  116. package/lib/core/watcher.d.ts +101 -0
  117. package/lib/core/watcher.js +219 -0
  118. package/lib/index.d.ts +238 -0
  119. package/lib/index.js +2764 -0
  120. package/lib/migrations/index.d.ts +29 -0
  121. package/lib/migrations/index.js +56 -0
  122. package/lib/migrations/v1-to-v2.d.ts +9 -0
  123. package/lib/migrations/v1-to-v2.js +10 -0
  124. package/lib/profiles/index.d.ts +4 -0
  125. package/lib/profiles/index.js +5 -0
  126. package/lib/profiles/profile-manager.d.ts +106 -0
  127. package/lib/profiles/profile-manager.js +543 -0
  128. package/lib/schema/config.d.ts +28 -0
  129. package/lib/schema/config.js +165 -0
  130. package/lib/schema/index.d.ts +24 -0
  131. package/lib/schema/index.js +26 -0
  132. package/lib/schema/manifest.d.ts +28 -0
  133. package/lib/schema/manifest.js +109 -0
  134. package/lib/schema/tombstones.d.ts +46 -0
  135. package/lib/schema/tombstones.js +64 -0
  136. package/lib/schema/types.d.ts +232 -0
  137. package/lib/schema/types.js +8 -0
  138. package/lib/schema/versions.d.ts +27 -0
  139. package/lib/schema/versions.js +50 -0
  140. package/lib/security/encryption.d.ts +85 -0
  141. package/lib/security/encryption.js +279 -0
  142. package/lib/security/index.d.ts +16 -0
  143. package/lib/security/index.js +17 -0
  144. package/lib/security/integrity.d.ts +30 -0
  145. package/lib/security/integrity.js +78 -0
  146. package/lib/security/redaction.d.ts +26 -0
  147. package/lib/security/redaction.js +95 -0
  148. package/lib/security/secret-scanner.d.ts +86 -0
  149. package/lib/security/secret-scanner.js +404 -0
  150. package/lib/security/vault.d.ts +59 -0
  151. package/lib/security/vault.js +151 -0
  152. package/lib/security/zip-security.d.ts +27 -0
  153. package/lib/security/zip-security.js +154 -0
  154. package/lib/sync/autosync-config.d.ts +39 -0
  155. package/lib/sync/autosync-config.js +151 -0
  156. package/lib/sync/autosync-scheduler.d.ts +139 -0
  157. package/lib/sync/autosync-scheduler.js +564 -0
  158. package/lib/sync/fs.d.ts +18 -0
  159. package/lib/sync/fs.js +49 -0
  160. package/lib/sync/git/git-transport.d.ts +100 -0
  161. package/lib/sync/git/git-transport.js +437 -0
  162. package/lib/sync/github-auth.d.ts +131 -0
  163. package/lib/sync/github-auth.js +264 -0
  164. package/lib/sync/layout.d.ts +43 -0
  165. package/lib/sync/layout.js +203 -0
  166. package/lib/sync/snapshot-json.d.ts +9 -0
  167. package/lib/sync/snapshot-json.js +107 -0
  168. package/lib/sync/sync-config.d.ts +81 -0
  169. package/lib/sync/sync-config.js +281 -0
  170. package/lib/sync/sync-engine.d.ts +269 -0
  171. package/lib/sync/sync-engine.js +591 -0
  172. package/lib/sync/sync-history.d.ts +42 -0
  173. package/lib/sync/sync-history.js +78 -0
  174. package/lib/sync/sync-selection.d.ts +29 -0
  175. package/lib/sync/sync-selection.js +127 -0
  176. package/lib/sync/sync-session.d.ts +40 -0
  177. package/lib/sync/sync-session.js +54 -0
  178. package/lib/sync/sync-state.d.ts +37 -0
  179. package/lib/sync/sync-state.js +108 -0
  180. package/lib/sync/transport.d.ts +75 -0
  181. package/lib/sync/transport.js +55 -0
  182. package/lib/sync/ui-prefs.d.ts +34 -0
  183. package/lib/sync/ui-prefs.js +109 -0
  184. package/lib/sync/webdav/webdav-transport.d.ts +77 -0
  185. package/lib/sync/webdav/webdav-transport.js +451 -0
  186. package/lib/ui/errors.d.ts +19 -0
  187. package/lib/ui/errors.js +81 -0
  188. package/lib/ui/export-flow.d.ts +82 -0
  189. package/lib/ui/export-flow.js +98 -0
  190. package/lib/ui/i18n.d.ts +289 -0
  191. package/lib/ui/i18n.js +581 -0
  192. package/lib/ui/migration-consult-view.d.ts +91 -0
  193. package/lib/ui/migration-consult-view.js +115 -0
  194. package/lib/ui/progress.d.ts +38 -0
  195. package/lib/ui/progress.js +87 -0
  196. package/lib/ui/report.d.ts +23 -0
  197. package/lib/ui/report.js +153 -0
  198. package/lib/ui/test-helpers.d.ts +69 -0
  199. package/lib/ui/test-helpers.js +154 -0
  200. package/lib/ui/types.d.ts +257 -0
  201. package/lib/ui/types.js +21 -0
  202. package/lib/utils/atomic-write.d.ts +88 -0
  203. package/lib/utils/atomic-write.js +399 -0
  204. package/lib/utils/env-lock.d.ts +393 -0
  205. package/lib/utils/env-lock.js +930 -0
  206. package/lib/utils/hashing.d.ts +17 -0
  207. package/lib/utils/hashing.js +41 -0
  208. package/lib/utils/json.d.ts +24 -0
  209. package/lib/utils/json.js +76 -0
  210. package/lib/utils/logger.d.ts +39 -0
  211. package/lib/utils/logger.js +82 -0
  212. package/lib/utils/paths.d.ts +42 -0
  213. package/lib/utils/paths.js +189 -0
  214. package/lib/utils/proxy.d.ts +69 -0
  215. package/lib/utils/proxy.js +455 -0
  216. package/lib/utils/recursive-walk.d.ts +24 -0
  217. package/lib/utils/recursive-walk.js +134 -0
  218. package/lib/utils/zip.d.ts +54 -0
  219. package/lib/utils/zip.js +285 -0
  220. package/package.json +188 -0
  221. package/src/adapters/agent-instructions.ts +48 -0
  222. package/src/adapters/agent-presets.ts +14 -0
  223. package/src/adapters/credentials.test.ts +90 -0
  224. package/src/adapters/credentials.ts +143 -0
  225. package/src/adapters/file-collection.ts +137 -0
  226. package/src/adapters/files.test.ts +353 -0
  227. package/src/adapters/index.ts +94 -0
  228. package/src/adapters/link-report.test.ts +65 -0
  229. package/src/adapters/link-report.ts +61 -0
  230. package/src/adapters/mcp.test.ts +96 -0
  231. package/src/adapters/mcp.ts +185 -0
  232. package/src/adapters/plugin-files.ts +146 -0
  233. package/src/adapters/plugins.test.ts +326 -0
  234. package/src/adapters/plugins.ts +615 -0
  235. package/src/adapters/pnpm-workspace.test.ts +87 -0
  236. package/src/adapters/pnpm-workspace.ts +150 -0
  237. package/src/adapters/prompts.test.ts +110 -0
  238. package/src/adapters/prompts.ts +230 -0
  239. package/src/adapters/providers.test.ts +126 -0
  240. package/src/adapters/providers.ts +173 -0
  241. package/src/adapters/roundtrip.test.ts +190 -0
  242. package/src/adapters/self.test.ts +92 -0
  243. package/src/adapters/self.ts +75 -0
  244. package/src/adapters/sessions.ts +15 -0
  245. package/src/adapters/settings.test.ts +100 -0
  246. package/src/adapters/settings.ts +187 -0
  247. package/src/adapters/skills.ts +14 -0
  248. package/src/adapters/test-helpers.ts +248 -0
  249. package/src/adapters/ui.test.ts +57 -0
  250. package/src/adapters/ui.ts +108 -0
  251. package/src/adapters/workspaces.test.ts +106 -0
  252. package/src/adapters/workspaces.ts +109 -0
  253. package/src/client/ConfigManagerSection.tsx +90 -0
  254. package/src/client/api.ts +66 -0
  255. package/src/client/client-types.ts +18 -0
  256. package/src/client/common/ErrorBanner.tsx +73 -0
  257. package/src/client/common/Icon.tsx +129 -0
  258. package/src/client/common/Modal.tsx +173 -0
  259. package/src/client/common/ToastViewport.tsx +73 -0
  260. package/src/client/common/toast-store.test.ts +192 -0
  261. package/src/client/common/toast-store.ts +181 -0
  262. package/src/client/common/toast-types.ts +7 -0
  263. package/src/client/common/ui.tsx +342 -0
  264. package/src/client/config-manager.module.css +2971 -0
  265. package/src/client/css-modules.d.ts +8 -0
  266. package/src/client/index.ts +65 -0
  267. package/src/client/locales.ts +56 -0
  268. package/src/client/lucide-icons.d.ts +38 -0
  269. package/src/client/run-store.test.ts +223 -0
  270. package/src/client/run-store.ts +372 -0
  271. package/src/client/sync/SyncConfirmView.tsx +379 -0
  272. package/src/client/sync/SyncHistoryView.test.ts +40 -0
  273. package/src/client/sync/SyncHistoryView.tsx +220 -0
  274. package/src/client/sync/SyncSettingsView.tsx +1535 -0
  275. package/src/client/sync/history-model.test.ts +194 -0
  276. package/src/client/sync/history-model.ts +195 -0
  277. package/src/client/sync/sync-api.test.ts +585 -0
  278. package/src/client/sync/sync-api.ts +543 -0
  279. package/src/client/sync/sync-locales.ts +416 -0
  280. package/src/client/sync/sync-push-preview.test.ts +52 -0
  281. package/src/client/sync/sync-view-v2.test.ts +213 -0
  282. package/src/client/sync/sync-view.test.ts +487 -0
  283. package/src/client/sync/sync-view.ts +759 -0
  284. package/src/core/analyzer.ts +1068 -0
  285. package/src/core/backup.ts +605 -0
  286. package/src/core/boot-rescue.test.ts +847 -0
  287. package/src/core/boot-rescue.ts +737 -0
  288. package/src/core/cache-cleaner.test.ts +169 -0
  289. package/src/core/cache-cleaner.ts +121 -0
  290. package/src/core/config-lifecycle.test.ts +727 -0
  291. package/src/core/config-lifecycle.ts +573 -0
  292. package/src/core/config-snapshot.test.ts +369 -0
  293. package/src/core/config-snapshot.ts +522 -0
  294. package/src/core/config-state.test.ts +381 -0
  295. package/src/core/config-state.ts +207 -0
  296. package/src/core/consult-source.test.ts +199 -0
  297. package/src/core/consult-source.ts +293 -0
  298. package/src/core/crash-report.test.ts +380 -0
  299. package/src/core/crash-report.ts +369 -0
  300. package/src/core/exporter.ts +417 -0
  301. package/src/core/ghost-sweep.test.ts +94 -0
  302. package/src/core/ghost-sweep.ts +67 -0
  303. package/src/core/importer.ts +83 -0
  304. package/src/core/index.ts +56 -0
  305. package/src/core/journal.test.ts +257 -0
  306. package/src/core/journal.ts +518 -0
  307. package/src/core/local-plugin-host.ts +152 -0
  308. package/src/core/local-plugin-pack.test.ts +359 -0
  309. package/src/core/local-plugin-pack.ts +363 -0
  310. package/src/core/messages.test.ts +54 -0
  311. package/src/core/messages.ts +664 -0
  312. package/src/core/migration-consult.test.ts +315 -0
  313. package/src/core/migration-consult.ts +494 -0
  314. package/src/core/migration-history.test.ts +319 -0
  315. package/src/core/migration-history.ts +484 -0
  316. package/src/core/model-tools.test.ts +190 -0
  317. package/src/core/model-tools.ts +208 -0
  318. package/src/core/msg-types.ts +10 -0
  319. package/src/core/phase3-child-crash.ts +95 -0
  320. package/src/core/phase3-host.ts +411 -0
  321. package/src/core/phase3-p1.test.ts +212 -0
  322. package/src/core/phase3-p2b-fingerprint.test.ts +189 -0
  323. package/src/core/phase3-prod-child.ts +36 -0
  324. package/src/core/phase3-production-integration.test.ts +286 -0
  325. package/src/core/phase4-crash-child.ts +101 -0
  326. package/src/core/phase4-crash-injection.test.ts +166 -0
  327. package/src/core/plugin-cli.fs.test.ts +184 -0
  328. package/src/core/plugin-cli.test.ts +137 -0
  329. package/src/core/plugin-cli.ts +563 -0
  330. package/src/core/reconcile.test.ts +392 -0
  331. package/src/core/reconcile.ts +498 -0
  332. package/src/core/recovery-orchestrator.test.ts +145 -0
  333. package/src/core/recovery-orchestrator.ts +366 -0
  334. package/src/core/restore-manage.test.ts +94 -0
  335. package/src/core/restore.ts +849 -0
  336. package/src/core/rollback.ts +151 -0
  337. package/src/core/run-progress.test.ts +237 -0
  338. package/src/core/run-registry.test.ts +232 -0
  339. package/src/core/run-registry.ts +209 -0
  340. package/src/core/smoke.test.ts +842 -0
  341. package/src/core/startup-barrier.ts +99 -0
  342. package/src/core/types.ts +542 -0
  343. package/src/core/undo.ts +116 -0
  344. package/src/core/validator.ts +84 -0
  345. package/src/core/verify-recovery.ts +265 -0
  346. package/src/core/watcher.test.ts +326 -0
  347. package/src/core/watcher.ts +263 -0
  348. package/src/index.facade.test.ts +265 -0
  349. package/src/index.sync.test.ts +217 -0
  350. package/src/index.ts +2975 -0
  351. package/src/migrations/index.ts +71 -0
  352. package/src/migrations/v1-to-v2.ts +17 -0
  353. package/src/profiles/index.ts +8 -0
  354. package/src/profiles/profile-manager.test.ts +282 -0
  355. package/src/profiles/profile-manager.ts +630 -0
  356. package/src/schema/config.ts +165 -0
  357. package/src/schema/index.ts +71 -0
  358. package/src/schema/manifest-schema.test.ts +519 -0
  359. package/src/schema/manifest.ts +124 -0
  360. package/src/schema/tombstones.test.ts +131 -0
  361. package/src/schema/tombstones.ts +89 -0
  362. package/src/schema/types.ts +245 -0
  363. package/src/schema/versions.ts +55 -0
  364. package/src/security/encryption.ts +335 -0
  365. package/src/security/index.ts +16 -0
  366. package/src/security/integrity.ts +102 -0
  367. package/src/security/redaction.ts +101 -0
  368. package/src/security/secret-scanner.ts +445 -0
  369. package/src/security/security.test.ts +1215 -0
  370. package/src/security/vault.test.ts +164 -0
  371. package/src/security/vault.ts +198 -0
  372. package/src/security/zip-security.ts +180 -0
  373. package/src/sync/autosync-config.test.ts +147 -0
  374. package/src/sync/autosync-config.ts +179 -0
  375. package/src/sync/autosync-scheduler.test.ts +490 -0
  376. package/src/sync/autosync-scheduler.ts +646 -0
  377. package/src/sync/fs.ts +48 -0
  378. package/src/sync/git/git-transport.test.ts +673 -0
  379. package/src/sync/git/git-transport.ts +491 -0
  380. package/src/sync/github-auth.test.ts +280 -0
  381. package/src/sync/github-auth.ts +356 -0
  382. package/src/sync/layout.test.ts +270 -0
  383. package/src/sync/layout.ts +222 -0
  384. package/src/sync/snapshot-json.test.ts +119 -0
  385. package/src/sync/snapshot-json.ts +128 -0
  386. package/src/sync/sync-config.test.ts +310 -0
  387. package/src/sync/sync-config.ts +299 -0
  388. package/src/sync/sync-engine.test.ts +1074 -0
  389. package/src/sync/sync-engine.ts +754 -0
  390. package/src/sync/sync-history.test.ts +116 -0
  391. package/src/sync/sync-history.ts +120 -0
  392. package/src/sync/sync-selection.test.ts +186 -0
  393. package/src/sync/sync-selection.ts +143 -0
  394. package/src/sync/sync-session.test.ts +143 -0
  395. package/src/sync/sync-session.ts +77 -0
  396. package/src/sync/sync-state.test.ts +164 -0
  397. package/src/sync/sync-state.ts +131 -0
  398. package/src/sync/transport.test.ts +111 -0
  399. package/src/sync/transport.ts +118 -0
  400. package/src/sync/ui-prefs.test.ts +152 -0
  401. package/src/sync/ui-prefs.ts +135 -0
  402. package/src/sync/webdav/webdav-transport.test.ts +871 -0
  403. package/src/sync/webdav/webdav-transport.ts +535 -0
  404. package/src/ui/errors.test.ts +47 -0
  405. package/src/ui/errors.ts +100 -0
  406. package/src/ui/export-flow.test.ts +87 -0
  407. package/src/ui/export-flow.ts +156 -0
  408. package/src/ui/i18n.ts +590 -0
  409. package/src/ui/migration-consult-view.test.ts +151 -0
  410. package/src/ui/migration-consult-view.ts +178 -0
  411. package/src/ui/progress.test.ts +47 -0
  412. package/src/ui/progress.ts +102 -0
  413. package/src/ui/report.test.ts +101 -0
  414. package/src/ui/report.ts +146 -0
  415. package/src/ui/test-helpers.ts +184 -0
  416. package/src/ui/types.ts +325 -0
  417. package/src/utils/atomic-write.test.ts +312 -0
  418. package/src/utils/atomic-write.ts +422 -0
  419. package/src/utils/env-lock.test.ts +999 -0
  420. package/src/utils/env-lock.ts +1086 -0
  421. package/src/utils/hashing.ts +53 -0
  422. package/src/utils/json.ts +77 -0
  423. package/src/utils/logger.ts +114 -0
  424. package/src/utils/paths.ts +176 -0
  425. package/src/utils/proxy.test.ts +465 -0
  426. package/src/utils/proxy.ts +493 -0
  427. package/src/utils/recursive-walk.test.ts +148 -0
  428. package/src/utils/recursive-walk.ts +145 -0
  429. package/src/utils/zip.ts +332 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * 迁移前咨询的纯渲染模型(Phase 7,m6-ui)。
3
+ *
4
+ * 把 core 的 ConsultReport 转成 React 可直接绑定的视图数据:
5
+ * - 健康评分徽章(verdict → Badge kind)
6
+ * - 维度明细(每维度:label / score / verdict / issues)
7
+ * - 建议(proceed / review / block + 触发项)
8
+ * - 将应用摘要(willApply)
9
+ *
10
+ * 安全:所有展示文本渲染前由 UI 层 redact() 兜底;本模型只做结构转换,不引入敏感值。
11
+ * 文案走 UiT(zh 源 / en 镜像,见 src/ui/i18n.ts)。
12
+ */
13
+ import type { UiT } from './i18n.ts';
14
+ import type { ConsultReport, ConsultDimensionId, HealthVerdict, Recommendation } from '../core/migration-consult.ts';
15
+ /** Badge kind(与 DESIGN.md 四态语义一一对应) */
16
+ export type ConsultBadgeKind = 'ok' | 'info' | 'warn' | 'error';
17
+ /** 维度视图数据 */
18
+ export interface ConsultDimensionView {
19
+ id: ConsultDimensionId;
20
+ label: string;
21
+ score: number;
22
+ verdict: HealthVerdict;
23
+ badgeKind: ConsultBadgeKind;
24
+ issues: {
25
+ severity: 'info' | 'warning' | 'error';
26
+ message: string;
27
+ }[];
28
+ }
29
+ /** 咨询卡视图数据 */
30
+ export interface ConsultView {
31
+ healthScore: number;
32
+ verdict: HealthVerdict;
33
+ verdictBadgeKind: ConsultBadgeKind;
34
+ recommendation: Recommendation;
35
+ recommendationBadgeKind: ConsultBadgeKind;
36
+ recommendationLabel: string;
37
+ reasons: string[];
38
+ dimensions: ConsultDimensionView[];
39
+ willApply: {
40
+ sections: string[];
41
+ itemCount: number;
42
+ conflicts: number;
43
+ risks: number;
44
+ overwritten: number;
45
+ dryRun: boolean;
46
+ };
47
+ }
48
+ /** 建议依据分组条目(去重后的 message + 在原始数组中的出现次数) */
49
+ export interface ConsultReasonGroup {
50
+ message: string;
51
+ /** 该 message 在原始 reasons 数组中的出现次数(≥1;仅用于 UI 展示「×N」) */
52
+ count: number;
53
+ }
54
+ /**
55
+ * 「建议依据」去重(纯函数)。
56
+ *
57
+ * 背景:core 的 `recommendationReasons` 是各维度 error/warning issue message 的
58
+ * 直接拼接,同一句话可能被 push 多次(如 migratability 维度按 `m.warnings` 逐条 push
59
+ * 「存在需注意的迁移项」),同一句也可能既出现在维度 issue 又出现在 reasons 中。
60
+ *
61
+ * 去重规则(严格按此实现,勿擅自放宽):
62
+ * 1. **按原文去重**:只有完全相同的字符串才算重复——不做 trim 后合并、不做大小写
63
+ * 折叠、不做前缀/子串归并。因此 `'A'`、`' A'`、`'A '` 是三个不同条目。
64
+ * 2. **保持首次出现顺序**:稳定去重,输出顺序 = 各条目在输入中首次出现的顺序。
65
+ * 3. **丢弃空串与纯空白字符串**(`trim() === ''`),它们不参与展示。
66
+ *
67
+ * 不修改入参,返回新数组。
68
+ */
69
+ export declare function dedupeConsultReasons(reasons: string[]): string[];
70
+ /**
71
+ * 「建议依据」分组(纯函数):去重后给出每个条目的重复次数,供 UI 渲染「×N」。
72
+ *
73
+ * 规则:
74
+ * 1. 先经 `dedupeConsultReasons` 去重(原文去重、丢弃空串/纯空白、保持首现顺序);
75
+ * 2. `count` = 该 message 在**原始数组**(未去重)中的出现次数,按原文精确匹配统计,
76
+ * 因此 count ≥ 1;count 仅用于展示「×N」,不代表任何业务优先级或权重;
77
+ * 3. 输出顺序 = 去重后的顺序(即各条目首次出现的顺序)。
78
+ *
79
+ * 不修改入参,返回新数组。
80
+ */
81
+ export declare function consultReasonGroups(reasons: string[]): ConsultReasonGroup[];
82
+ /** verdict → Badge kind(语义映射) */
83
+ export declare function consultVerdictBadgeKind(v: HealthVerdict): ConsultBadgeKind;
84
+ /** recommendation → Badge kind */
85
+ export declare function consultRecommendationBadgeKind(r: Recommendation): ConsultBadgeKind;
86
+ /** 维度 label(i18n key 后缀) */
87
+ export declare function consultDimensionLabel(id: ConsultDimensionId, t: UiT): string;
88
+ /** 把 ConsultReport 转成视图数据(纯函数) */
89
+ export declare function consultView(report: ConsultReport, t: UiT): ConsultView;
90
+ /** recommendation 的可读标签 */
91
+ export declare function consultRecommendationLabel(r: Recommendation, t: UiT): string;
@@ -0,0 +1,115 @@
1
+ /**
2
+ * 「建议依据」去重(纯函数)。
3
+ *
4
+ * 背景:core 的 `recommendationReasons` 是各维度 error/warning issue message 的
5
+ * 直接拼接,同一句话可能被 push 多次(如 migratability 维度按 `m.warnings` 逐条 push
6
+ * 「存在需注意的迁移项」),同一句也可能既出现在维度 issue 又出现在 reasons 中。
7
+ *
8
+ * 去重规则(严格按此实现,勿擅自放宽):
9
+ * 1. **按原文去重**:只有完全相同的字符串才算重复——不做 trim 后合并、不做大小写
10
+ * 折叠、不做前缀/子串归并。因此 `'A'`、`' A'`、`'A '` 是三个不同条目。
11
+ * 2. **保持首次出现顺序**:稳定去重,输出顺序 = 各条目在输入中首次出现的顺序。
12
+ * 3. **丢弃空串与纯空白字符串**(`trim() === ''`),它们不参与展示。
13
+ *
14
+ * 不修改入参,返回新数组。
15
+ */
16
+ export function dedupeConsultReasons(reasons) {
17
+ const seen = new Set();
18
+ const out = [];
19
+ for (const reason of reasons) {
20
+ if (reason.trim() === '')
21
+ continue; // 空串/纯空白:直接丢弃
22
+ if (seen.has(reason))
23
+ continue; // 原文去重:仅完全相同才视为重复
24
+ seen.add(reason);
25
+ out.push(reason);
26
+ }
27
+ return out;
28
+ }
29
+ /**
30
+ * 「建议依据」分组(纯函数):去重后给出每个条目的重复次数,供 UI 渲染「×N」。
31
+ *
32
+ * 规则:
33
+ * 1. 先经 `dedupeConsultReasons` 去重(原文去重、丢弃空串/纯空白、保持首现顺序);
34
+ * 2. `count` = 该 message 在**原始数组**(未去重)中的出现次数,按原文精确匹配统计,
35
+ * 因此 count ≥ 1;count 仅用于展示「×N」,不代表任何业务优先级或权重;
36
+ * 3. 输出顺序 = 去重后的顺序(即各条目首次出现的顺序)。
37
+ *
38
+ * 不修改入参,返回新数组。
39
+ */
40
+ export function consultReasonGroups(reasons) {
41
+ const counts = new Map();
42
+ for (const reason of reasons) {
43
+ counts.set(reason, (counts.get(reason) ?? 0) + 1);
44
+ }
45
+ return dedupeConsultReasons(reasons).map((message) => ({
46
+ message,
47
+ // 去重结果必来自入参,故此处理论上不会取到兜底值
48
+ count: counts.get(message) ?? 0,
49
+ }));
50
+ }
51
+ /** verdict → Badge kind(语义映射) */
52
+ export function consultVerdictBadgeKind(v) {
53
+ switch (v) {
54
+ case 'healthy': return 'ok';
55
+ case 'needs-attention': return 'warn';
56
+ case 'critical': return 'error';
57
+ }
58
+ }
59
+ /** recommendation → Badge kind */
60
+ export function consultRecommendationBadgeKind(r) {
61
+ switch (r) {
62
+ case 'proceed': return 'ok';
63
+ case 'review': return 'warn';
64
+ case 'block': return 'error';
65
+ }
66
+ }
67
+ /** 维度 label(i18n key 后缀) */
68
+ export function consultDimensionLabel(id, t) {
69
+ switch (id) {
70
+ case 'compatibility': return t('consult.dim.compatibility');
71
+ case 'integrity': return t('consult.dim.integrity');
72
+ case 'sections': return t('consult.dim.sections');
73
+ case 'consistency': return t('consult.dim.consistency');
74
+ case 'sensitive': return t('consult.dim.sensitive');
75
+ case 'migratability': return t('consult.dim.migratability');
76
+ }
77
+ }
78
+ /** 把 ConsultReport 转成视图数据(纯函数) */
79
+ export function consultView(report, t) {
80
+ const dimensions = report.dimensions.map((d) => ({
81
+ id: d.id,
82
+ label: consultDimensionLabel(d.id, t),
83
+ score: d.score,
84
+ verdict: d.verdict,
85
+ badgeKind: consultVerdictBadgeKind(d.verdict),
86
+ issues: d.issues.map((i) => ({ severity: i.severity, message: i.message })),
87
+ }));
88
+ return {
89
+ healthScore: report.healthScore,
90
+ verdict: report.verdict,
91
+ verdictBadgeKind: consultVerdictBadgeKind(report.verdict),
92
+ recommendation: report.recommendation,
93
+ recommendationBadgeKind: consultRecommendationBadgeKind(report.recommendation),
94
+ recommendationLabel: consultRecommendationLabel(report.recommendation, t),
95
+ reasons: report.recommendationReasons,
96
+ dimensions,
97
+ willApply: {
98
+ sections: report.willApply.sections,
99
+ itemCount: report.willApply.itemCount,
100
+ conflicts: report.willApply.conflicts,
101
+ risks: report.willApply.risks,
102
+ overwritten: report.willApply.overwritten,
103
+ dryRun: report.willApply.dryRun,
104
+ },
105
+ };
106
+ }
107
+ /** recommendation 的可读标签 */
108
+ export function consultRecommendationLabel(r, t) {
109
+ switch (r) {
110
+ case 'proceed': return t('consult.recommendation.proceed');
111
+ case 'review': return t('consult.recommendation.review');
112
+ case 'block': return t('consult.recommendation.block');
113
+ }
114
+ }
115
+ //# sourceMappingURL=migration-consult-view.js.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * 进度阶段文案与进度追踪(规范 §29,m6-ui)。
3
+ *
4
+ * 纯文本层:每个阶段 id 有默认文案;未知阶段回退显示 id 本身。
5
+ * ProgressTracker 供导出/导入控制器在调用 core 前后发出阶段事件(UI 不冻结)。
6
+ */
7
+ import type { ProgressListener } from './types.ts';
8
+ import { type UiT } from './i18n.ts';
9
+ /** 导出阶段文案(规范 §29 Export 示例) */
10
+ export declare const EXPORT_STAGES: readonly string[];
11
+ /** 导入阶段文案(规范 §29 Import 示例 + 快照/回滚阶段) */
12
+ export declare const IMPORT_STAGES: readonly string[];
13
+ /**
14
+ * 真实执行阶段(不在 IMPORT_STAGES 序列里,因此 step/total 缺省 → 进度条渲染
15
+ * 为不定态动画而非伪造百分比)。execute 是一个单次 HTTP 请求,Host 端串行
16
+ * 跑完全部计划项(其中插件安装是 npm 串行,耗时最长);请求期间没有中间
17
+ * 进度事件可回传,旧实现把 restoring-settings / restoring-plugins /
18
+ * restoring-mcp / validating-config 在请求前全部预发,导致进度条瞬间跳到
19
+ * 78% 后长时间无变化——像卡死。现在统一在请求期间显示 'executing' 不定态,
20
+ * 让用户明确知道「仍在执行,请等待」。
21
+ */
22
+ export declare const EXECUTING_STAGE: 'executing';
23
+ /** 阶段 id → 用户可读文案(未知阶段回退 id) */
24
+ export declare function stageText(stage: string, t?: UiT): string;
25
+ /**
26
+ * 进度追踪器:按给定阶段序列在回调时附带 step/total 序号。
27
+ * 控制器调用 core 前后 emit(),UI 侧渲染进度条/阶段文字。
28
+ */
29
+ export declare class ProgressTracker {
30
+ private readonly listener;
31
+ private readonly stages;
32
+ private readonly emitted;
33
+ constructor(stages: readonly string[], listener?: ProgressListener);
34
+ /** 发出某阶段事件(可携带 detail);未在序列中的阶段 step/total 缺省 */
35
+ emit(stage: string, detail?: string): void;
36
+ /** 已发出阶段的快照(测试与日志用) */
37
+ get events(): readonly string[];
38
+ }
@@ -0,0 +1,87 @@
1
+ import { zhUiT } from './i18n.js';
2
+ /** 导出阶段文案(规范 §29 Export 示例) */
3
+ export const EXPORT_STAGES = [
4
+ 'analyzing', // Analyzing configuration...
5
+ 'exporting-settings', // Exporting settings...
6
+ 'scanning-secrets', // Scanning secrets...
7
+ 'exporting-plugins', // Exporting plugins...
8
+ 'creating-archive', // Creating archive...
9
+ 'calculating-checksums', // Calculating checksums...
10
+ 'done',
11
+ ];
12
+ /** 导入阶段文案(规范 §29 Import 示例 + 快照/回滚阶段) */
13
+ export const IMPORT_STAGES = [
14
+ 'validating', // Validating backup...
15
+ 'checking-compatibility', // Checking compatibility...
16
+ 'creating-snapshot', // Creating safety snapshot...
17
+ 'restoring-settings', // Restoring settings...
18
+ 'restoring-plugins', // Restoring plugins...
19
+ 'restoring-mcp', // Restoring MCP...
20
+ 'validating-config', // Validating configuration...
21
+ 'rolling-back', // Rolling back...(仅失败回滚时)
22
+ 'done',
23
+ ];
24
+ /**
25
+ * 真实执行阶段(不在 IMPORT_STAGES 序列里,因此 step/total 缺省 → 进度条渲染
26
+ * 为不定态动画而非伪造百分比)。execute 是一个单次 HTTP 请求,Host 端串行
27
+ * 跑完全部计划项(其中插件安装是 npm 串行,耗时最长);请求期间没有中间
28
+ * 进度事件可回传,旧实现把 restoring-settings / restoring-plugins /
29
+ * restoring-mcp / validating-config 在请求前全部预发,导致进度条瞬间跳到
30
+ * 78% 后长时间无变化——像卡死。现在统一在请求期间显示 'executing' 不定态,
31
+ * 让用户明确知道「仍在执行,请等待」。
32
+ */
33
+ export const EXECUTING_STAGE = 'executing';
34
+ const STAGE_KEYS = {
35
+ analyzing: 'progress.analyzing',
36
+ 'exporting-settings': 'progress.exportingSettings',
37
+ 'scanning-secrets': 'progress.scanningSecrets',
38
+ 'exporting-plugins': 'progress.exportingPlugins',
39
+ 'creating-archive': 'progress.creatingArchive',
40
+ 'calculating-checksums': 'progress.calculatingChecksums',
41
+ exporting: 'progress.exporting',
42
+ validating: 'progress.validating',
43
+ 'checking-compatibility': 'progress.checkingCompatibility',
44
+ 'creating-snapshot': 'progress.creatingSnapshot',
45
+ 'restoring-settings': 'progress.restoringSettings',
46
+ 'restoring-plugins': 'progress.restoringPlugins',
47
+ 'restoring-mcp': 'progress.restoringMcp',
48
+ 'validating-config': 'progress.validatingConfig',
49
+ 'rolling-back': 'progress.rollingBack',
50
+ executing: 'progress.executing',
51
+ done: 'progress.done',
52
+ };
53
+ /** 阶段 id → 用户可读文案(未知阶段回退 id) */
54
+ export function stageText(stage, t = zhUiT) {
55
+ const key = STAGE_KEYS[stage];
56
+ return key !== undefined ? t(key) : stage;
57
+ }
58
+ /**
59
+ * 进度追踪器:按给定阶段序列在回调时附带 step/total 序号。
60
+ * 控制器调用 core 前后 emit(),UI 侧渲染进度条/阶段文字。
61
+ */
62
+ export class ProgressTracker {
63
+ listener;
64
+ stages;
65
+ emitted = [];
66
+ constructor(stages, listener) {
67
+ this.stages = stages;
68
+ this.listener = listener;
69
+ }
70
+ /** 发出某阶段事件(可携带 detail);未在序列中的阶段 step/total 缺省 */
71
+ emit(stage, detail) {
72
+ const idx = this.stages.indexOf(stage);
73
+ const event = {
74
+ stage,
75
+ detail,
76
+ step: idx >= 0 ? idx + 1 : undefined,
77
+ total: idx >= 0 ? this.stages.length : undefined,
78
+ };
79
+ this.emitted.push(stage);
80
+ this.listener?.(event);
81
+ }
82
+ /** 已发出阶段的快照(测试与日志用) */
83
+ get events() {
84
+ return [...this.emitted];
85
+ }
86
+ }
87
+ //# sourceMappingURL=progress.js.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 报告渲染(规范 §21 导出报告 / §22 导入报告 / §17 回滚报告,m6-ui)。
3
+ *
4
+ * 纯文本渲染:输出用户可读的多行文本(未来 React 客户端可直接替换为组件渲染)。
5
+ * 导入报告按分区统计:从 ExecutedItem.itemId 前缀推断所属分区(与 adapters 的 id 规则一致)。
6
+ */
7
+ import type { SectionId } from '../schema/types.ts';
8
+ import type { ExecutedItem, ExportReport, ImportResult, RollbackReport } from '../core/types.ts';
9
+ import type { ImportResultAction, ImportSectionStat } from './types.ts';
10
+ import { type UiT } from './i18n.ts';
11
+ export declare function renderExportReport(report: ExportReport, t?: UiT): string;
12
+ /** 从 itemId 前缀推断所属分区(与 adapters id 规则对齐;未知归 'other') */
13
+ export declare function sectionFromItemId(itemId: string): SectionId | 'other';
14
+ /** 按分区聚合执行结果(统计 + 明细) */
15
+ export declare function importSectionStats(executed: readonly ExecutedItem[]): ImportSectionStat[];
16
+ /** 导入报告渲染(含回滚状态;§22 动作按钮由 suggestedActions 给出) */
17
+ export declare function renderImportReport(result: ImportResult, t?: UiT): string;
18
+ /** 结果页动作按钮(§22)。报告已内联展示全部失败/警告项的原因与回滚详情(§23),
19
+ * 不再提供空操作的 Fix Issues / View Details 按钮——仅保留「完成」。 */
20
+ export declare function suggestedActions(_result: ImportResult): ImportResultAction[];
21
+ /** 回滚报告渲染(full / partial + 人工恢复清单) */
22
+ export declare function renderRollbackReport(rr: RollbackReport, t?: UiT): string;
23
+ export declare function formatBytes(n: number): string;
@@ -0,0 +1,153 @@
1
+ import { zhUiT } from './i18n.js';
2
+ /* ---------------- §21 导出报告 ---------------- */
3
+ export function renderExportReport(report, t = zhUiT) {
4
+ const lines = [t('report.backupCreated'), ''];
5
+ lines.push(t('report.included'));
6
+ for (const { section, counts } of report.included) {
7
+ const detail = Object.entries(counts)
8
+ .map(([k, v]) => `${v} ${k}`)
9
+ .join(', ');
10
+ lines.push(` ✓ ${section}${detail !== '' ? ` (${detail})` : ''}`);
11
+ }
12
+ lines.push('');
13
+ if (report.excluded.length > 0) {
14
+ lines.push(t('report.excluded'));
15
+ for (const s of report.excluded)
16
+ lines.push(` ○ ${s}`);
17
+ lines.push('');
18
+ }
19
+ lines.push(t('report.security'));
20
+ lines.push(` ✓ ${t('report.apiKeysExcluded')} ${report.security.secretsExcluded ? t('report.yes') : t('report.no')}`);
21
+ lines.push(` ✓ ${t('report.containsSecrets')} ${report.security.containsSecrets ? t('report.yesEncrypted') : t('report.no')}`);
22
+ lines.push(` ✓ ${t('report.encrypted')} ${report.security.encrypted ? t('report.yes') : t('report.no')}`);
23
+ if (report.security.redactedHits > 0)
24
+ lines.push(` ⚠ ${t('report.redacted', { count: String(report.security.redactedHits) })}`);
25
+ lines.push('');
26
+ lines.push(`${t('report.file')} ${report.file.name} (${formatBytes(report.file.sizeBytes)})`);
27
+ for (const w of report.warnings)
28
+ lines.push(` ⚠ ${w}`);
29
+ return lines.join('\n');
30
+ }
31
+ /* ---------------- §22 导入报告 ---------------- */
32
+ /** 从 itemId 前缀推断所属分区(与 adapters id 规则对齐;未知归 'other') */
33
+ export function sectionFromItemId(itemId) {
34
+ if (itemId.startsWith('settings:'))
35
+ return 'settings';
36
+ if (itemId.startsWith('ui:'))
37
+ return 'ui';
38
+ if (itemId.startsWith('provider:'))
39
+ return 'providers';
40
+ if (itemId.startsWith('plugin:') || itemId.startsWith('patch:'))
41
+ return 'plugins';
42
+ if (itemId.startsWith('mcp:'))
43
+ return 'mcp';
44
+ if (itemId.startsWith('prompt:'))
45
+ return 'prompts';
46
+ if (itemId.startsWith('workspace:'))
47
+ return 'workspaces';
48
+ if (itemId.startsWith('secret:'))
49
+ return 'credentialsStatus';
50
+ if (itemId.startsWith('skills:'))
51
+ return 'skills';
52
+ if (itemId.startsWith('agentPresets:'))
53
+ return 'agentPresets';
54
+ if (itemId.startsWith('agentInstructions:'))
55
+ return 'agentInstructions';
56
+ if (itemId.startsWith('pluginFiles:'))
57
+ return 'pluginFiles';
58
+ if (itemId.startsWith('sessions:'))
59
+ return 'sessions';
60
+ return 'other';
61
+ }
62
+ /** 按分区聚合执行结果(统计 + 明细) */
63
+ export function importSectionStats(executed) {
64
+ const bySection = new Map();
65
+ for (const e of executed) {
66
+ const section = sectionFromItemId(e.itemId);
67
+ let stat = bySection.get(section);
68
+ if (!stat) {
69
+ stat = { section: section, ok: 0, skipped: 0, warned: 0, failed: 0, items: [] };
70
+ bySection.set(section, stat);
71
+ }
72
+ if (e.status === 'ok')
73
+ stat.ok += 1;
74
+ else if (e.status === 'skipped')
75
+ stat.skipped += 1;
76
+ else if (e.status === 'warning')
77
+ stat.warned += 1;
78
+ else
79
+ stat.failed += 1;
80
+ stat.items.push(e);
81
+ }
82
+ return [...bySection.values()];
83
+ }
84
+ /** 导入报告渲染(含回滚状态;§22 动作按钮由 suggestedActions 给出) */
85
+ export function renderImportReport(result, t = zhUiT) {
86
+ const lines = [result.ok ? t('report.importComplete') : t('report.importFailed'), ''];
87
+ // F4:被删除墓碑过滤的条目提示(用户明确删过、不复活)
88
+ if ((result.skippedTombstoned?.length ?? 0) > 0) {
89
+ lines.push(t('report.tombstonedSkipped', { count: String(result.skippedTombstoned.length) }));
90
+ lines.push('');
91
+ }
92
+ const stats = importSectionStats(result.executed);
93
+ for (const s of stats) {
94
+ const parts = [];
95
+ if (s.ok > 0)
96
+ parts.push(`✓ ${s.ok} ${t('report.importedRestored')}`);
97
+ if (s.skipped > 0)
98
+ parts.push(`- ${s.skipped} ${t('report.skipped')}`);
99
+ if (s.warned > 0)
100
+ parts.push(`⚠ ${s.warned} ${t('report.needAttention')}`);
101
+ if (s.failed > 0)
102
+ parts.push(`✗ ${s.failed} ${t('report.failed')}`);
103
+ lines.push(`${s.section}: ${parts.join(' ') || t('report.noChanges')}`);
104
+ // 失败/警告项给出可操作原因(§23)
105
+ for (const it of s.items) {
106
+ if (it.status === 'failed' || it.status === 'warning') {
107
+ lines.push(` ${it.status === 'failed' ? t('report.reason') : t('report.note')}: ${it.message ?? t('report.unknownReason')}`);
108
+ }
109
+ }
110
+ }
111
+ if (result.missingSecrets.length > 0) {
112
+ lines.push(`${t('report.secrets')} ⚠ ${t('report.credentialsNeedEntry', { count: String(result.missingSecrets.length) })}`);
113
+ }
114
+ if (result.needsRestart) {
115
+ lines.push(t('report.restartPluginsMcp'));
116
+ }
117
+ for (const w of result.warnings)
118
+ lines.push(`⚠ ${w}`);
119
+ if (result.rollback) {
120
+ lines.push('');
121
+ lines.push(renderRollbackReport(result.rollback, t));
122
+ }
123
+ return lines.join('\n');
124
+ }
125
+ /** 结果页动作按钮(§22)。报告已内联展示全部失败/警告项的原因与回滚详情(§23),
126
+ * 不再提供空操作的 Fix Issues / View Details 按钮——仅保留「完成」。 */
127
+ export function suggestedActions(_result) {
128
+ return ['done'];
129
+ }
130
+ /* ---------------- §17 回滚报告 ---------------- */
131
+ /** 回滚报告渲染(full / partial + 人工恢复清单) */
132
+ export function renderRollbackReport(rr, t = zhUiT) {
133
+ if (rr.full) {
134
+ return t('report.rollbackFull');
135
+ }
136
+ const lines = [t('report.rollbackPartial')];
137
+ lines.push(t('report.rollbackManual'));
138
+ for (const f of rr.failed) {
139
+ lines.push(` - ${f.item}: ${f.reason}${f.manualHint ? ` (${f.manualHint})` : ''}`);
140
+ }
141
+ if (rr.restored.length > 0)
142
+ lines.push(t('report.restored', { count: String(rr.restored.length) }));
143
+ return lines.join('\n');
144
+ }
145
+ /* ---------------- 工具 ---------------- */
146
+ export function formatBytes(n) {
147
+ if (n < 1024)
148
+ return `${n} B`;
149
+ if (n < 1024 * 1024)
150
+ return `${(n / 1024).toFixed(1)} KB`;
151
+ return `${(n / (1024 * 1024)).toFixed(1)} MB`;
152
+ }
153
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1,69 @@
1
+ /**
2
+ * UI 层测试辅助(m6-ui):mock core 调用与样本数据。
3
+ * 仅供 src/ui/*.test.ts 使用,不参与生产构建语义。
4
+ */
5
+ import type { Manifest } from '../schema/types.ts';
6
+ import type { ExportReport, ImportAnalysis, ImportDecisions, ImportPlan, ImportResult, PlanItem, RollbackReport } from '../core/types.ts';
7
+ import type { ExportPort } from './export-flow.ts';
8
+ import type { ImportPort } from './types.ts';
9
+ /** 样本 manifest(UI 测试不关心真实字段,仅类型占位) */
10
+ export declare function makeManifest(): Manifest;
11
+ export declare function makeExportReport(overrides?: Partial<ExportReport>): ExportReport;
12
+ /** 内存 ExportPort mock:记录调用参数,返回固定结果 */
13
+ export declare class MockExportPort implements ExportPort {
14
+ calls: {
15
+ includeSecrets: boolean;
16
+ only?: string[];
17
+ }[];
18
+ result: {
19
+ zipPath: string;
20
+ manifest: Manifest;
21
+ report: ExportReport;
22
+ };
23
+ constructor(report?: ExportReport);
24
+ export(opts: {
25
+ includeSecrets: boolean;
26
+ only?: string[];
27
+ }): Promise<{
28
+ zipPath: string;
29
+ manifest: Manifest;
30
+ report: ExportReport;
31
+ }>;
32
+ }
33
+ export declare function makeAnalysis(overrides?: Partial<ImportAnalysis>): ImportAnalysis;
34
+ export declare function makePlanItem(overrides?: Partial<PlanItem>): PlanItem;
35
+ export declare function makePlan(overrides?: Partial<ImportPlan>): ImportPlan;
36
+ export declare function makeRollbackReport(overrides?: Partial<RollbackReport>): RollbackReport;
37
+ export declare function makeImportResult(overrides?: Partial<ImportResult>): ImportResult;
38
+ /** 内存 ImportPort mock:可编排各阶段返回与调用记录 */
39
+ export declare class MockImportPort implements ImportPort {
40
+ analysis: ImportAnalysis;
41
+ plan: ImportPlan;
42
+ result: ImportResult;
43
+ analyzeCalls: number;
44
+ planCalls: ImportDecisions[];
45
+ executeCalls: {
46
+ confirm: boolean;
47
+ secretInputs?: Record<string, string>;
48
+ rollbackOnError: boolean;
49
+ decryptPassword?: string;
50
+ plan?: ImportPlan;
51
+ }[];
52
+ constructor(opts?: {
53
+ analysis?: ImportAnalysis;
54
+ plan?: ImportPlan;
55
+ result?: ImportResult;
56
+ });
57
+ analyzeImport(): Promise<ImportAnalysis>;
58
+ createImportPlan(_zip: string, decisions: ImportDecisions): Promise<ImportPlan>;
59
+ decryptArchive(zipPath: string): Promise<{
60
+ zipPath: string;
61
+ refs: string[];
62
+ }>;
63
+ executeImportPlan(_zip: string, plan: ImportPlan, opts: {
64
+ confirm: boolean;
65
+ secretInputs?: Record<string, string>;
66
+ rollbackOnError: boolean;
67
+ decryptPassword?: string;
68
+ }): Promise<ImportResult>;
69
+ }