@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,154 @@
|
|
|
1
|
+
/** 样本 manifest(UI 测试不关心真实字段,仅类型占位) */
|
|
2
|
+
export function makeManifest() {
|
|
3
|
+
return {
|
|
4
|
+
schemaVersion: 1,
|
|
5
|
+
exporter: { name: 'dsh-config-manager-test', version: '0.0.0' },
|
|
6
|
+
source: { dshVersion: '0.1.0-rc.6', platform: 'win32', arch: 'x64' },
|
|
7
|
+
exportedAt: '2026-08-14T12:00:00.000Z',
|
|
8
|
+
sections: {
|
|
9
|
+
settings: true, ui: false, providers: false, plugins: false, mcp: false, prompts: false,
|
|
10
|
+
skills: false, agentPresets: false, agentInstructions: false, workspaces: false, pluginFiles: false,
|
|
11
|
+
credentialsStatus: false, secrets: false, sessions: false, self: false,
|
|
12
|
+
},
|
|
13
|
+
security: { containsSecrets: false, encrypted: false, encryption: null },
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function makeExportReport(overrides = {}) {
|
|
17
|
+
return {
|
|
18
|
+
included: [
|
|
19
|
+
{ section: 'settings', counts: { namespaces: 3 } },
|
|
20
|
+
{ section: 'plugins', counts: { plugins: 8 } },
|
|
21
|
+
],
|
|
22
|
+
excluded: ['sessions', 'pluginFiles'],
|
|
23
|
+
security: { secretsExcluded: true, containsSecrets: false, encrypted: false, redactedHits: 2 },
|
|
24
|
+
file: { name: 'dsh-config-2026-08-14.zip', sizeBytes: 20480 },
|
|
25
|
+
warnings: [],
|
|
26
|
+
...overrides,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** 内存 ExportPort mock:记录调用参数,返回固定结果 */
|
|
30
|
+
export class MockExportPort {
|
|
31
|
+
calls = [];
|
|
32
|
+
result;
|
|
33
|
+
constructor(report = makeExportReport()) {
|
|
34
|
+
this.result = {
|
|
35
|
+
zipPath: report.file.name,
|
|
36
|
+
manifest: makeManifest(),
|
|
37
|
+
report,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async export(opts) {
|
|
41
|
+
this.calls.push({ includeSecrets: opts.includeSecrets, only: opts.only });
|
|
42
|
+
return this.result;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/* ---------------- Import mock ---------------- */
|
|
46
|
+
export function makeAnalysis(overrides = {}) {
|
|
47
|
+
return {
|
|
48
|
+
valid: true,
|
|
49
|
+
errors: [],
|
|
50
|
+
warnings: [],
|
|
51
|
+
compatibility: 'good',
|
|
52
|
+
sectionsInZip: ['settings', 'plugins', 'mcp', 'prompts'],
|
|
53
|
+
unsupportedSections: [],
|
|
54
|
+
unsupportedVersions: [],
|
|
55
|
+
pluginSummary: { installed: 6, toInstall: 2 },
|
|
56
|
+
pathIssues: [],
|
|
57
|
+
secretCount: 3,
|
|
58
|
+
dependencyIssues: [],
|
|
59
|
+
encrypted: false,
|
|
60
|
+
...overrides,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export function makePlanItem(overrides = {}) {
|
|
64
|
+
return {
|
|
65
|
+
id: 'settings:general',
|
|
66
|
+
kind: 'Create',
|
|
67
|
+
adapter: 'settings',
|
|
68
|
+
description: '创建设置 general',
|
|
69
|
+
severity: 'info',
|
|
70
|
+
...overrides,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function makePlan(overrides = {}) {
|
|
74
|
+
return {
|
|
75
|
+
items: [
|
|
76
|
+
makePlanItem({ id: 'settings:a', kind: 'Update', description: '更新设置 a' }),
|
|
77
|
+
makePlanItem({ id: 'settings:b', kind: 'Create', description: '创建设置 b' }),
|
|
78
|
+
makePlanItem({ id: 'plugin:x', kind: 'Install', adapter: 'plugins', description: '安装插件 x' }),
|
|
79
|
+
makePlanItem({ id: 'plugin:y', kind: 'Skip', adapter: 'plugins', description: '插件 y 已一致' }),
|
|
80
|
+
makePlanItem({ id: 'prompt:p', kind: 'Create', adapter: 'prompts', description: '创建提示 p' }),
|
|
81
|
+
makePlanItem({ id: 'mcp:m', kind: 'Create', adapter: 'mcp', description: '创建 MCP m' }),
|
|
82
|
+
makePlanItem({ id: 'secret:K1', kind: 'MissingSecret', adapter: 'credentialsStatus', description: '凭据 K1 需要补录' }),
|
|
83
|
+
],
|
|
84
|
+
globalStrategy: 'merge',
|
|
85
|
+
pathMappings: [],
|
|
86
|
+
missingSecrets: [{ ref: 'K1', required: true }],
|
|
87
|
+
needsRestart: true,
|
|
88
|
+
estimatedActions: {
|
|
89
|
+
settings: 2, ui: 0, providers: 0, plugins: 1, mcp: 1, prompts: 1,
|
|
90
|
+
skills: 0, agentPresets: 0, agentInstructions: 0, workspaces: 0, pluginFiles: 0,
|
|
91
|
+
credentialsStatus: 0, secrets: 0, sessions: 0, self: 0,
|
|
92
|
+
},
|
|
93
|
+
...overrides,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export function makeRollbackReport(overrides = {}) {
|
|
97
|
+
return {
|
|
98
|
+
full: false,
|
|
99
|
+
restored: ['settings:a'],
|
|
100
|
+
failed: [{ item: 'plugin:x', reason: '安装失败', manualHint: '请手动安装' }],
|
|
101
|
+
...overrides,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export function makeImportResult(overrides = {}) {
|
|
105
|
+
return {
|
|
106
|
+
ok: true,
|
|
107
|
+
executed: [
|
|
108
|
+
{ itemId: 'settings:a', status: 'ok' },
|
|
109
|
+
{ itemId: 'settings:b', status: 'ok' },
|
|
110
|
+
{ itemId: 'plugin:x', status: 'ok', message: '需要重启生效' },
|
|
111
|
+
{ itemId: 'plugin:y', status: 'skipped' },
|
|
112
|
+
{ itemId: 'prompt:p', status: 'ok' },
|
|
113
|
+
{ itemId: 'mcp:m', status: 'ok' },
|
|
114
|
+
{ itemId: 'secret:K1', status: 'skipped', message: '凭据未提供' },
|
|
115
|
+
],
|
|
116
|
+
needsRestart: true,
|
|
117
|
+
missingSecrets: ['K1'],
|
|
118
|
+
warnings: [],
|
|
119
|
+
rollback: null,
|
|
120
|
+
snapshotId: 'snap-1',
|
|
121
|
+
...overrides,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** 内存 ImportPort mock:可编排各阶段返回与调用记录 */
|
|
125
|
+
export class MockImportPort {
|
|
126
|
+
analysis;
|
|
127
|
+
plan;
|
|
128
|
+
result;
|
|
129
|
+
analyzeCalls = 0;
|
|
130
|
+
planCalls = [];
|
|
131
|
+
executeCalls = [];
|
|
132
|
+
constructor(opts = {}) {
|
|
133
|
+
this.analysis = opts.analysis ?? makeAnalysis();
|
|
134
|
+
this.plan = opts.plan ?? makePlan();
|
|
135
|
+
this.result = opts.result ?? makeImportResult();
|
|
136
|
+
}
|
|
137
|
+
async analyzeImport() {
|
|
138
|
+
this.analyzeCalls += 1;
|
|
139
|
+
return this.analysis;
|
|
140
|
+
}
|
|
141
|
+
async createImportPlan(_zip, decisions) {
|
|
142
|
+
this.planCalls.push(decisions);
|
|
143
|
+
return this.plan;
|
|
144
|
+
}
|
|
145
|
+
async decryptArchive(zipPath) {
|
|
146
|
+
// 测试用:把传入路径视为已解锁的明文 ZIP(不真正解密),无内部凭据
|
|
147
|
+
return { zipPath, refs: [] };
|
|
148
|
+
}
|
|
149
|
+
async executeImportPlan(_zip, plan, opts) {
|
|
150
|
+
this.executeCalls.push({ ...opts, plan });
|
|
151
|
+
return this.result;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=test-helpers.js.map
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI 层共享类型(m6-ui,框架无关)。
|
|
3
|
+
*
|
|
4
|
+
* 设计原则(对齐 Docs/design/architecture.md §12.2 与规范 §28/§29):
|
|
5
|
+
* - 本模块为纯 TypeScript 逻辑层,不引入 React / 打包器 / 任何运行时依赖;
|
|
6
|
+
* - 未来 React 客户端(src/client/)直接消费本层的控制器输出(渲染文本 / 状态快照);
|
|
7
|
+
* - UI 层不直接 import core 的类实现,只依赖 core/types.ts 的纯类型 + 注入的「端口」
|
|
8
|
+
* (ExportPort / ImportPort,宿主在 settings.section 挂载时把真实 Exporter/Importer 接入)。
|
|
9
|
+
*/
|
|
10
|
+
import type { SectionId } from '../schema/types.ts';
|
|
11
|
+
import type { CompatibilityScore, ImportAnalysis, ImportDecisions, ImportPlan, ImportResult, ItemResolution, PathIssue, PlanItem, Portability, RollbackReport } from '../core/types.ts';
|
|
12
|
+
export type ExportMode = 'quick' | 'custom';
|
|
13
|
+
/** Custom Export 分组(规范 §1 分类;automation 组在 DSH 中无对应分区,UI 标注说明) */
|
|
14
|
+
export type ExportGroup = 'general' | 'ai' | 'extensions' | 'mcp' | 'customization' | 'automation' | 'workspace' | 'ui' | 'optional';
|
|
15
|
+
/** 分类树节点(与 adapters 的 displayName/defaultIncluded/portability 对齐;宿主可注入覆盖) */
|
|
16
|
+
export interface ExportCategory {
|
|
17
|
+
id: SectionId;
|
|
18
|
+
label: string;
|
|
19
|
+
description: string;
|
|
20
|
+
defaultIncluded: boolean;
|
|
21
|
+
portability: Portability;
|
|
22
|
+
group: ExportGroup;
|
|
23
|
+
/** 涉及秘密状态(如 credentialsStatus):UI 需展示安全提示但绝不显示值 */
|
|
24
|
+
sensitive?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ExportGroupDef {
|
|
27
|
+
id: ExportGroup;
|
|
28
|
+
label: string;
|
|
29
|
+
/** automation 组在 DSH 无对应配置时的说明 */
|
|
30
|
+
note?: string;
|
|
31
|
+
}
|
|
32
|
+
/** Custom Export 分组目录(规范 §1;automation 组 DSH 无对应分区,仅说明) */
|
|
33
|
+
export declare const EXPORT_GROUPS: readonly ExportGroupDef[];
|
|
34
|
+
/** Quick Export 推荐项 = defaultIncluded 且非 deviceSpecific(设计 §11.1) */
|
|
35
|
+
export declare function isQuickRecommended(c: ExportCategory): boolean;
|
|
36
|
+
export interface ProgressEvent {
|
|
37
|
+
/** 阶段 id(见 progress.ts 的 STAGE_TEXTS) */
|
|
38
|
+
stage: string;
|
|
39
|
+
detail?: string;
|
|
40
|
+
/** 阶段序号(从 1 起,供 UI 显示 n/m) */
|
|
41
|
+
step?: number;
|
|
42
|
+
/** 阶段总数 */
|
|
43
|
+
total?: number;
|
|
44
|
+
}
|
|
45
|
+
export type ProgressListener = (event: ProgressEvent) => void;
|
|
46
|
+
export type ImportStep = 'select' | 'analyzing' | 'compatibility' | 'preview' | 'conflicts' | 'path-mapping' | 'secrets' | 'importing' | 'result';
|
|
47
|
+
/** Preview 摘要(规范 §10 示例的数值化版本) */
|
|
48
|
+
export interface ImportPreviewSummary {
|
|
49
|
+
/** 将更新的配置项数(Create+Update+Install 合计) */
|
|
50
|
+
willChange: number;
|
|
51
|
+
/** 已存在且一致的项(Skip) */
|
|
52
|
+
unchanged: number;
|
|
53
|
+
settingsUpdates: number;
|
|
54
|
+
pluginsInstalled: number;
|
|
55
|
+
pluginsToInstall: number;
|
|
56
|
+
mcpAdds: number;
|
|
57
|
+
prompts: number;
|
|
58
|
+
pathMappingsNeeded: number;
|
|
59
|
+
secretsNeeded: number;
|
|
60
|
+
conflicts: number;
|
|
61
|
+
needsRestart: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** 向导状态快照(React 客户端可直接绑定渲染) */
|
|
64
|
+
export interface WizardSnapshot {
|
|
65
|
+
step: ImportStep;
|
|
66
|
+
zipPath: string | null;
|
|
67
|
+
analysis: ImportAnalysis | null;
|
|
68
|
+
plan: ImportPlan | null;
|
|
69
|
+
result: ImportResult | null;
|
|
70
|
+
/** 导入执行的回滚策略(场景 E:默认 true 整体回滚) */
|
|
71
|
+
rollbackOnError: boolean;
|
|
72
|
+
errors: string[];
|
|
73
|
+
}
|
|
74
|
+
/** 单个冲突项的视图数据:当前值 vs 导入值摘要 + 用户决策 */
|
|
75
|
+
export interface ConflictViewItem {
|
|
76
|
+
item: PlanItem;
|
|
77
|
+
currentSummary?: string;
|
|
78
|
+
importedSummary?: string;
|
|
79
|
+
resolution: ItemResolution | null;
|
|
80
|
+
}
|
|
81
|
+
/** 路径映射编辑器的单条记录(旧前缀 → 新前缀;未解析时 newPrefix 为空串) */
|
|
82
|
+
export interface PathMappingDraft {
|
|
83
|
+
/** 关联的原始路径问题值(一条 issue 一条 draft;批量映射用 oldPrefix 聚合) */
|
|
84
|
+
oldPrefix: string;
|
|
85
|
+
newPrefix: string;
|
|
86
|
+
issue?: PathIssue;
|
|
87
|
+
/** 应用范围(缺省 [] = 全部相关分区,与 core applyMappingsToSections 语义一致) */
|
|
88
|
+
appliesTo: PathMappingAppliesTo[];
|
|
89
|
+
}
|
|
90
|
+
/** 与 core PathMapping.appliesTo 对齐的取值(留空数组 = 全应用) */
|
|
91
|
+
export type PathMappingAppliesTo = 'workspaces' | 'mcp' | 'pluginConfig' | 'skills';
|
|
92
|
+
export interface CompatibilityView {
|
|
93
|
+
score: CompatibilityScore;
|
|
94
|
+
sourceDsh: string;
|
|
95
|
+
targetDsh: string;
|
|
96
|
+
description: string;
|
|
97
|
+
}
|
|
98
|
+
/** 导入结果按分区的统计(report.ts 用) */
|
|
99
|
+
export interface ImportSectionStat {
|
|
100
|
+
section: SectionId;
|
|
101
|
+
ok: number;
|
|
102
|
+
skipped: number;
|
|
103
|
+
warned: number;
|
|
104
|
+
failed: number;
|
|
105
|
+
items: {
|
|
106
|
+
itemId: string;
|
|
107
|
+
status: 'ok' | 'skipped' | 'warning' | 'failed';
|
|
108
|
+
message?: string;
|
|
109
|
+
}[];
|
|
110
|
+
}
|
|
111
|
+
export type ImportResultAction = 'fixIssues' | 'viewDetails' | 'done';
|
|
112
|
+
export interface RollbackView {
|
|
113
|
+
report: RollbackReport | null;
|
|
114
|
+
/** 是否有可展示的人工恢复清单(partial 回滚时) */
|
|
115
|
+
hasManualRecovery: boolean;
|
|
116
|
+
}
|
|
117
|
+
/** UI 层与 core 的导入端口(宿主注入真实 Importer;测试注入内存 mock) */
|
|
118
|
+
export interface ImportPort {
|
|
119
|
+
analyzeImport(zipPath: string): Promise<ImportAnalysis>;
|
|
120
|
+
createImportPlan(zipPath: string, decisions: ImportDecisions): Promise<ImportPlan>;
|
|
121
|
+
/**
|
|
122
|
+
* 解锁整体加密备份(只读,零写入):用备份密码解密上传的加密容器,得到明文 ZIP
|
|
123
|
+
* 写入受控临时目录并返回新的 zipPath,供 analyze/plan/execute 引用。
|
|
124
|
+
* 顺带返回解密覆盖的凭据 ref 名(非值)——导出时容器密码与内部 secrets.enc
|
|
125
|
+
* 密码同源,解锁即完成凭据解密验证,无需第二次密码校验。
|
|
126
|
+
* 密码仅内存,绝不落盘/落日志;解密后的明文 ZIP 亦为临时文件,导入结束后清理。
|
|
127
|
+
*/
|
|
128
|
+
decryptArchive(zipPath: string, password: string): Promise<{
|
|
129
|
+
zipPath: string;
|
|
130
|
+
refs: string[];
|
|
131
|
+
}>;
|
|
132
|
+
executeImportPlan(zipPath: string, plan: ImportPlan, opts: {
|
|
133
|
+
/** 用户确认(安全阀,非 true 拒绝执行) */
|
|
134
|
+
confirm: boolean;
|
|
135
|
+
secretInputs?: Record<string, string>;
|
|
136
|
+
/** 显式回滚策略:true=任一项失败整体回滚(场景 E);false=单项失败继续(§34.17) */
|
|
137
|
+
rollbackOnError: boolean;
|
|
138
|
+
/** 加密备份的解密密码(仅内存;core 拒绝加密备份无密码执行) */
|
|
139
|
+
decryptPassword?: string;
|
|
140
|
+
}): Promise<ImportResult>;
|
|
141
|
+
}
|
|
142
|
+
/** 选项构造辅助:从 PlanItem 提取稳定决策键(与 core analyzer.applyItemResolution 的 id 语义一致) */
|
|
143
|
+
export declare function itemDecisionKey(item: PlanItem): string;
|
|
144
|
+
/** recovery 决策(§5.2):rollback-recommended=恢复到 trusted snapshot;rollback-continue=续跑中断回滚;needs-attention=需人工调查。 */
|
|
145
|
+
export type RecoveryDecision = 'rollback-recommended' | 'rollback-continue' | 'needs-attention';
|
|
146
|
+
/** post-recovery verification verdict(§6.3)。 */
|
|
147
|
+
export type RecoveryVerdict = 'MATCH' | 'PARTIAL_MATCH' | 'MISMATCH' | 'VERIFICATION_ERROR';
|
|
148
|
+
/** GET /recovery/status 的单个 incident(未解决 operation)。 */
|
|
149
|
+
export interface RecoveryIncident {
|
|
150
|
+
operationId: string;
|
|
151
|
+
operationType: string;
|
|
152
|
+
state: string;
|
|
153
|
+
decision: RecoveryDecision;
|
|
154
|
+
snapshotId: string | null;
|
|
155
|
+
/** 已 redact 的原因文本。 */
|
|
156
|
+
reason: string;
|
|
157
|
+
createdAt: string;
|
|
158
|
+
}
|
|
159
|
+
/** GET /recovery/status 响应。 */
|
|
160
|
+
export interface RecoveryStatus {
|
|
161
|
+
incidents: RecoveryIncident[];
|
|
162
|
+
running: {
|
|
163
|
+
runId: string;
|
|
164
|
+
status: string;
|
|
165
|
+
}[];
|
|
166
|
+
/**
|
|
167
|
+
* 环境锁状态摘要(issue #31)。纯残留锁**不是** journal:进程在 op 期间被杀时
|
|
168
|
+
* `journalId: null`、`transactions/active/` 为空,incidents 恒为 [],而 423 文案却
|
|
169
|
+
* 让用户去「事故恢复」处理 → 面板恒空、GUI 无出路。本字段让面板能显示可执行的锁事项。
|
|
170
|
+
* 旧宿主不返回 → undefined(面板按「无锁事项」处理,不误报)。
|
|
171
|
+
*/
|
|
172
|
+
lock?: RecoveryLockStatus;
|
|
173
|
+
}
|
|
174
|
+
/** 环境锁状态摘要:**只暴露分类**(owner pid/op/hostname 属内部诊断,不进 UI/响应体)。 */
|
|
175
|
+
export interface RecoveryLockStatus {
|
|
176
|
+
/** LockState:STALE_LOCK_DETECTED / UNKNOWN_STATE / LOCKED / FREE / LOCK_IO_ERROR / PERMISSION_ERROR */
|
|
177
|
+
state: string;
|
|
178
|
+
/** 是否需用户显式处理(残留锁/无法判定)。LOCKED 活锁为 false —— 它会自行释放,不该催用户回收。 */
|
|
179
|
+
attention: boolean;
|
|
180
|
+
}
|
|
181
|
+
/** POST /recovery/lock/recover 响应(显式回收 stale 残留锁;拒绝时 ok=false)。 */
|
|
182
|
+
export interface RecoveryLockRecoverResult {
|
|
183
|
+
ok: boolean;
|
|
184
|
+
removed: boolean;
|
|
185
|
+
state: string;
|
|
186
|
+
}
|
|
187
|
+
/** GET /recovery/:operationId/preview 响应(只读,零写入)。 */
|
|
188
|
+
export interface RecoveryPreview {
|
|
189
|
+
operationId: string;
|
|
190
|
+
operationType: string;
|
|
191
|
+
state: string;
|
|
192
|
+
decision: RecoveryDecision;
|
|
193
|
+
snapshotId: string | null;
|
|
194
|
+
snapshotVerdict: string | null;
|
|
195
|
+
snapshotMeta: {
|
|
196
|
+
id: string;
|
|
197
|
+
createdAt: string;
|
|
198
|
+
operationType?: string;
|
|
199
|
+
} | null;
|
|
200
|
+
environmentFingerprint: string;
|
|
201
|
+
environmentCompatible: boolean;
|
|
202
|
+
reason: string;
|
|
203
|
+
createdAt: string;
|
|
204
|
+
}
|
|
205
|
+
/** POST /recovery/:operationId/verify 响应。 */
|
|
206
|
+
export interface RecoveryVerifyResult {
|
|
207
|
+
ok: boolean;
|
|
208
|
+
operationId: string;
|
|
209
|
+
verdict: RecoveryVerdict;
|
|
210
|
+
terminal: string;
|
|
211
|
+
/** 每项检查结果(已 redact)。 */
|
|
212
|
+
details: string[];
|
|
213
|
+
/** 需人工处理项(已 redact)。 */
|
|
214
|
+
manualHints: string[];
|
|
215
|
+
}
|
|
216
|
+
/** POST /recovery/:operationId/execute|retry 响应。 */
|
|
217
|
+
export interface RecoveryExecuteResult {
|
|
218
|
+
ok: boolean;
|
|
219
|
+
operationId: string;
|
|
220
|
+
decision: RecoveryDecision;
|
|
221
|
+
state: string;
|
|
222
|
+
runId: string;
|
|
223
|
+
}
|
|
224
|
+
/** POST /recovery/:operationId/confirm 响应。 */
|
|
225
|
+
export interface RecoveryConfirmResult {
|
|
226
|
+
ok: boolean;
|
|
227
|
+
operationId: string;
|
|
228
|
+
snapshotId: string;
|
|
229
|
+
verdict: string;
|
|
230
|
+
}
|
|
231
|
+
/** POST /recovery/:operationId/dismiss 响应。 */
|
|
232
|
+
export interface RecoveryDismissResult {
|
|
233
|
+
ok: boolean;
|
|
234
|
+
operationId: string;
|
|
235
|
+
dismissed: boolean;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Recovery 端口契约(§10.3):recovery 无现有 port(ExportPort/ImportPort 只服务控制器)。
|
|
239
|
+
* `recovery-api.ts` 实现之;`recovery-view.ts` 是纯渲染模型(非控制器),消费本端口返回的渲染数据。
|
|
240
|
+
* 安全:所有 destructive 动作(confirm/execute/retry/dismiss)必须显式传 userConfirmed=true,
|
|
241
|
+
* 由 Host 侧双重校验(请求体 + journal 状态机)。
|
|
242
|
+
*/
|
|
243
|
+
export interface RecoveryPort {
|
|
244
|
+
status(): Promise<RecoveryStatus>;
|
|
245
|
+
preview(operationId: string): Promise<RecoveryPreview>;
|
|
246
|
+
confirm(operationId: string, userConfirmed: boolean): Promise<RecoveryConfirmResult>;
|
|
247
|
+
execute(operationId: string, userConfirmed: boolean): Promise<RecoveryExecuteResult>;
|
|
248
|
+
verify(operationId: string): Promise<RecoveryVerifyResult>;
|
|
249
|
+
retry(operationId: string, userConfirmed: boolean): Promise<RecoveryExecuteResult>;
|
|
250
|
+
dismiss(operationId: string, userConfirmed: boolean): Promise<RecoveryDismissResult>;
|
|
251
|
+
/**
|
|
252
|
+
* POST /recovery/lock/recover(issue #31):显式回收 stale 残留配置锁。
|
|
253
|
+
* 不带 operationId(残留锁没有 journal);宿主侧会重新证明确属 stale 才回收,
|
|
254
|
+
* 无法证明(活锁/判定不确定/二次验证失败)→ 返回 ok=false 且不做任何改动。
|
|
255
|
+
*/
|
|
256
|
+
recoverStaleLock(userConfirmed: boolean): Promise<RecoveryLockRecoverResult>;
|
|
257
|
+
}
|
package/lib/ui/types.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Custom Export 分组目录(规范 §1;automation 组 DSH 无对应分区,仅说明) */
|
|
2
|
+
export const EXPORT_GROUPS = [
|
|
3
|
+
{ id: 'general', label: 'General' },
|
|
4
|
+
{ id: 'ai', label: 'AI' },
|
|
5
|
+
{ id: 'extensions', label: 'Extensions' },
|
|
6
|
+
{ id: 'mcp', label: 'MCP / Tools' },
|
|
7
|
+
{ id: 'customization', label: 'Customization' },
|
|
8
|
+
{ id: 'automation', label: 'Automation', note: 'DSH 当前无 Workflows / Commands 配置文件(运行时注册),无迁移内容' },
|
|
9
|
+
{ id: 'workspace', label: 'Workspace' },
|
|
10
|
+
{ id: 'ui', label: 'UI' },
|
|
11
|
+
{ id: 'optional', label: 'Optional Data' },
|
|
12
|
+
];
|
|
13
|
+
/** Quick Export 推荐项 = defaultIncluded 且非 deviceSpecific(设计 §11.1) */
|
|
14
|
+
export function isQuickRecommended(c) {
|
|
15
|
+
return c.defaultIncluded && c.portability !== 'deviceSpecific';
|
|
16
|
+
}
|
|
17
|
+
/** 选项构造辅助:从 PlanItem 提取稳定决策键(与 core analyzer.applyItemResolution 的 id 语义一致) */
|
|
18
|
+
export function itemDecisionKey(item) {
|
|
19
|
+
return item.id;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** 文件句柄最小面(node fs/promises FileHandle 的子集) */
|
|
2
|
+
export interface AtomicHandle {
|
|
3
|
+
writeFile(data: Uint8Array): Promise<void>;
|
|
4
|
+
sync(): Promise<void>;
|
|
5
|
+
close(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
/** 可注入异步文件系统门面(默认实现包 node:fs/promises;测试注入失败点) */
|
|
8
|
+
export interface AtomicIo {
|
|
9
|
+
mkdir(dir: string, opts: {
|
|
10
|
+
recursive: boolean;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
/** 目标不存在返回 null */
|
|
13
|
+
lstat(p: string): Promise<{
|
|
14
|
+
isSymbolicLink(): boolean;
|
|
15
|
+
} | null>;
|
|
16
|
+
/** 目标不存在返回 null */
|
|
17
|
+
stat(p: string): Promise<{
|
|
18
|
+
mode: number;
|
|
19
|
+
} | null>;
|
|
20
|
+
realpath(p: string): Promise<string>;
|
|
21
|
+
open(p: string, flags: string, mode?: number): Promise<AtomicHandle>;
|
|
22
|
+
rename(src: string, dst: string): Promise<void>;
|
|
23
|
+
unlink(p: string): Promise<void>;
|
|
24
|
+
copyFile(src: string, dst: string, mode?: number): Promise<void>;
|
|
25
|
+
chmod(p: string, mode: number): Promise<void>;
|
|
26
|
+
/** 父目录 fsync(POSIX strong durability);Windows/不支持时静默 no-op */
|
|
27
|
+
fsyncDir(p: string): Promise<void>;
|
|
28
|
+
/** 重试退避(可注入便于测试) */
|
|
29
|
+
sleep(ms: number): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/** 同步版注入面(atomicWriteFileSync 用;仅 plugin-cli 等同步路径) */
|
|
32
|
+
export interface AtomicIoSync {
|
|
33
|
+
mkdir(dir: string, opts: {
|
|
34
|
+
recursive: boolean;
|
|
35
|
+
}): void;
|
|
36
|
+
lstat(p: string): {
|
|
37
|
+
isSymbolicLink(): boolean;
|
|
38
|
+
mode: number;
|
|
39
|
+
} | null;
|
|
40
|
+
realpath(p: string): string;
|
|
41
|
+
open(p: string, flags: string, mode?: number): number;
|
|
42
|
+
writeFd(fd: number, buf: Uint8Array): void;
|
|
43
|
+
fsyncFd(fd: number): void;
|
|
44
|
+
closeFd(fd: number): void;
|
|
45
|
+
rename(src: string, dst: string): void;
|
|
46
|
+
unlink(p: string): void;
|
|
47
|
+
/** 目录 fsync(POSIX);Windows/不支持时 no-op */
|
|
48
|
+
fsyncDir(p: string): void;
|
|
49
|
+
}
|
|
50
|
+
export type SymlinkPolicy = 'follow' | 'reject';
|
|
51
|
+
export interface AtomicWriteOptions {
|
|
52
|
+
/** 新文件权限;sensitive 调用显式 0o600 */
|
|
53
|
+
mode?: number;
|
|
54
|
+
/** 默认 true:目标存在则继承其 mode */
|
|
55
|
+
preserveMode?: boolean;
|
|
56
|
+
/** Windows / 目标被占用瞬时错误重试次数(默认 3) */
|
|
57
|
+
retries?: number;
|
|
58
|
+
/** 重试退避基数 ms(默认 25,翻倍递增:25→50→100) */
|
|
59
|
+
retryDelayMs?: number;
|
|
60
|
+
/** POSIX 是否 fsync 父目录(默认 true;Windows 自动跳过) */
|
|
61
|
+
fsyncDir?: boolean;
|
|
62
|
+
/** symlink 策略:默认 'follow';sensitive 调用传 'reject' */
|
|
63
|
+
symlink?: SymlinkPolicy;
|
|
64
|
+
/** 测试注入的异步 io */
|
|
65
|
+
io?: AtomicIo;
|
|
66
|
+
/** tmp 清理失败回调(调用方接线日志,满足「清理失败留痕」要求) */
|
|
67
|
+
onCleanupFailure?: (tmp: string, err: unknown) => void;
|
|
68
|
+
}
|
|
69
|
+
export interface AtomicWriteSyncOptions extends Omit<AtomicWriteOptions, 'io'> {
|
|
70
|
+
syncIo?: AtomicIoSync;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* tmp 名中 base 片段清洗:拒绝含 路径分隔符 / .. / 反斜杠 / 控制字符 / Windows 非法字符 的
|
|
74
|
+
* 目标 basename,防止恶意 base 把 tmp 引出目标目录。返回安全 base。
|
|
75
|
+
*/
|
|
76
|
+
export declare function sanitizeTmpBase(base: string): string;
|
|
77
|
+
/**
|
|
78
|
+
* 原子写文件:同目录唯一 tmp → 写完整内容 → fsync(tmp) → rename(tmp, target)。
|
|
79
|
+
* 失败时不改写原 target(目标要么旧完整、要么新完整)。
|
|
80
|
+
*/
|
|
81
|
+
export declare function atomicWriteFile(target: string, data: string | Uint8Array, rawOpts?: AtomicWriteOptions): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* 原子拷贝:copyFile(src→tmp) + fsync(tmp) + rename(tmp, dst)。
|
|
84
|
+
* 不整文件读内存(大 snapshot/session 避免双内存)。失败不改写 dst。
|
|
85
|
+
*/
|
|
86
|
+
export declare function atomicCopyFile(src: string, dst: string, rawOpts?: AtomicWriteOptions): Promise<void>;
|
|
87
|
+
/** 同步版原子写(plugin-cli 等同步路径)。语义与 atomicWriteFile 一致。 */
|
|
88
|
+
export declare function atomicWriteFileSync(target: string, data: string | Uint8Array, rawOpts?: AtomicWriteSyncOptions): void;
|