@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.
- package/LICENSE +21 -0
- package/README.md +105 -0
- package/cordis.patch.yml +21 -0
- package/lib/adapters/agent-instructions.d.ts +13 -0
- package/lib/adapters/agent-instructions.js +46 -0
- package/lib/adapters/agent-presets.d.ts +13 -0
- package/lib/adapters/agent-presets.js +14 -0
- package/lib/adapters/credentials.d.ts +37 -0
- package/lib/adapters/credentials.js +122 -0
- package/lib/adapters/file-collection.d.ts +15 -0
- package/lib/adapters/file-collection.js +127 -0
- package/lib/adapters/index.d.ts +57 -0
- package/lib/adapters/index.js +55 -0
- package/lib/adapters/link-report.d.ts +16 -0
- package/lib/adapters/link-report.js +47 -0
- package/lib/adapters/mcp.d.ts +28 -0
- package/lib/adapters/mcp.js +178 -0
- package/lib/adapters/plugin-files.d.ts +18 -0
- package/lib/adapters/plugin-files.js +142 -0
- package/lib/adapters/plugins.d.ts +41 -0
- package/lib/adapters/plugins.js +603 -0
- package/lib/adapters/pnpm-workspace.d.ts +26 -0
- package/lib/adapters/pnpm-workspace.js +147 -0
- package/lib/adapters/prompts.d.ts +30 -0
- package/lib/adapters/prompts.js +231 -0
- package/lib/adapters/providers.d.ts +34 -0
- package/lib/adapters/providers.js +155 -0
- package/lib/adapters/self.d.ts +17 -0
- package/lib/adapters/self.js +71 -0
- package/lib/adapters/sessions.d.ts +14 -0
- package/lib/adapters/sessions.js +15 -0
- package/lib/adapters/settings.d.ts +28 -0
- package/lib/adapters/settings.js +165 -0
- package/lib/adapters/skills.d.ts +13 -0
- package/lib/adapters/skills.js +14 -0
- package/lib/adapters/test-helpers.d.ts +125 -0
- package/lib/adapters/test-helpers.js +236 -0
- package/lib/adapters/ui.d.ts +27 -0
- package/lib/adapters/ui.js +89 -0
- package/lib/adapters/workspaces.d.ts +13 -0
- package/lib/adapters/workspaces.js +106 -0
- package/lib/client.d.ts +1026 -0
- package/lib/client.js +10047 -0
- package/lib/core/analyzer.d.ts +99 -0
- package/lib/core/analyzer.js +934 -0
- package/lib/core/backup.d.ts +138 -0
- package/lib/core/backup.js +513 -0
- package/lib/core/boot-rescue.d.ts +146 -0
- package/lib/core/boot-rescue.js +618 -0
- package/lib/core/cache-cleaner.d.ts +31 -0
- package/lib/core/cache-cleaner.js +95 -0
- package/lib/core/config-lifecycle.d.ts +180 -0
- package/lib/core/config-lifecycle.js +481 -0
- package/lib/core/config-snapshot.d.ts +135 -0
- package/lib/core/config-snapshot.js +424 -0
- package/lib/core/config-state.d.ts +70 -0
- package/lib/core/config-state.js +177 -0
- package/lib/core/consult-source.d.ts +58 -0
- package/lib/core/consult-source.js +260 -0
- package/lib/core/crash-report.d.ts +84 -0
- package/lib/core/crash-report.js +317 -0
- package/lib/core/exporter.d.ts +68 -0
- package/lib/core/exporter.js +375 -0
- package/lib/core/ghost-sweep.d.ts +19 -0
- package/lib/core/ghost-sweep.js +52 -0
- package/lib/core/importer.d.ts +60 -0
- package/lib/core/importer.js +29 -0
- package/lib/core/index.d.ts +14 -0
- package/lib/core/index.js +14 -0
- package/lib/core/journal.d.ts +197 -0
- package/lib/core/journal.js +418 -0
- package/lib/core/local-plugin-host.d.ts +35 -0
- package/lib/core/local-plugin-host.js +120 -0
- package/lib/core/local-plugin-pack.d.ts +135 -0
- package/lib/core/local-plugin-pack.js +278 -0
- package/lib/core/messages.d.ts +310 -0
- package/lib/core/messages.js +621 -0
- package/lib/core/migration-consult.d.ts +117 -0
- package/lib/core/migration-consult.js +363 -0
- package/lib/core/migration-history.d.ts +153 -0
- package/lib/core/migration-history.js +411 -0
- package/lib/core/model-tools.d.ts +50 -0
- package/lib/core/model-tools.js +148 -0
- package/lib/core/msg-types.d.ts +8 -0
- package/lib/core/msg-types.js +6 -0
- package/lib/core/phase3-child-crash.d.ts +1 -0
- package/lib/core/phase3-child-crash.js +87 -0
- package/lib/core/phase3-host.d.ts +138 -0
- package/lib/core/phase3-host.js +359 -0
- package/lib/core/phase3-prod-child.d.ts +1 -0
- package/lib/core/phase3-prod-child.js +35 -0
- package/lib/core/phase4-crash-child.d.ts +1 -0
- package/lib/core/phase4-crash-child.js +103 -0
- package/lib/core/plugin-cli.d.ts +150 -0
- package/lib/core/plugin-cli.js +497 -0
- package/lib/core/reconcile.d.ts +120 -0
- package/lib/core/reconcile.js +389 -0
- package/lib/core/recovery-orchestrator.d.ts +94 -0
- package/lib/core/recovery-orchestrator.js +327 -0
- package/lib/core/restore.d.ts +162 -0
- package/lib/core/restore.js +703 -0
- package/lib/core/rollback.d.ts +12 -0
- package/lib/core/rollback.js +145 -0
- package/lib/core/run-registry.d.ts +85 -0
- package/lib/core/run-registry.js +157 -0
- package/lib/core/startup-barrier.d.ts +53 -0
- package/lib/core/startup-barrier.js +77 -0
- package/lib/core/types.d.ts +515 -0
- package/lib/core/types.js +27 -0
- package/lib/core/undo.d.ts +73 -0
- package/lib/core/undo.js +87 -0
- package/lib/core/validator.d.ts +18 -0
- package/lib/core/validator.js +77 -0
- package/lib/core/verify-recovery.d.ts +21 -0
- package/lib/core/verify-recovery.js +256 -0
- package/lib/core/watcher.d.ts +101 -0
- package/lib/core/watcher.js +219 -0
- package/lib/index.d.ts +238 -0
- package/lib/index.js +2764 -0
- package/lib/migrations/index.d.ts +29 -0
- package/lib/migrations/index.js +56 -0
- package/lib/migrations/v1-to-v2.d.ts +9 -0
- package/lib/migrations/v1-to-v2.js +10 -0
- package/lib/profiles/index.d.ts +4 -0
- package/lib/profiles/index.js +5 -0
- package/lib/profiles/profile-manager.d.ts +106 -0
- package/lib/profiles/profile-manager.js +543 -0
- package/lib/schema/config.d.ts +28 -0
- package/lib/schema/config.js +165 -0
- package/lib/schema/index.d.ts +24 -0
- package/lib/schema/index.js +26 -0
- package/lib/schema/manifest.d.ts +28 -0
- package/lib/schema/manifest.js +109 -0
- package/lib/schema/tombstones.d.ts +46 -0
- package/lib/schema/tombstones.js +64 -0
- package/lib/schema/types.d.ts +232 -0
- package/lib/schema/types.js +8 -0
- package/lib/schema/versions.d.ts +27 -0
- package/lib/schema/versions.js +50 -0
- package/lib/security/encryption.d.ts +85 -0
- package/lib/security/encryption.js +279 -0
- package/lib/security/index.d.ts +16 -0
- package/lib/security/index.js +17 -0
- package/lib/security/integrity.d.ts +30 -0
- package/lib/security/integrity.js +78 -0
- package/lib/security/redaction.d.ts +26 -0
- package/lib/security/redaction.js +95 -0
- package/lib/security/secret-scanner.d.ts +86 -0
- package/lib/security/secret-scanner.js +404 -0
- package/lib/security/vault.d.ts +59 -0
- package/lib/security/vault.js +151 -0
- package/lib/security/zip-security.d.ts +27 -0
- package/lib/security/zip-security.js +154 -0
- package/lib/sync/autosync-config.d.ts +39 -0
- package/lib/sync/autosync-config.js +151 -0
- package/lib/sync/autosync-scheduler.d.ts +139 -0
- package/lib/sync/autosync-scheduler.js +564 -0
- package/lib/sync/fs.d.ts +18 -0
- package/lib/sync/fs.js +49 -0
- package/lib/sync/git/git-transport.d.ts +100 -0
- package/lib/sync/git/git-transport.js +437 -0
- package/lib/sync/github-auth.d.ts +131 -0
- package/lib/sync/github-auth.js +264 -0
- package/lib/sync/layout.d.ts +43 -0
- package/lib/sync/layout.js +203 -0
- package/lib/sync/snapshot-json.d.ts +9 -0
- package/lib/sync/snapshot-json.js +107 -0
- package/lib/sync/sync-config.d.ts +81 -0
- package/lib/sync/sync-config.js +281 -0
- package/lib/sync/sync-engine.d.ts +269 -0
- package/lib/sync/sync-engine.js +591 -0
- package/lib/sync/sync-history.d.ts +42 -0
- package/lib/sync/sync-history.js +78 -0
- package/lib/sync/sync-selection.d.ts +29 -0
- package/lib/sync/sync-selection.js +127 -0
- package/lib/sync/sync-session.d.ts +40 -0
- package/lib/sync/sync-session.js +54 -0
- package/lib/sync/sync-state.d.ts +37 -0
- package/lib/sync/sync-state.js +108 -0
- package/lib/sync/transport.d.ts +75 -0
- package/lib/sync/transport.js +55 -0
- package/lib/sync/ui-prefs.d.ts +34 -0
- package/lib/sync/ui-prefs.js +109 -0
- package/lib/sync/webdav/webdav-transport.d.ts +77 -0
- package/lib/sync/webdav/webdav-transport.js +451 -0
- package/lib/ui/errors.d.ts +19 -0
- package/lib/ui/errors.js +81 -0
- package/lib/ui/export-flow.d.ts +82 -0
- package/lib/ui/export-flow.js +98 -0
- package/lib/ui/i18n.d.ts +289 -0
- package/lib/ui/i18n.js +581 -0
- package/lib/ui/migration-consult-view.d.ts +91 -0
- package/lib/ui/migration-consult-view.js +115 -0
- package/lib/ui/progress.d.ts +38 -0
- package/lib/ui/progress.js +87 -0
- package/lib/ui/report.d.ts +23 -0
- package/lib/ui/report.js +153 -0
- package/lib/ui/test-helpers.d.ts +69 -0
- package/lib/ui/test-helpers.js +154 -0
- package/lib/ui/types.d.ts +257 -0
- package/lib/ui/types.js +21 -0
- package/lib/utils/atomic-write.d.ts +88 -0
- package/lib/utils/atomic-write.js +399 -0
- package/lib/utils/env-lock.d.ts +393 -0
- package/lib/utils/env-lock.js +930 -0
- package/lib/utils/hashing.d.ts +17 -0
- package/lib/utils/hashing.js +41 -0
- package/lib/utils/json.d.ts +24 -0
- package/lib/utils/json.js +76 -0
- package/lib/utils/logger.d.ts +39 -0
- package/lib/utils/logger.js +82 -0
- package/lib/utils/paths.d.ts +42 -0
- package/lib/utils/paths.js +189 -0
- package/lib/utils/proxy.d.ts +69 -0
- package/lib/utils/proxy.js +455 -0
- package/lib/utils/recursive-walk.d.ts +24 -0
- package/lib/utils/recursive-walk.js +134 -0
- package/lib/utils/zip.d.ts +54 -0
- package/lib/utils/zip.js +285 -0
- package/package.json +188 -0
- package/src/adapters/agent-instructions.ts +48 -0
- package/src/adapters/agent-presets.ts +14 -0
- package/src/adapters/credentials.test.ts +90 -0
- package/src/adapters/credentials.ts +143 -0
- package/src/adapters/file-collection.ts +137 -0
- package/src/adapters/files.test.ts +353 -0
- package/src/adapters/index.ts +94 -0
- package/src/adapters/link-report.test.ts +65 -0
- package/src/adapters/link-report.ts +61 -0
- package/src/adapters/mcp.test.ts +96 -0
- package/src/adapters/mcp.ts +185 -0
- package/src/adapters/plugin-files.ts +146 -0
- package/src/adapters/plugins.test.ts +326 -0
- package/src/adapters/plugins.ts +615 -0
- package/src/adapters/pnpm-workspace.test.ts +87 -0
- package/src/adapters/pnpm-workspace.ts +150 -0
- package/src/adapters/prompts.test.ts +110 -0
- package/src/adapters/prompts.ts +230 -0
- package/src/adapters/providers.test.ts +126 -0
- package/src/adapters/providers.ts +173 -0
- package/src/adapters/roundtrip.test.ts +190 -0
- package/src/adapters/self.test.ts +92 -0
- package/src/adapters/self.ts +75 -0
- package/src/adapters/sessions.ts +15 -0
- package/src/adapters/settings.test.ts +100 -0
- package/src/adapters/settings.ts +187 -0
- package/src/adapters/skills.ts +14 -0
- package/src/adapters/test-helpers.ts +248 -0
- package/src/adapters/ui.test.ts +57 -0
- package/src/adapters/ui.ts +108 -0
- package/src/adapters/workspaces.test.ts +106 -0
- package/src/adapters/workspaces.ts +109 -0
- package/src/client/ConfigManagerSection.tsx +90 -0
- package/src/client/api.ts +66 -0
- package/src/client/client-types.ts +18 -0
- package/src/client/common/ErrorBanner.tsx +73 -0
- package/src/client/common/Icon.tsx +129 -0
- package/src/client/common/Modal.tsx +173 -0
- package/src/client/common/ToastViewport.tsx +73 -0
- package/src/client/common/toast-store.test.ts +192 -0
- package/src/client/common/toast-store.ts +181 -0
- package/src/client/common/toast-types.ts +7 -0
- package/src/client/common/ui.tsx +342 -0
- package/src/client/config-manager.module.css +2971 -0
- package/src/client/css-modules.d.ts +8 -0
- package/src/client/index.ts +65 -0
- package/src/client/locales.ts +56 -0
- package/src/client/lucide-icons.d.ts +38 -0
- package/src/client/run-store.test.ts +223 -0
- package/src/client/run-store.ts +372 -0
- package/src/client/sync/SyncConfirmView.tsx +379 -0
- package/src/client/sync/SyncHistoryView.test.ts +40 -0
- package/src/client/sync/SyncHistoryView.tsx +220 -0
- package/src/client/sync/SyncSettingsView.tsx +1535 -0
- package/src/client/sync/history-model.test.ts +194 -0
- package/src/client/sync/history-model.ts +195 -0
- package/src/client/sync/sync-api.test.ts +585 -0
- package/src/client/sync/sync-api.ts +543 -0
- package/src/client/sync/sync-locales.ts +416 -0
- package/src/client/sync/sync-push-preview.test.ts +52 -0
- package/src/client/sync/sync-view-v2.test.ts +213 -0
- package/src/client/sync/sync-view.test.ts +487 -0
- package/src/client/sync/sync-view.ts +759 -0
- package/src/core/analyzer.ts +1068 -0
- package/src/core/backup.ts +605 -0
- package/src/core/boot-rescue.test.ts +847 -0
- package/src/core/boot-rescue.ts +737 -0
- package/src/core/cache-cleaner.test.ts +169 -0
- package/src/core/cache-cleaner.ts +121 -0
- package/src/core/config-lifecycle.test.ts +727 -0
- package/src/core/config-lifecycle.ts +573 -0
- package/src/core/config-snapshot.test.ts +369 -0
- package/src/core/config-snapshot.ts +522 -0
- package/src/core/config-state.test.ts +381 -0
- package/src/core/config-state.ts +207 -0
- package/src/core/consult-source.test.ts +199 -0
- package/src/core/consult-source.ts +293 -0
- package/src/core/crash-report.test.ts +380 -0
- package/src/core/crash-report.ts +369 -0
- package/src/core/exporter.ts +417 -0
- package/src/core/ghost-sweep.test.ts +94 -0
- package/src/core/ghost-sweep.ts +67 -0
- package/src/core/importer.ts +83 -0
- package/src/core/index.ts +56 -0
- package/src/core/journal.test.ts +257 -0
- package/src/core/journal.ts +518 -0
- package/src/core/local-plugin-host.ts +152 -0
- package/src/core/local-plugin-pack.test.ts +359 -0
- package/src/core/local-plugin-pack.ts +363 -0
- package/src/core/messages.test.ts +54 -0
- package/src/core/messages.ts +664 -0
- package/src/core/migration-consult.test.ts +315 -0
- package/src/core/migration-consult.ts +494 -0
- package/src/core/migration-history.test.ts +319 -0
- package/src/core/migration-history.ts +484 -0
- package/src/core/model-tools.test.ts +190 -0
- package/src/core/model-tools.ts +208 -0
- package/src/core/msg-types.ts +10 -0
- package/src/core/phase3-child-crash.ts +95 -0
- package/src/core/phase3-host.ts +411 -0
- package/src/core/phase3-p1.test.ts +212 -0
- package/src/core/phase3-p2b-fingerprint.test.ts +189 -0
- package/src/core/phase3-prod-child.ts +36 -0
- package/src/core/phase3-production-integration.test.ts +286 -0
- package/src/core/phase4-crash-child.ts +101 -0
- package/src/core/phase4-crash-injection.test.ts +166 -0
- package/src/core/plugin-cli.fs.test.ts +184 -0
- package/src/core/plugin-cli.test.ts +137 -0
- package/src/core/plugin-cli.ts +563 -0
- package/src/core/reconcile.test.ts +392 -0
- package/src/core/reconcile.ts +498 -0
- package/src/core/recovery-orchestrator.test.ts +145 -0
- package/src/core/recovery-orchestrator.ts +366 -0
- package/src/core/restore-manage.test.ts +94 -0
- package/src/core/restore.ts +849 -0
- package/src/core/rollback.ts +151 -0
- package/src/core/run-progress.test.ts +237 -0
- package/src/core/run-registry.test.ts +232 -0
- package/src/core/run-registry.ts +209 -0
- package/src/core/smoke.test.ts +842 -0
- package/src/core/startup-barrier.ts +99 -0
- package/src/core/types.ts +542 -0
- package/src/core/undo.ts +116 -0
- package/src/core/validator.ts +84 -0
- package/src/core/verify-recovery.ts +265 -0
- package/src/core/watcher.test.ts +326 -0
- package/src/core/watcher.ts +263 -0
- package/src/index.facade.test.ts +265 -0
- package/src/index.sync.test.ts +217 -0
- package/src/index.ts +2975 -0
- package/src/migrations/index.ts +71 -0
- package/src/migrations/v1-to-v2.ts +17 -0
- package/src/profiles/index.ts +8 -0
- package/src/profiles/profile-manager.test.ts +282 -0
- package/src/profiles/profile-manager.ts +630 -0
- package/src/schema/config.ts +165 -0
- package/src/schema/index.ts +71 -0
- package/src/schema/manifest-schema.test.ts +519 -0
- package/src/schema/manifest.ts +124 -0
- package/src/schema/tombstones.test.ts +131 -0
- package/src/schema/tombstones.ts +89 -0
- package/src/schema/types.ts +245 -0
- package/src/schema/versions.ts +55 -0
- package/src/security/encryption.ts +335 -0
- package/src/security/index.ts +16 -0
- package/src/security/integrity.ts +102 -0
- package/src/security/redaction.ts +101 -0
- package/src/security/secret-scanner.ts +445 -0
- package/src/security/security.test.ts +1215 -0
- package/src/security/vault.test.ts +164 -0
- package/src/security/vault.ts +198 -0
- package/src/security/zip-security.ts +180 -0
- package/src/sync/autosync-config.test.ts +147 -0
- package/src/sync/autosync-config.ts +179 -0
- package/src/sync/autosync-scheduler.test.ts +490 -0
- package/src/sync/autosync-scheduler.ts +646 -0
- package/src/sync/fs.ts +48 -0
- package/src/sync/git/git-transport.test.ts +673 -0
- package/src/sync/git/git-transport.ts +491 -0
- package/src/sync/github-auth.test.ts +280 -0
- package/src/sync/github-auth.ts +356 -0
- package/src/sync/layout.test.ts +270 -0
- package/src/sync/layout.ts +222 -0
- package/src/sync/snapshot-json.test.ts +119 -0
- package/src/sync/snapshot-json.ts +128 -0
- package/src/sync/sync-config.test.ts +310 -0
- package/src/sync/sync-config.ts +299 -0
- package/src/sync/sync-engine.test.ts +1074 -0
- package/src/sync/sync-engine.ts +754 -0
- package/src/sync/sync-history.test.ts +116 -0
- package/src/sync/sync-history.ts +120 -0
- package/src/sync/sync-selection.test.ts +186 -0
- package/src/sync/sync-selection.ts +143 -0
- package/src/sync/sync-session.test.ts +143 -0
- package/src/sync/sync-session.ts +77 -0
- package/src/sync/sync-state.test.ts +164 -0
- package/src/sync/sync-state.ts +131 -0
- package/src/sync/transport.test.ts +111 -0
- package/src/sync/transport.ts +118 -0
- package/src/sync/ui-prefs.test.ts +152 -0
- package/src/sync/ui-prefs.ts +135 -0
- package/src/sync/webdav/webdav-transport.test.ts +871 -0
- package/src/sync/webdav/webdav-transport.ts +535 -0
- package/src/ui/errors.test.ts +47 -0
- package/src/ui/errors.ts +100 -0
- package/src/ui/export-flow.test.ts +87 -0
- package/src/ui/export-flow.ts +156 -0
- package/src/ui/i18n.ts +590 -0
- package/src/ui/migration-consult-view.test.ts +151 -0
- package/src/ui/migration-consult-view.ts +178 -0
- package/src/ui/progress.test.ts +47 -0
- package/src/ui/progress.ts +102 -0
- package/src/ui/report.test.ts +101 -0
- package/src/ui/report.ts +146 -0
- package/src/ui/test-helpers.ts +184 -0
- package/src/ui/types.ts +325 -0
- package/src/utils/atomic-write.test.ts +312 -0
- package/src/utils/atomic-write.ts +422 -0
- package/src/utils/env-lock.test.ts +999 -0
- package/src/utils/env-lock.ts +1086 -0
- package/src/utils/hashing.ts +53 -0
- package/src/utils/json.ts +77 -0
- package/src/utils/logger.ts +114 -0
- package/src/utils/paths.ts +176 -0
- package/src/utils/proxy.test.ts +465 -0
- package/src/utils/proxy.ts +493 -0
- package/src/utils/recursive-walk.test.ts +148 -0
- package/src/utils/recursive-walk.ts +145 -0
- package/src/utils/zip.ts +332 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-config-manager 浏览器半入口 —— 运行在 dsh web GUI 内。
|
|
3
|
+
* 宽读法改造:仅保留同步设置页与对应字典注册。
|
|
4
|
+
*/
|
|
5
|
+
import type { ClientContext } from './client-types.ts'
|
|
6
|
+
// Type-only:拉入 ctx.locale 的 Context 合并(dsh-client-locale)。
|
|
7
|
+
import type {} from '@deepseek-ai/dsh-client-locale/client'
|
|
8
|
+
// Type-only:拉入 settings.section 的 SlotMap 合并(dsh-client-ui-settings)。
|
|
9
|
+
import type {} from '@deepseek-ai/dsh-client-ui-settings/client'
|
|
10
|
+
// Type-only:拉入 SlotMap / LocaleNamespaceMap 合并表(dsh-client-ui-slots)。
|
|
11
|
+
import type {} from '@deepseek-ai/dsh-client-ui-slots'
|
|
12
|
+
import { ConfigManagerApi } from './api.ts'
|
|
13
|
+
import { ConfigManagerSection } from './ConfigManagerSection.tsx'
|
|
14
|
+
import { en, zh, type ConfigManagerKey } from './locales.ts'
|
|
15
|
+
import { makeUiT, type UiT } from '../ui/i18n.ts'
|
|
16
|
+
import { SyncApi } from './sync/sync-api.ts'
|
|
17
|
+
import { en as syncEn, zh as syncZh, type SyncKey } from './sync/sync-locales.ts'
|
|
18
|
+
|
|
19
|
+
/** 本插件拥有的 locale namespace。 */
|
|
20
|
+
const NS = 'config-manager'
|
|
21
|
+
/** 远程同步设置区块的独立 locale namespace。 */
|
|
22
|
+
const SYNC_NS = 'config-manager-sync'
|
|
23
|
+
|
|
24
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
25
|
+
interface LocaleNamespaceMap {
|
|
26
|
+
/** Config Manager 表面文案。 */
|
|
27
|
+
'config-manager': ConfigManagerKey
|
|
28
|
+
/** 远程同步设置区块文案。 */
|
|
29
|
+
'config-manager-sync': SyncKey
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** 必需服务(fiber inject 等待 —— slots/locale 必须先就绪)。 */
|
|
34
|
+
export const inject = ['slots', 'locale']
|
|
35
|
+
|
|
36
|
+
/** 类型面(导出纪律:除插件契约外无值导出)。 */
|
|
37
|
+
export type { ConfigManagerSectionProps } from './ConfigManagerSection.tsx'
|
|
38
|
+
export type { SyncSettingsViewProps } from './sync/SyncSettingsView.tsx'
|
|
39
|
+
export type { ConfigManagerApiError, ServiceStatus } from './api.ts'
|
|
40
|
+
export type { ConfigManagerKey } from './locales.ts'
|
|
41
|
+
export type { SyncKey } from './sync/sync-locales.ts'
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 注册 Config Manager 设置页。
|
|
45
|
+
* @param ctx - client root context(slots + locale 服务)。
|
|
46
|
+
*/
|
|
47
|
+
export function apply(ctx: ClientContext): void {
|
|
48
|
+
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'config-manager: dictionaries')
|
|
49
|
+
ctx.effect(() => ctx.locale.register(SYNC_NS, { zh: syncZh, en: syncEn }), 'config-manager: sync dictionaries')
|
|
50
|
+
|
|
51
|
+
const t = ctx.locale.bind(NS)
|
|
52
|
+
const uiT: UiT = makeUiT(ctx.locale.getLocale().active === 'en' ? 'en' : 'zh')
|
|
53
|
+
const api = new ConfigManagerApi(uiT)
|
|
54
|
+
const syncT = ctx.locale.bind(SYNC_NS)
|
|
55
|
+
const syncApi = new SyncApi(uiT)
|
|
56
|
+
|
|
57
|
+
ctx.slots.inject('settings.section', () => ctx.slots.register({
|
|
58
|
+
name: 'settings.section',
|
|
59
|
+
id: 'config-manager',
|
|
60
|
+
order: 60,
|
|
61
|
+
label: () => t('section.label'),
|
|
62
|
+
locale: NS,
|
|
63
|
+
inject: () => ({ api, syncApi, syncT }),
|
|
64
|
+
}, ConfigManagerSection))
|
|
65
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Manager 表面文案:zh 为源语言,en 镜像每个键。
|
|
3
|
+
* 字典 namespace 由 client/index.ts 注册(declare module 合并进 LocaleNamespaceMap)。
|
|
4
|
+
* 键集合通过 `ConfigManagerKey` 类型在注册处做编译期校验(缺键/多键即编译错误)。
|
|
5
|
+
* 宽读法精简版:仅保留同步页与基础 Shell/Toast 文案。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const zh = {
|
|
9
|
+
// 入口
|
|
10
|
+
'section.label': '配置同步',
|
|
11
|
+
'section.description': '远程同步 DSH 配置',
|
|
12
|
+
// 视图与导航
|
|
13
|
+
'view.sync': '远程同步',
|
|
14
|
+
'nav.sync': '远程同步',
|
|
15
|
+
// 公共
|
|
16
|
+
'common.close': '关闭',
|
|
17
|
+
'common.cancel': '取消',
|
|
18
|
+
'common.confirm': '确认',
|
|
19
|
+
'common.retry': '重试',
|
|
20
|
+
'common.loading': '加载中…',
|
|
21
|
+
'common.unknownError': '未知错误',
|
|
22
|
+
// 全局通知(右下角 Toast)
|
|
23
|
+
'toast.copied': '已复制到剪贴板',
|
|
24
|
+
'toast.copyFailed': '复制失败,请手动选择文本复制',
|
|
25
|
+
'toast.refreshed': '已刷新',
|
|
26
|
+
// 状态栏
|
|
27
|
+
'shell.status.running': '正在同步({count} 个任务进行中)',
|
|
28
|
+
'shell.status.idle': '就绪',
|
|
29
|
+
'shell.version': 'v{plugin} · DSH {dsh}',
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type ConfigManagerKey = keyof typeof zh
|
|
33
|
+
|
|
34
|
+
export const en: Record<ConfigManagerKey, string> = {
|
|
35
|
+
// Entry
|
|
36
|
+
'section.label': 'Config Sync',
|
|
37
|
+
'section.description': 'Sync DSH configurations remotely',
|
|
38
|
+
// Views & Navigation
|
|
39
|
+
'view.sync': 'Remote Sync',
|
|
40
|
+
'nav.sync': 'Remote Sync',
|
|
41
|
+
// Common
|
|
42
|
+
'common.close': 'Close',
|
|
43
|
+
'common.cancel': 'Cancel',
|
|
44
|
+
'common.confirm': 'Confirm',
|
|
45
|
+
'common.retry': 'Retry',
|
|
46
|
+
'common.loading': 'Loading…',
|
|
47
|
+
'common.unknownError': 'Unknown error',
|
|
48
|
+
// Toasts
|
|
49
|
+
'toast.copied': 'Copied to clipboard',
|
|
50
|
+
'toast.copyFailed': 'Failed to copy, please select text manually',
|
|
51
|
+
'toast.refreshed': 'Refreshed',
|
|
52
|
+
// Status bar
|
|
53
|
+
'shell.status.running': 'Syncing ({count} active task(s))',
|
|
54
|
+
'shell.status.idle': 'Ready',
|
|
55
|
+
'shell.version': 'v{plugin} · DSH {dsh}',
|
|
56
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lucide-react 单图标深路径导入的类型声明(逐图标 tree-shake,详见 Icon.tsx)。
|
|
3
|
+
*
|
|
4
|
+
* 这些 .mjs 深路径无随附类型;NodeNext 下物理文件存在时 TS 不回退通配 ambient,故为每个
|
|
5
|
+
* 用到的图标做精确路径声明。
|
|
6
|
+
*
|
|
7
|
+
* 关键:本文件刻意不含任何顶层 import/export —— 一旦有,文件即变为「模块」,内部的
|
|
8
|
+
* `declare module` 退化为「增量合并(augmentation)」,要求被声明模块已有基础声明;而这些
|
|
9
|
+
* 子路径模块并无基础声明,augmentation 会静默失效(实测恰好部分图标因此报 TS7016)。
|
|
10
|
+
* 保持全局脚本态后,`declare module` 才是真正的全局 ambient 声明,对所有图标一致生效。
|
|
11
|
+
* 图标类型用 lucide 的 ForwardRefExoticComponent 形状内联描述,避免顶层 import。
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
type LucideIconComponent = import('lucide-react').LucideIcon
|
|
15
|
+
|
|
16
|
+
declare module 'lucide-react/dist/esm/icons/arrow-right.mjs' { const i: LucideIconComponent; export default i }
|
|
17
|
+
declare module 'lucide-react/dist/esm/icons/check-circle.mjs' { const i: LucideIconComponent; export default i }
|
|
18
|
+
declare module 'lucide-react/dist/esm/icons/chevron-down.mjs' { const i: LucideIconComponent; export default i }
|
|
19
|
+
declare module 'lucide-react/dist/esm/icons/chevron-right.mjs' { const i: LucideIconComponent; export default i }
|
|
20
|
+
declare module 'lucide-react/dist/esm/icons/clock.mjs' { const i: LucideIconComponent; export default i }
|
|
21
|
+
declare module 'lucide-react/dist/esm/icons/copy.mjs' { const i: LucideIconComponent; export default i }
|
|
22
|
+
declare module 'lucide-react/dist/esm/icons/database-backup.mjs' { const i: LucideIconComponent; export default i }
|
|
23
|
+
declare module 'lucide-react/dist/esm/icons/download.mjs' { const i: LucideIconComponent; export default i }
|
|
24
|
+
declare module 'lucide-react/dist/esm/icons/eye.mjs' { const i: LucideIconComponent; export default i }
|
|
25
|
+
declare module 'lucide-react/dist/esm/icons/folder-input.mjs' { const i: LucideIconComponent; export default i }
|
|
26
|
+
declare module 'lucide-react/dist/esm/icons/hard-drive-download.mjs' { const i: LucideIconComponent; export default i }
|
|
27
|
+
declare module 'lucide-react/dist/esm/icons/info.mjs' { const i: LucideIconComponent; export default i }
|
|
28
|
+
declare module 'lucide-react/dist/esm/icons/message-square.mjs' { const i: LucideIconComponent; export default i }
|
|
29
|
+
declare module 'lucide-react/dist/esm/icons/package-check.mjs' { const i: LucideIconComponent; export default i }
|
|
30
|
+
declare module 'lucide-react/dist/esm/icons/pencil.mjs' { const i: LucideIconComponent; export default i }
|
|
31
|
+
declare module 'lucide-react/dist/esm/icons/refresh-cw.mjs' { const i: LucideIconComponent; export default i }
|
|
32
|
+
declare module 'lucide-react/dist/esm/icons/rotate-cw.mjs' { const i: LucideIconComponent; export default i }
|
|
33
|
+
declare module 'lucide-react/dist/esm/icons/search.mjs' { const i: LucideIconComponent; export default i }
|
|
34
|
+
declare module 'lucide-react/dist/esm/icons/trash-2.mjs' { const i: LucideIconComponent; export default i }
|
|
35
|
+
declare module 'lucide-react/dist/esm/icons/triangle-alert.mjs' { const i: LucideIconComponent; export default i }
|
|
36
|
+
declare module 'lucide-react/dist/esm/icons/upload.mjs' { const i: LucideIconComponent; export default i }
|
|
37
|
+
declare module 'lucide-react/dist/esm/icons/x.mjs' { const i: LucideIconComponent; export default i }
|
|
38
|
+
declare module 'lucide-react/dist/esm/icons/circle-alert.mjs' { const i: LucideIconComponent; export default i }
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* run-store 单测:模块级单例 store + sessionStorage 恢复(同步面板专属)。
|
|
3
|
+
*
|
|
4
|
+
* 覆盖:
|
|
5
|
+
* - 敏感字段(token/webdavPassword/encryptPassword 等)绝不写入 sessionStorage(白名单剔除);
|
|
6
|
+
* - 内存瞬态(busy/savingConfig)不写入 sessionStorage,刷新后复位;
|
|
7
|
+
* - 非敏感状态序列化/反序列化往返(新实例 + 同存储 = 模拟刷新);
|
|
8
|
+
* - 损坏/版本不符数据回退默认并清除脏键;
|
|
9
|
+
* - 旧版顶层 syncMode 载荷向后兼容迁移;
|
|
10
|
+
* - subscribe/notify 语义与 this 绑定回归(useSyncExternalStore 方式)。
|
|
11
|
+
*/
|
|
12
|
+
import test from 'node:test'
|
|
13
|
+
import assert from 'node:assert/strict'
|
|
14
|
+
|
|
15
|
+
import { RunStore, STATE_KEY, type StoreStorage } from './run-store.ts'
|
|
16
|
+
|
|
17
|
+
/* ------------------------------------------------------------- fixtures */
|
|
18
|
+
|
|
19
|
+
function makeStorage(): { storage: StoreStorage; raw: () => string | null } {
|
|
20
|
+
let value: string | null = null
|
|
21
|
+
return {
|
|
22
|
+
storage: {
|
|
23
|
+
getItem: (key: string) => (key === STATE_KEY ? value : null),
|
|
24
|
+
setItem: (key: string, v: string) => {
|
|
25
|
+
if (key === STATE_KEY) value = v
|
|
26
|
+
},
|
|
27
|
+
removeItem: (key: string) => {
|
|
28
|
+
if (key === STATE_KEY) value = null
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
raw: () => value,
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* ---------------------------------------------------------- 序列化白名单 */
|
|
36
|
+
|
|
37
|
+
test('run-store: token 与 webdav 密码绝不写入 sessionStorage', () => {
|
|
38
|
+
const { storage, raw } = makeStorage()
|
|
39
|
+
const store = new RunStore({ storage })
|
|
40
|
+
store.patch({
|
|
41
|
+
sync: {
|
|
42
|
+
channel: 'git',
|
|
43
|
+
repoUrl: 'https://github.com/user/private-sync.git',
|
|
44
|
+
token: 'ghp_SECRET_TOKEN_VALUE',
|
|
45
|
+
webdavUrl: 'https://dav.example.com',
|
|
46
|
+
webdavUsername: 'davuser',
|
|
47
|
+
webdavPassword: 'WEBDAV_SECRET_PASSWORD',
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const text = raw()
|
|
52
|
+
assert.ok(text !== null, 'patch 后已同步持久化')
|
|
53
|
+
assert.ok(!text.includes('ghp_SECRET_TOKEN_VALUE'), 'token 绝不得落盘')
|
|
54
|
+
assert.ok(!text.includes('WEBDAV_SECRET_PASSWORD'), 'webdav 密码绝不得落盘')
|
|
55
|
+
|
|
56
|
+
const parsed = JSON.parse(text) as Record<string, unknown>
|
|
57
|
+
const syncObj = parsed['sync'] as Record<string, unknown>
|
|
58
|
+
assert.ok(!('token' in syncObj), 'token 字段已从持久化剔除')
|
|
59
|
+
assert.ok(!('webdavPassword' in syncObj), 'webdavPassword 字段已从持久化剔除')
|
|
60
|
+
|
|
61
|
+
// 新实例加载时敏感凭据重置为空串
|
|
62
|
+
const reloaded = new RunStore({ storage })
|
|
63
|
+
assert.equal(reloaded.getSnapshot().sync.token, '')
|
|
64
|
+
assert.equal(reloaded.getSnapshot().sync.webdavPassword, '')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('run-store: byChannel 加密解密密码绝不写入 sessionStorage', () => {
|
|
68
|
+
const { storage, raw } = makeStorage()
|
|
69
|
+
const store = new RunStore({ storage })
|
|
70
|
+
store.patch({
|
|
71
|
+
sync: {
|
|
72
|
+
byChannel: {
|
|
73
|
+
git: {
|
|
74
|
+
syncSections: ['settings'],
|
|
75
|
+
syncMode: 'advanced',
|
|
76
|
+
selectedSnapshotId: '',
|
|
77
|
+
autosync: null,
|
|
78
|
+
autosyncEnabled: false,
|
|
79
|
+
autosyncInterval: '60m',
|
|
80
|
+
snapshots: [],
|
|
81
|
+
},
|
|
82
|
+
webdav: {
|
|
83
|
+
syncSections: ['settings', 'skills'],
|
|
84
|
+
syncMode: 'default',
|
|
85
|
+
selectedSnapshotId: '',
|
|
86
|
+
autosync: null,
|
|
87
|
+
autosyncEnabled: true,
|
|
88
|
+
autosyncInterval: '30m',
|
|
89
|
+
snapshots: [],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
const text = raw()
|
|
96
|
+
assert.ok(text !== null)
|
|
97
|
+
|
|
98
|
+
// 刷新后分区选择正确保留(凭据本身走 DSH credentials,不进 UI 状态)
|
|
99
|
+
const reloaded = new RunStore({ storage })
|
|
100
|
+
const snap = reloaded.getSnapshot().sync
|
|
101
|
+
assert.equal('encryptPassword' in snap.byChannel.git, false, 'ChannelSyncState 不再有加密密码字段')
|
|
102
|
+
// 非敏感选项正确保留
|
|
103
|
+
assert.equal(snap.byChannel.git.syncMode, 'advanced')
|
|
104
|
+
assert.deepEqual(snap.byChannel.git.syncSections, ['settings'])
|
|
105
|
+
assert.equal(snap.byChannel.webdav.autosyncEnabled, true)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
test('run-store: busy 与 savingConfig 为内存瞬态——不写入 sessionStorage、刷新后复位', () => {
|
|
109
|
+
const { storage, raw } = makeStorage()
|
|
110
|
+
const first = new RunStore({ storage })
|
|
111
|
+
first.patch({ sync: { busy: 'push', savingConfig: true } })
|
|
112
|
+
|
|
113
|
+
const text = raw()
|
|
114
|
+
assert.ok(text !== null)
|
|
115
|
+
const parsed = JSON.parse(text) as Record<string, unknown>
|
|
116
|
+
const sync = parsed['sync'] as Record<string, unknown>
|
|
117
|
+
assert.ok(!('busy' in sync), 'busy 为瞬态,不得落盘')
|
|
118
|
+
assert.ok(!('savingConfig' in sync), 'savingConfig 为瞬态,不得落盘')
|
|
119
|
+
|
|
120
|
+
// 新实例(模拟刷新):复位为 null 与 false
|
|
121
|
+
const second = new RunStore({ storage })
|
|
122
|
+
assert.equal(second.getSnapshot().sync.busy, null, '刷新后 busy 复位为 null')
|
|
123
|
+
assert.equal(second.getSnapshot().sync.savingConfig, false, '刷新后 savingConfig 复位为 false')
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
test('run-store: 非敏感同步表单状态往返恢复', () => {
|
|
127
|
+
const { storage } = makeStorage()
|
|
128
|
+
const first = new RunStore({ storage })
|
|
129
|
+
first.patch({
|
|
130
|
+
sync: {
|
|
131
|
+
channel: 'webdav',
|
|
132
|
+
webdavUrl: 'https://nextcloud.example.com/remote.php/dav/files/alice',
|
|
133
|
+
webdavUsername: 'alice',
|
|
134
|
+
repoUrl: 'git@github.com:alice/dsh-sync.git',
|
|
135
|
+
lastRestoreId: 'restore-20260919',
|
|
136
|
+
pushPreview: { preview: null, open: true },
|
|
137
|
+
error: '网络波动错误(已脱敏)',
|
|
138
|
+
loadError: '远端连接失败',
|
|
139
|
+
},
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const second = new RunStore({ storage })
|
|
143
|
+
const s = second.getSnapshot().sync
|
|
144
|
+
assert.equal(s.channel, 'webdav')
|
|
145
|
+
assert.equal(s.webdavUrl, 'https://nextcloud.example.com/remote.php/dav/files/alice')
|
|
146
|
+
assert.equal(s.webdavUsername, 'alice')
|
|
147
|
+
assert.equal(s.repoUrl, 'git@github.com:alice/dsh-sync.git')
|
|
148
|
+
assert.equal(s.lastRestoreId, 'restore-20260919')
|
|
149
|
+
assert.equal(s.pushPreview.open, true)
|
|
150
|
+
assert.equal(s.error, '网络波动错误(已脱敏)')
|
|
151
|
+
assert.equal(s.loadError, '远端连接失败')
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
test('run-store: 损坏或版本不符的存储数据回退默认并清除脏键', () => {
|
|
155
|
+
const { storage, raw } = makeStorage()
|
|
156
|
+
storage.setItem(STATE_KEY, 'not valid json')
|
|
157
|
+
|
|
158
|
+
const store = new RunStore({ storage })
|
|
159
|
+
assert.equal(store.getSnapshot().panel, 'sync')
|
|
160
|
+
assert.equal(store.getSnapshot().sync.channel, 'git')
|
|
161
|
+
assert.equal(raw(), null, '损坏键已被清除')
|
|
162
|
+
|
|
163
|
+
// 版本不符
|
|
164
|
+
storage.setItem(STATE_KEY, JSON.stringify({ v: 999, panel: 'sync' }))
|
|
165
|
+
const store2 = new RunStore({ storage })
|
|
166
|
+
assert.equal(store2.getSnapshot().panel, 'sync')
|
|
167
|
+
assert.equal(raw(), null, '旧版本键已被清除')
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
test('run-store: subscribe/notify: patch 触发监听器,退订后不再通知', () => {
|
|
171
|
+
const { storage } = makeStorage()
|
|
172
|
+
const store = new RunStore({ storage })
|
|
173
|
+
let calls = 0
|
|
174
|
+
const unsubscribe = store.subscribe(() => { calls++ })
|
|
175
|
+
|
|
176
|
+
store.patch({ sync: { channel: 'webdav' } })
|
|
177
|
+
assert.equal(calls, 1)
|
|
178
|
+
|
|
179
|
+
store.patch({ sync: { repoUrl: 'https://example.com/repo.git' } })
|
|
180
|
+
assert.equal(calls, 2)
|
|
181
|
+
|
|
182
|
+
unsubscribe()
|
|
183
|
+
store.patch({ sync: { channel: 'git' } })
|
|
184
|
+
assert.equal(calls, 2, '退订后不应再触发')
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
test('run-store: subscribe/getSnapshot 以裸引用调用时 this 绑定实例(useSyncExternalStore 方式)', () => {
|
|
188
|
+
const { storage } = makeStorage()
|
|
189
|
+
const store = new RunStore({ storage })
|
|
190
|
+
const { subscribe, getSnapshot } = store
|
|
191
|
+
|
|
192
|
+
assert.doesNotThrow(() => {
|
|
193
|
+
const snap = getSnapshot()
|
|
194
|
+
assert.equal(snap.panel, 'sync')
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
let count = 0
|
|
198
|
+
const unsub = subscribe(() => { count++ })
|
|
199
|
+
store.patch({ sync: { channel: 'webdav' } })
|
|
200
|
+
assert.equal(count, 1)
|
|
201
|
+
unsub()
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
test('run-store: 旧版顶层 syncMode 载荷 → 迁移为 git 通道的 byChannel 状态', () => {
|
|
205
|
+
const { storage } = makeStorage()
|
|
206
|
+
const legacyPayload = {
|
|
207
|
+
v: 1,
|
|
208
|
+
panel: 'sync',
|
|
209
|
+
sync: {
|
|
210
|
+
channel: 'git',
|
|
211
|
+
repoUrl: 'https://github.com/user/repo.git',
|
|
212
|
+
syncMode: 'advanced',
|
|
213
|
+
syncSections: ['settings', 'skills'],
|
|
214
|
+
byChannel: {},
|
|
215
|
+
},
|
|
216
|
+
}
|
|
217
|
+
storage.setItem(STATE_KEY, JSON.stringify(legacyPayload))
|
|
218
|
+
|
|
219
|
+
const store = new RunStore({ storage })
|
|
220
|
+
const s = store.getSnapshot().sync
|
|
221
|
+
assert.equal(s.byChannel.git.syncMode, 'advanced')
|
|
222
|
+
assert.deepEqual(s.byChannel.git.syncSections, ['settings', 'skills'])
|
|
223
|
+
})
|