@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,181 @@
1
+ /**
2
+ * Toast Store —— 全局通知的纯逻辑状态机(零 DOM、零 React,node 可单测)。
3
+ *
4
+ * 为什么独立成 store:插件里大量「操作完成后临时提示」原先散落在各页的局部 state
5
+ * (`flash` / `feedback` / `saved`)里,只能渲染在页面内容流中、切页即丢失、还会把
6
+ * 页面顶开一块。统一到模块级 store 后可跨页面存活,并集中处理去重、同屏上限与自动消失。
7
+ *
8
+ * 设计要点:
9
+ * - 订阅式(`subscribe`/`getSnapshot`)对接 `useSyncExternalStore`;snapshot 引用仅在
10
+ * 真正变更时替换,避免 React 无限重渲染。
11
+ * - 计时器依赖注入(`schedule`/`cancel`):测试里可用假计时器精确驱动,不必等真实时间。
12
+ * - 同 `kind + text` 已在屏时**不重复入队**,只重置计时(防连点导致刷屏)。
13
+ * - 同屏上限 `maxVisible`(默认 4):超出时挤掉最旧的一条,连其计时器一并清理。
14
+ * - 空文案(trim 后为空)直接忽略,杜绝空白通知条。
15
+ */
16
+ import type { ToastKind } from './toast-types.ts'
17
+
18
+ export type { ToastKind }
19
+
20
+ /** 单条通知。 */
21
+ export interface ToastItem {
22
+ id: number
23
+ kind: ToastKind
24
+ text: string
25
+ /** 自动消失毫秒数;0 = 不自动消失(须手动关闭) */
26
+ durationMs: number
27
+ }
28
+
29
+ /** store 快照(`getSnapshot` 返回的稳定引用)。 */
30
+ export interface ToastSnapshot {
31
+ items: ToastItem[]
32
+ }
33
+
34
+ /** 计时器句柄(浏览器为 number,node 为 Timeout,测试可自定义)。 */
35
+ export type ToastTimerHandle = unknown
36
+
37
+ export interface ToastStoreOptions {
38
+ /** 同屏最大条数(默认 4);超出挤掉最旧。 */
39
+ maxVisible?: number
40
+ /** 排定计时器(默认 setTimeout),测试可注入假实现。 */
41
+ schedule?: (fn: () => void, ms: number) => ToastTimerHandle
42
+ /** 取消计时器(默认 clearTimeout)。 */
43
+ cancel?: (handle: ToastTimerHandle) => void
44
+ }
45
+
46
+ /** 各语义的默认停留时长:成功/普通短、失败/警告长(错误需要更多阅读时间)。 */
47
+ export const DEFAULT_DURATION_MS: Record<ToastKind, number> = {
48
+ ok: 3200,
49
+ info: 3200,
50
+ warn: 5200,
51
+ error: 6400,
52
+ }
53
+
54
+ /** 同屏上限:超过 4 条会盖住插件画布右下角的大片区域。 */
55
+ export const MAX_VISIBLE = 4
56
+
57
+ const EMPTY: ToastSnapshot = { items: [] }
58
+
59
+ /**
60
+ * 全局通知状态机。通常只用下方的 `toast` 单例,测试时可直接 new 一个隔离实例。
61
+ */
62
+ export class ToastStore {
63
+ private items: ToastItem[] = []
64
+ private readonly timers = new Map<number, ToastTimerHandle>()
65
+ private readonly listeners = new Set<() => void>()
66
+ private nextId = 1
67
+ private snapshot: ToastSnapshot = EMPTY
68
+ private readonly maxVisible: number
69
+ private readonly schedule: (fn: () => void, ms: number) => ToastTimerHandle
70
+ private readonly cancel: (handle: ToastTimerHandle) => void
71
+
72
+ constructor(options: ToastStoreOptions = {}) {
73
+ this.maxVisible = options.maxVisible ?? MAX_VISIBLE
74
+ this.schedule = options.schedule ?? ((fn, ms) => setTimeout(fn, ms))
75
+ this.cancel = options.cancel ?? ((handle) => { clearTimeout(handle as ReturnType<typeof setTimeout>) })
76
+ }
77
+
78
+ subscribe = (listener: () => void): (() => void) => {
79
+ this.listeners.add(listener)
80
+ return () => { this.listeners.delete(listener) }
81
+ }
82
+
83
+ getSnapshot = (): ToastSnapshot => this.snapshot
84
+
85
+ /**
86
+ * 推入一条通知。返回该条 id;空文案返回 0(表示未入队)。
87
+ * 同 kind+text 已在屏时复用原条目并重置计时。
88
+ */
89
+ push(kind: ToastKind, text: string, durationMs?: number): number {
90
+ const value = text.trim()
91
+ if (value === '') return 0
92
+ const duration = durationMs ?? DEFAULT_DURATION_MS[kind]
93
+
94
+ const existing = this.items.find((t) => t.kind === kind && t.text === value)
95
+ if (existing !== undefined) {
96
+ this.arm(existing.id, duration)
97
+ return existing.id
98
+ }
99
+
100
+ const id = this.nextId++
101
+ const next: ToastItem[] = [...this.items, { id, kind, text: value, durationMs: duration }]
102
+ const overflowCount = Math.max(0, next.length - this.maxVisible)
103
+ for (const stale of next.slice(0, overflowCount)) this.disarm(stale.id)
104
+ this.items = next.slice(overflowCount)
105
+ this.arm(id, duration)
106
+ this.commit()
107
+ return id
108
+ }
109
+
110
+ /** 关闭指定通知(手动关闭 / 计时到期共用)。 */
111
+ dismiss(id: number): void {
112
+ if (!this.items.some((t) => t.id === id)) return
113
+ this.disarm(id)
114
+ this.items = this.items.filter((t) => t.id !== id)
115
+ this.commit()
116
+ }
117
+
118
+ /**
119
+ * 重新计时(悬停暂停用):取消该条当前计时并按 `durationMs`(缺省沿用原时长)重新排定。
120
+ * 不改变条目位置与内容,因此不产生新快照——避免悬停时触发无谓重渲染。
121
+ */
122
+ resetTimer(id: number, durationMs?: number): void {
123
+ const item = this.items.find((t) => t.id === id)
124
+ if (item === undefined) return
125
+ this.arm(id, durationMs ?? item.durationMs)
126
+ }
127
+
128
+ /** 暂停自动消失(悬停):仅取消计时,条目与位置不变。 */
129
+ pauseTimer(id: number): void {
130
+ if (!this.items.some((t) => t.id === id)) return
131
+ this.disarm(id)
132
+ }
133
+
134
+ /** 清空全部通知。 */
135
+ clear(): void {
136
+ if (this.items.length === 0) return
137
+ for (const item of this.items) this.disarm(item.id)
138
+ this.items = []
139
+ this.commit()
140
+ }
141
+
142
+ /** 排定 / 重置某条的自动消失计时;durationMs <= 0 表示常驻。 */
143
+ private arm(id: number, durationMs: number): void {
144
+ this.disarm(id)
145
+ if (durationMs <= 0) return
146
+ this.timers.set(id, this.schedule(() => { this.dismiss(id) }, durationMs))
147
+ }
148
+
149
+ private disarm(id: number): void {
150
+ const handle = this.timers.get(id)
151
+ if (handle === undefined) return
152
+ this.cancel(handle)
153
+ this.timers.delete(id)
154
+ }
155
+
156
+ /** 提交新快照并通知订阅者(仅在真正变化时调用)。 */
157
+ private commit(): void {
158
+ this.snapshot = { items: this.items }
159
+ for (const listener of this.listeners) listener()
160
+ }
161
+ }
162
+
163
+ /** 进程级单例(插件内所有页面共用一套通知队列)。 */
164
+ export const toastStore = new ToastStore()
165
+
166
+ /**
167
+ * 面向业务代码的调用入口。
168
+ *
169
+ * toast.ok('已保存配置档案')
170
+ * toast.error(redact(err.message))
171
+ *
172
+ * 约定:文案在调用前完成 i18n 与 `redact()`(本模块不碰翻译与脱敏)。
173
+ */
174
+ export const toast = {
175
+ ok: (text: string, durationMs?: number): number => toastStore.push('ok', text, durationMs),
176
+ info: (text: string, durationMs?: number): number => toastStore.push('info', text, durationMs),
177
+ warn: (text: string, durationMs?: number): number => toastStore.push('warn', text, durationMs),
178
+ error: (text: string, durationMs?: number): number => toastStore.push('error', text, durationMs),
179
+ dismiss: (id: number): void => { toastStore.dismiss(id) },
180
+ clear: (): void => { toastStore.clear() },
181
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Toast 公共类型 —— 独立成文件是为了让 store(无 React)与视图(React)都能引用,
3
+ * 且不产生「store → 视图」的反向依赖。
4
+ */
5
+
6
+ /** 通知语义:与 Badge / Banner / StatusDot 的既有四态保持一致。 */
7
+ export type ToastKind = 'ok' | 'info' | 'warn' | 'error'
@@ -0,0 +1,342 @@
1
+ /**
2
+ * Config Manager 基础 UI 原语 —— Workbench Design System(2026-09 Full UI Rebuild)。
3
+ * 全部走 DSH Design System 的 --dsw-* token,不另造视觉体系;类名来自
4
+ * config-manager.module.css,无业务逻辑。
5
+ *
6
+ * 本文件是重建后的原语层:在既有 API(Button/Badge/Banner/Card/Spinner/Field/
7
+ * SectionTitle/Empty/Checkbox/Stepper)完全兼容的前提下,新增:
8
+ * - Button size('sm' 密集场景)
9
+ * - IconButton(导航/工具栏图标动作)
10
+ * - StatusDot(状态栏/行内状态点)
11
+ * - Segmented(页内子视图分段切换)
12
+ */
13
+ import type { ChangeEvent, CSSProperties, ReactNode } from 'react'
14
+ import css from '../config-manager.module.css'
15
+
16
+ /* ---------------- Button ---------------- */
17
+
18
+ export type ButtonVariant = 'primary' | 'ghost' | 'danger'
19
+ export type ButtonSize = 'sm' | 'md'
20
+
21
+ export interface ButtonProps {
22
+ variant?: ButtonVariant
23
+ /** 尺寸:sm = 表格行内/密集工具栏(24px);md = 常规(28px,缺省) */
24
+ size?: ButtonSize
25
+ disabled?: boolean
26
+ /** 进行中态:自动 disabled + aria-busy(children 由调用方渲染 Spinner 保持现状) */
27
+ loading?: boolean
28
+ onClick?: () => void
29
+ children: ReactNode
30
+ title?: string
31
+ className?: string
32
+ /** 外链 URL:存在时渲染 <a>(新窗口 + noreferrer,防 tabnabbing),否则渲染 <button> */
33
+ href?: string
34
+ /** 是否新窗口打开(仅 href 存在时生效;默认 true) */
35
+ newTab?: boolean
36
+ }
37
+
38
+ /**
39
+ * 统一按钮(primary=主操作 / ghost=次操作 / danger=危险操作)。
40
+ * 带 href 时渲染同款按钮类的外链 <a>;loading=true 时自动禁用并标注 aria-busy。
41
+ */
42
+ export function Button({ variant = 'ghost', size, disabled, loading = false, onClick, children, title, className, href, newTab = true }: ButtonProps) {
43
+ const cls =
44
+ variant === 'primary' ? css.primaryButton
45
+ : variant === 'danger' ? css.dangerButton
46
+ : css.ghostButton
47
+ const effectiveDisabled = disabled === true || loading
48
+ const sizeProps = size === 'sm' ? { 'data-size': 'sm' as const } : {}
49
+ if (href !== undefined) {
50
+ return (
51
+ <a
52
+ className={className !== undefined ? `${cls} ${className}` : cls}
53
+ href={href}
54
+ target={newTab ? '_blank' : undefined}
55
+ rel={newTab ? 'noreferrer' : undefined}
56
+ title={title}
57
+ aria-busy={loading || undefined}
58
+ onClick={onClick}
59
+ // 按钮类无 text-decoration 规则,<a> 默认下划线破坏按钮外观
60
+ style={{ textDecoration: 'none' }}
61
+ {...sizeProps}
62
+ >
63
+ {children}
64
+ </a>
65
+ )
66
+ }
67
+ return (
68
+ <button
69
+ type="button"
70
+ className={className !== undefined ? `${cls} ${className}` : cls}
71
+ disabled={effectiveDisabled}
72
+ title={title}
73
+ aria-busy={loading || undefined}
74
+ onClick={onClick}
75
+ {...sizeProps}
76
+ >
77
+ {children}
78
+ </button>
79
+ )
80
+ }
81
+
82
+ /* ---------------- IconButton ---------------- */
83
+
84
+ export interface IconButtonProps {
85
+ /** 图标/符号(文本符号;aria-label 必填描述用途) */
86
+ icon: ReactNode
87
+ /** 无障碍名称(必填:图标按钮没有可见文本) */
88
+ label: string
89
+ onClick?: () => void
90
+ disabled?: boolean
91
+ /** 高亮态(如抽屉打开时对应按钮 active) */
92
+ active?: boolean
93
+ /** 危险语义(红色;用于行内删除等破坏性动作的视觉隔离) */
94
+ danger?: boolean
95
+ title?: string
96
+ }
97
+
98
+ /** 图标按钮(导航条/工具栏图标动作;26px 触达区)。 */
99
+ export function IconButton({ icon, label, onClick, disabled, active, danger, title }: IconButtonProps) {
100
+ return (
101
+ <button
102
+ type="button"
103
+ className={css.iconBtn}
104
+ aria-label={label}
105
+ title={title ?? label}
106
+ data-active={active === true ? '' : undefined}
107
+ data-danger={danger === true ? '' : undefined}
108
+ disabled={disabled === true}
109
+ onClick={onClick}
110
+ >
111
+ {icon}
112
+ </button>
113
+ )
114
+ }
115
+
116
+ /* ---------------- StatusDot ---------------- */
117
+
118
+ export type StatusDotKind = 'idle' | 'ok' | 'info' | 'warn' | 'error'
119
+
120
+ export interface StatusDotProps {
121
+ kind?: StatusDotKind
122
+ /** 进行中脉冲动画 */
123
+ pulse?: boolean
124
+ }
125
+
126
+ /** 状态点(状态栏/行内状态指示)。 */
127
+ export function StatusDot({ kind = 'idle', pulse }: StatusDotProps) {
128
+ return (
129
+ <span
130
+ className={css.statusDot}
131
+ data-kind={kind === 'idle' ? undefined : kind}
132
+ data-pulse={pulse === true ? '' : undefined}
133
+ aria-hidden="true"
134
+ />
135
+ )
136
+ }
137
+
138
+ /* ---------------- Badge ---------------- */
139
+
140
+ export type BadgeKind = 'info' | 'ok' | 'warn' | 'error'
141
+
142
+ export interface BadgeProps {
143
+ kind?: BadgeKind
144
+ children: ReactNode
145
+ /** 悬停提示(可选) */
146
+ title?: string
147
+ }
148
+
149
+ /** 状态徽章(info=业务色 / ok=成功 / warn=警告 / error=错误)。 */
150
+ export function Badge({ kind = 'info', children, title }: BadgeProps) {
151
+ return <span className={`${css.badge} ${css[`badge${kind[0]!.toUpperCase()}${kind.slice(1)}`] ?? ''}`} title={title}>{children}</span>
152
+ }
153
+
154
+ /* ---------------- Banner ---------------- */
155
+
156
+ export type BannerKind = 'ok' | 'error' | 'info' | 'warn'
157
+
158
+ export interface BannerProps {
159
+ kind?: BannerKind
160
+ children: ReactNode
161
+ }
162
+
163
+ /** 说明横幅(ok/error/info/warn 四态) */
164
+ export function Banner({ kind = 'info', children }: BannerProps) {
165
+ return <div className={css.banner} data-kind={kind}>{children}</div>
166
+ }
167
+
168
+ /* ---------------- Card ---------------- */
169
+
170
+ export interface CardProps {
171
+ children: ReactNode
172
+ className?: string
173
+ /** 少量布局微调(flex 填充等);常规布局仍走 CSS 类 */
174
+ style?: CSSProperties
175
+ }
176
+
177
+ /** 卡片容器(bg-layer-2 + 细边框) */
178
+ export function Card({ children, className, style }: CardProps) {
179
+ return <div className={className !== undefined ? `${css.card} ${className}` : css.card} style={style}>{children}</div>
180
+ }
181
+
182
+ /* ---------------- Spinner ---------------- */
183
+
184
+ export interface SpinnerProps {
185
+ label?: string
186
+ }
187
+
188
+ /** 加载指示(旋转环 + 可选文案) */
189
+ export function Spinner({ label }: SpinnerProps) {
190
+ return (
191
+ <span className={css.spinnerWrap}>
192
+ <span className={css.spinner} aria-hidden="true" />
193
+ {label !== undefined && <span className={css.spinnerLabel}>{label}</span>}
194
+ </span>
195
+ )
196
+ }
197
+
198
+ /* ---------------- Field ---------------- */
199
+
200
+ export interface FieldProps {
201
+ label: string
202
+ hint?: string
203
+ children: ReactNode
204
+ }
205
+
206
+ /** 表单字段(标签 + 控件 + 说明) */
207
+ export function Field({ label, hint, children }: FieldProps) {
208
+ return (
209
+ <label className={css.field}>
210
+ <span className={css.fieldLabel}>{label}</span>
211
+ {children}
212
+ {hint !== undefined && <span className={css.hint}>{hint}</span>}
213
+ </label>
214
+ )
215
+ }
216
+
217
+ /* ---------------- SectionTitle ---------------- */
218
+
219
+ export interface SectionTitleProps {
220
+ title: string
221
+ subtitle?: string
222
+ }
223
+
224
+ /** 区块标题(页面内二级标题 + 可选副标题) */
225
+ export function SectionTitle({ title, subtitle }: SectionTitleProps) {
226
+ return (
227
+ <div className={css.sectionTitleBlock}>
228
+ <h3 className={css.sectionTitle}>{title}</h3>
229
+ {subtitle !== undefined && <p className={css.sectionSubtitle}>{subtitle}</p>}
230
+ </div>
231
+ )
232
+ }
233
+
234
+ /* ---------------- Empty / Loading ---------------- */
235
+
236
+ export interface EmptyProps {
237
+ children: ReactNode
238
+ }
239
+
240
+ /** 空状态占位 */
241
+ export function Empty({ children }: EmptyProps) {
242
+ return <div className={css.empty}>{children}</div>
243
+ }
244
+
245
+ /* ---------------- Checkbox ---------------- */
246
+
247
+ export interface CheckboxProps {
248
+ checked: boolean
249
+ onChange: (checked: boolean) => void
250
+ label: ReactNode
251
+ disabled?: boolean
252
+ }
253
+
254
+ /** 复选框行(勾选 + 标签) */
255
+ export function Checkbox({ checked, onChange, label, disabled }: CheckboxProps) {
256
+ return (
257
+ <label className={css.checkboxRow}>
258
+ <input
259
+ type="checkbox"
260
+ checked={checked}
261
+ disabled={disabled}
262
+ onChange={(event: ChangeEvent<HTMLInputElement>) => { onChange(event.target.checked) }}
263
+ />
264
+ <span>{label}</span>
265
+ </label>
266
+ )
267
+ }
268
+
269
+ /* ---------------- Segmented ---------------- */
270
+
271
+ export interface SegmentedItem {
272
+ id: string
273
+ label: string
274
+ /** 计数徽标(可选;如市场分区筛选计数) */
275
+ count?: number
276
+ }
277
+
278
+ export interface SegmentedProps {
279
+ items: SegmentedItem[]
280
+ active: string
281
+ onChange: (id: string) => void
282
+ ariaLabel?: string
283
+ }
284
+
285
+ /** 分段控件(页内子视图切换;受控)。 */
286
+ export function Segmented({ items, active, onChange, ariaLabel }: SegmentedProps) {
287
+ return (
288
+ <div className={css.segGroup} role="tablist" aria-label={ariaLabel}>
289
+ {items.map((item) => (
290
+ <button
291
+ key={item.id}
292
+ type="button"
293
+ role="tab"
294
+ aria-selected={item.id === active}
295
+ data-active={item.id === active ? '' : undefined}
296
+ className={css.segItem}
297
+ onClick={() => { onChange(item.id) }}
298
+ >
299
+ {item.label}
300
+ {item.count !== undefined && <span aria-hidden="true">·{item.count}</span>}
301
+ </button>
302
+ ))}
303
+ </div>
304
+ )
305
+ }
306
+
307
+ /* ---------------- Stepper ---------------- */
308
+
309
+ export type StepperStepState = 'done' | 'current' | 'todo'
310
+
311
+ export interface StepperStep {
312
+ /** 步骤唯一 key(React list key)。 */
313
+ key: string
314
+ label: string
315
+ state: StepperStepState
316
+ }
317
+
318
+ export interface StepperProps {
319
+ steps: StepperStep[]
320
+ /** 可访问性说明(如「第 2 步,共 6 步」);存在时容器带 role=group + aria-label */
321
+ ariaLabel?: string
322
+ }
323
+
324
+ /**
325
+ * 向导步骤条(只读指示器,非导航):紧凑圆点(序号/✓)+ 连接线 + 标签。
326
+ * state 由调用方的纯函数模型给出;组件不做任何状态推断。
327
+ */
328
+ export function Stepper({ steps, ariaLabel }: StepperProps) {
329
+ return (
330
+ <div className={css.stepper} role={ariaLabel !== undefined ? 'group' : 'list'} aria-label={ariaLabel}>
331
+ {steps.map((step, i) => (
332
+ <span key={step.key} role="listitem" className={css.stepperStep} data-state={step.state}>
333
+ <span className={css.stepperDot} data-state={step.state} aria-hidden="true">
334
+ {step.state === 'done' ? '✓' : i + 1}
335
+ </span>
336
+ <span className={css.stepperLabel}>{step.label}</span>
337
+ {i < steps.length - 1 && <span className={css.stepperConnector} aria-hidden="true" />}
338
+ </span>
339
+ ))}
340
+ </div>
341
+ )
342
+ }