@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,515 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 核心引擎契约类型(对齐 Docs/design/architecture.md §13.2/§13.3/§13.5)。
|
|
3
|
+
*
|
|
4
|
+
* 关键解耦原则:核心引擎只依赖这里的接口,绝不 import DSH 运行时包。
|
|
5
|
+
* HostContext 是 m3 定义、m5 实现的 DSH Service 门面(研究报告 §3.2 的叶子方法最小集),
|
|
6
|
+
* 测试用内存 mock 即可驱动完整导出→导入往返。
|
|
7
|
+
*/
|
|
8
|
+
import type { EncryptionInfo, Manifest, SectionId, WorkspaceRecord } from '../schema/types.ts';
|
|
9
|
+
import type { TombstoneKind } from '../schema/tombstones.ts';
|
|
10
|
+
import type { MutationLockPort } from '../utils/env-lock.ts';
|
|
11
|
+
import type { RecursiveListing } from '../utils/recursive-walk.ts';
|
|
12
|
+
import type { Logger } from '../utils/logger.ts';
|
|
13
|
+
import type { MsgFunc } from './messages.ts';
|
|
14
|
+
export interface ExportOptions {
|
|
15
|
+
/** 是否包含真实秘密(必须配合 encryption 提供者;缺省 false = 只导状态) */
|
|
16
|
+
includeSecrets: boolean;
|
|
17
|
+
/** 仅导出指定分区(缺省 = 全部默认包含分区) */
|
|
18
|
+
only?: SectionId[];
|
|
19
|
+
/** 导出文件路径(缺省自动生成 dsh-config-<date>.zip) */
|
|
20
|
+
outPath?: string;
|
|
21
|
+
/** 导出备注(P0-④:host 写入 exports/.backup-notes.json,随 self 分区迁移;非敏感) */
|
|
22
|
+
note?: string;
|
|
23
|
+
}
|
|
24
|
+
/** adapter.export() 的产出:数据 + 文件 + 报告计数 + 告警 */
|
|
25
|
+
export interface ExportSection<T = unknown> {
|
|
26
|
+
sectionId: SectionId;
|
|
27
|
+
data: T;
|
|
28
|
+
/** 文件类分区(skills/agentPresets/pluginFiles/sessions)以真实文件形式进入 ZIP */
|
|
29
|
+
files?: {
|
|
30
|
+
relativePath: string;
|
|
31
|
+
data: Uint8Array;
|
|
32
|
+
}[];
|
|
33
|
+
counts: Record<string, number>;
|
|
34
|
+
warnings: string[];
|
|
35
|
+
}
|
|
36
|
+
export interface ValidationResult {
|
|
37
|
+
valid: boolean;
|
|
38
|
+
issues: {
|
|
39
|
+
path: string;
|
|
40
|
+
message: string;
|
|
41
|
+
severity: 'error' | 'warning';
|
|
42
|
+
}[];
|
|
43
|
+
}
|
|
44
|
+
export interface SensitiveHit {
|
|
45
|
+
path: string;
|
|
46
|
+
field: string;
|
|
47
|
+
}
|
|
48
|
+
export interface SecretScanner {
|
|
49
|
+
/** 递归扫描 + 剥离敏感字段值;返回清洗后的数据与命中清单(不泄值) */
|
|
50
|
+
scanAndRedact(data: unknown): {
|
|
51
|
+
sanitized: unknown;
|
|
52
|
+
hits: SensitiveHit[];
|
|
53
|
+
};
|
|
54
|
+
/** 文本级扫描(文件类分区内容),供强化版使用 */
|
|
55
|
+
scanText?(text: string): SensitiveHit[];
|
|
56
|
+
}
|
|
57
|
+
export interface NamespaceInfo {
|
|
58
|
+
value: unknown;
|
|
59
|
+
base?: unknown;
|
|
60
|
+
revision: number;
|
|
61
|
+
applies?: string[];
|
|
62
|
+
secrets: {
|
|
63
|
+
path: string[];
|
|
64
|
+
set: boolean;
|
|
65
|
+
}[];
|
|
66
|
+
}
|
|
67
|
+
export interface SettingsFacade {
|
|
68
|
+
/** 读某 namespace(redactSecrets 剥离密钥值);返回含乐观锁 revision */
|
|
69
|
+
describe(namespace: string, opts?: {
|
|
70
|
+
redactSecrets?: boolean;
|
|
71
|
+
}): Promise<NamespaceInfo>;
|
|
72
|
+
/** 整体替换(导入/回滚主通道);expectedRevision 不一致时抛 SETTINGS_CONFLICT 类错误 */
|
|
73
|
+
replace(namespace: string, value: unknown, expectedRevision?: number): Promise<void>;
|
|
74
|
+
/** 部分更新(未来 Merge 策略用) */
|
|
75
|
+
update?(namespace: string, patch: unknown, expectedRevision?: number): Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
export interface CredentialsFacade {
|
|
78
|
+
/** 只返回状态,永不返回值 */
|
|
79
|
+
describe(ref: string): Promise<{
|
|
80
|
+
configured: boolean;
|
|
81
|
+
source?: string;
|
|
82
|
+
writable?: boolean;
|
|
83
|
+
}>;
|
|
84
|
+
set(ref: string, value: string): Promise<void>;
|
|
85
|
+
unset(ref: string): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
export interface PluginInfo {
|
|
88
|
+
name: string;
|
|
89
|
+
version: string;
|
|
90
|
+
enabled: boolean;
|
|
91
|
+
isBundle?: boolean;
|
|
92
|
+
inBundles?: string[];
|
|
93
|
+
/** 声明依赖 spec(profile package.json dependencies 原样);文件视图来自 readInstalled */
|
|
94
|
+
spec?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface PluginsFacade {
|
|
97
|
+
listInstalled(): Promise<PluginInfo[]>;
|
|
98
|
+
/** 安装/更新插件;spec 为来源记录的声明依赖 spec(如 github:user/repo),缺省按裸包名装 npm 最新版。
|
|
99
|
+
* signal 可选:中止时宿主应 kill 子进程并清理半装状态(恢复 package.json + 删 node_modules/<pkg>)。 */
|
|
100
|
+
install(pkg: string, spec?: string, signal?: AbortSignal): Promise<{
|
|
101
|
+
needsRestart: boolean;
|
|
102
|
+
}>;
|
|
103
|
+
}
|
|
104
|
+
export interface WorkspaceFacade {
|
|
105
|
+
listRecords(): Promise<WorkspaceRecord[]>;
|
|
106
|
+
writeRecord(record: WorkspaceRecord): Promise<void>;
|
|
107
|
+
removeRecord?(id: string): Promise<void>;
|
|
108
|
+
}
|
|
109
|
+
export interface PatchChange {
|
|
110
|
+
lineId: string;
|
|
111
|
+
raw: unknown;
|
|
112
|
+
action: 'insert' | 'update' | 'remove';
|
|
113
|
+
}
|
|
114
|
+
export interface PatchFileFacade {
|
|
115
|
+
readPatchLines(file: string): Promise<{
|
|
116
|
+
lineId: string;
|
|
117
|
+
raw: unknown;
|
|
118
|
+
}[]>;
|
|
119
|
+
applyPatchChanges(file: string, changes: PatchChange[]): Promise<void>;
|
|
120
|
+
}
|
|
121
|
+
export interface FileSystemFacade {
|
|
122
|
+
readFile(relPath: string): Promise<Uint8Array>;
|
|
123
|
+
writeFile(relPath: string, data: Uint8Array): Promise<void>;
|
|
124
|
+
exists(relPath: string): Promise<boolean>;
|
|
125
|
+
copy(from: string, to: string): Promise<void>;
|
|
126
|
+
remove(relPath: string): Promise<void>;
|
|
127
|
+
listRecursive(dir: string): Promise<string[]>;
|
|
128
|
+
/**
|
|
129
|
+
* 与 listRecursive 相同的遍历,但**跟随**目录 junction / 符号链接,并附带被跳过的链接清单
|
|
130
|
+
* (issue #37)。可选:未实现时调用方回退到 listRecursive(行为与旧版一致)。
|
|
131
|
+
*/
|
|
132
|
+
listRecursiveDetailed?(dir: string): Promise<RecursiveListing>;
|
|
133
|
+
mkdir(dir: string): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
/** DSH 运行时门面:m3 只依赖此接口;m5 用真实 ctx.settings/credentials/… 实现 */
|
|
136
|
+
export interface HostContext {
|
|
137
|
+
platform: string;
|
|
138
|
+
arch: string;
|
|
139
|
+
homeDir: string;
|
|
140
|
+
dshVersion: string;
|
|
141
|
+
log: Logger;
|
|
142
|
+
settings: SettingsFacade;
|
|
143
|
+
credentials: CredentialsFacade;
|
|
144
|
+
plugins: PluginsFacade;
|
|
145
|
+
workspace: WorkspaceFacade;
|
|
146
|
+
patchFile: PatchFileFacade;
|
|
147
|
+
fs: FileSystemFacade;
|
|
148
|
+
/** 当前管理的 DSH profile 名(如 web);引擎用它定位 profiles/<profile>/cordis.patch.yml。宿主不暴露时缺省 */
|
|
149
|
+
profile?: string;
|
|
150
|
+
/**
|
|
151
|
+
* 消息翻译器(zh/en 目录,见 messages.ts)。由宿主按 DSH 应用语言注入;
|
|
152
|
+
* 缺省 zh(改造前行为)。引擎与适配器用它生成所有用户可见动态文案。
|
|
153
|
+
*/
|
|
154
|
+
msg?: MsgFunc;
|
|
155
|
+
/**
|
|
156
|
+
* 跨进程环境锁契约(Phase 2,可选注入)。宿主在构造时注入 GLOBAL EXCLUSIVE MUTATION LOCK
|
|
157
|
+
* 的 port;核心 destructive 入口用 runWithMutationLock(ctx.mutationLock, …) 包住 ——
|
|
158
|
+
* 无有效父 token → acquire(被别的进程/操作持有则抛 EnvironmentLockUnavailableError),
|
|
159
|
+
* 有有效父 token(nested rollback 等)→ reuse,不 reacquire。
|
|
160
|
+
* 测试 mock 缺省不注入 → 无锁环境(不锁定、不抛)。绝不用进程级 reentrancy 判断嵌套。
|
|
161
|
+
*/
|
|
162
|
+
mutationLock?: MutationLockPort;
|
|
163
|
+
/**
|
|
164
|
+
* Phase 3 SAFE MODE:同步谓词(读内存标志),供 runWithMutationLock/withMutationLock 的
|
|
165
|
+
* isBlocked 注入(env-lock 不识 policy)。true → 阻断 destructive。
|
|
166
|
+
*/
|
|
167
|
+
safeModeIsBlocked?: () => boolean;
|
|
168
|
+
/** Phase 3 恢复/事务(JournalStore + reconcile + runJournaled/runExternalIntent)。宿主注入。 */
|
|
169
|
+
phase3Recovery?: import('./phase3-host.ts').Phase3Recovery;
|
|
170
|
+
}
|
|
171
|
+
export type PlanItemKind = 'Create' | 'Update' | 'Skip' | 'Conflict' | 'Install' | 'MissingSecret' | 'MissingDependency' | 'PathMapping' | 'Warning' | 'Error';
|
|
172
|
+
export type ItemResolution = 'keepCurrent' | 'useImported' | 'review';
|
|
173
|
+
export type GlobalConflictStrategy = 'merge' | 'replace' | 'skipExisting';
|
|
174
|
+
export interface ConflictDecision {
|
|
175
|
+
itemId: string;
|
|
176
|
+
resolution: ItemResolution;
|
|
177
|
+
}
|
|
178
|
+
export interface PathMapping {
|
|
179
|
+
oldPrefix: string;
|
|
180
|
+
newPrefix: string;
|
|
181
|
+
appliesTo: ('workspaces' | 'mcp' | 'pluginConfig' | 'skills')[];
|
|
182
|
+
}
|
|
183
|
+
export interface PathIssue {
|
|
184
|
+
kind: 'missing' | 'platformMismatch' | 'homeMismatch';
|
|
185
|
+
value: string;
|
|
186
|
+
mappedTo?: string;
|
|
187
|
+
}
|
|
188
|
+
export interface SnapshotTarget {
|
|
189
|
+
adapter: SectionId;
|
|
190
|
+
ref: string;
|
|
191
|
+
}
|
|
192
|
+
export interface PlanItem {
|
|
193
|
+
id: string;
|
|
194
|
+
kind: PlanItemKind;
|
|
195
|
+
adapter: SectionId;
|
|
196
|
+
description: string;
|
|
197
|
+
detail?: string;
|
|
198
|
+
severity: 'info' | 'warning' | 'error';
|
|
199
|
+
conflict?: ConflictDecision;
|
|
200
|
+
pathMapping?: PathMapping;
|
|
201
|
+
missingDependency?: string;
|
|
202
|
+
target?: SnapshotTarget;
|
|
203
|
+
}
|
|
204
|
+
/** applyItem 结果。warning=true 表示“未应用但属非致命”(如目标路径不可达/需人工映射),
|
|
205
|
+
* 引擎记为警告、不触发失败回滚(§34.17 单项失败不拖垮整体)。 */
|
|
206
|
+
export interface ApplyResult {
|
|
207
|
+
ok: boolean;
|
|
208
|
+
message?: string;
|
|
209
|
+
needsRestart?: boolean;
|
|
210
|
+
warning?: boolean;
|
|
211
|
+
}
|
|
212
|
+
export interface ImportAnalysis {
|
|
213
|
+
valid: boolean;
|
|
214
|
+
errors: string[];
|
|
215
|
+
warnings: string[];
|
|
216
|
+
compatibility: 'excellent' | 'good' | 'partial' | 'unsupported';
|
|
217
|
+
sectionsInZip: SectionId[];
|
|
218
|
+
/**
|
|
219
|
+
* 备份 manifest 声明启用、但**本版本不认识**的分区 id(不在 `SECTION_IDS` 中)。
|
|
220
|
+
*
|
|
221
|
+
* 语义(G-01/G-02/G-03):这些分区的数据被跳过、未导入,且**绝不**计入
|
|
222
|
+
* `missingSections` —— 它们并非「备份声明了但文件缺失」,而是「本插件不认识」。
|
|
223
|
+
*
|
|
224
|
+
* 当前用户可见路径是 `warnings` 里的文案键 `import.unsupportedSections`
|
|
225
|
+
* (导入向导直接渲染 `analysis.warnings`);本字段供第三方实现者与
|
|
226
|
+
* 后续 UI 做结构化展示(例如把「未知分区」与「版本过高」分列)。**尚无 UI 消费点。**
|
|
227
|
+
*/
|
|
228
|
+
unsupportedSections: string[];
|
|
229
|
+
/**
|
|
230
|
+
* 已知分区、但其数据 `version` **高于**本版本支持的 1 → 该分区已被跳过(G-05)。
|
|
231
|
+
*
|
|
232
|
+
* 与 `unsupportedSections` 的区别:那个是「本插件不认识这个分区」,这个是
|
|
233
|
+
* 「认识这个分区,但它来自更新的格式」。两者都只告警、不阻断整个 bundle。
|
|
234
|
+
*
|
|
235
|
+
* 当前用户可见路径是 `warnings` 里的文案键 `import.unsupportedSectionVersion`;
|
|
236
|
+
* 本字段供第三方实现者与后续 UI 与 `unsupportedSections` 分列展示。**尚无 UI 消费点。**
|
|
237
|
+
*/
|
|
238
|
+
unsupportedVersions: {
|
|
239
|
+
section: SectionId;
|
|
240
|
+
version: number;
|
|
241
|
+
}[];
|
|
242
|
+
pluginSummary: {
|
|
243
|
+
installed: number;
|
|
244
|
+
toInstall: number;
|
|
245
|
+
};
|
|
246
|
+
pathIssues: PathIssue[];
|
|
247
|
+
secretCount: number;
|
|
248
|
+
dependencyIssues: {
|
|
249
|
+
item: string;
|
|
250
|
+
dependency: string;
|
|
251
|
+
}[];
|
|
252
|
+
/** 备份是否加密(manifest.security.encrypted):加密备份的凭据必须用解密密码恢复 */
|
|
253
|
+
encrypted: boolean;
|
|
254
|
+
}
|
|
255
|
+
export interface ImportDecisions {
|
|
256
|
+
strategy: GlobalConflictStrategy;
|
|
257
|
+
resolutions: Record<string, ItemResolution>;
|
|
258
|
+
pathMappings: PathMapping[];
|
|
259
|
+
}
|
|
260
|
+
export interface ImportPlan {
|
|
261
|
+
items: PlanItem[];
|
|
262
|
+
globalStrategy: GlobalConflictStrategy;
|
|
263
|
+
pathMappings: PathMapping[];
|
|
264
|
+
missingSecrets: {
|
|
265
|
+
ref: string;
|
|
266
|
+
required: boolean;
|
|
267
|
+
}[];
|
|
268
|
+
needsRestart: boolean;
|
|
269
|
+
estimatedActions: Record<SectionId, number>;
|
|
270
|
+
/** F4:被删除墓碑(tombstone)过滤掉的计划项(缺省/空数组 = 无过滤;UI 据此提示用户) */
|
|
271
|
+
skippedTombstoned?: SkippedTombstone[];
|
|
272
|
+
}
|
|
273
|
+
/** F4:被墓碑过滤的计划项记录(条目级:kind+id;分区级:kind='section',id=分区 id) */
|
|
274
|
+
export interface SkippedTombstone {
|
|
275
|
+
kind: TombstoneKind;
|
|
276
|
+
id: string;
|
|
277
|
+
adapter: SectionId;
|
|
278
|
+
}
|
|
279
|
+
export interface ExecutedItem {
|
|
280
|
+
itemId: string;
|
|
281
|
+
/** warning = 未应用但非致命(目标不可达等),不计入失败、不触发回滚 */
|
|
282
|
+
status: 'ok' | 'skipped' | 'warning' | 'failed';
|
|
283
|
+
message?: string;
|
|
284
|
+
/** 用户主动跳过(导入中点击「跳过当前插件」):status 为 skipped 且此标记为 true。
|
|
285
|
+
* 结果页据此区分「用户跳过」与「引擎跳过」,并提供重试入口。 */
|
|
286
|
+
skippedByUser?: boolean;
|
|
287
|
+
}
|
|
288
|
+
export interface ImportResult {
|
|
289
|
+
ok: boolean;
|
|
290
|
+
executed: ExecutedItem[];
|
|
291
|
+
needsRestart: boolean;
|
|
292
|
+
missingSecrets: string[];
|
|
293
|
+
warnings: string[];
|
|
294
|
+
rollback: RollbackReport | null;
|
|
295
|
+
snapshotId: string | null;
|
|
296
|
+
/** F4:本次导入被删除墓碑过滤掉的条目(缺省/空 = 无过滤;UI 据此提示用户) */
|
|
297
|
+
skippedTombstoned?: SkippedTombstone[];
|
|
298
|
+
}
|
|
299
|
+
export interface ImportContext {
|
|
300
|
+
manifest: Manifest;
|
|
301
|
+
targetPlatform: string;
|
|
302
|
+
/** 目标 DSH 门面(adapter 比较目标状态 / 写入 / 读取数据用) */
|
|
303
|
+
target: HostContext;
|
|
304
|
+
/** 已由 PathMapper 处理后的各分区最终数据(adapter.applyItem 从这取写入内容) */
|
|
305
|
+
sections: Map<SectionId, unknown>;
|
|
306
|
+
pathMappings: PathMapping[];
|
|
307
|
+
resolutions: Record<string, ItemResolution>;
|
|
308
|
+
/** 用户补录的秘密值(仅内存,永不落盘/日志) */
|
|
309
|
+
secretInputs: Record<string, string>;
|
|
310
|
+
decryptedCredentials?: Map<string, string>;
|
|
311
|
+
log: Logger;
|
|
312
|
+
/** 消息翻译器(analyzer 注入;适配器用它生成计划项描述/校验/结果消息) */
|
|
313
|
+
msg: MsgFunc;
|
|
314
|
+
/**
|
|
315
|
+
* 执行日志回调(executeImportPlan 注入;适配器在发出子进程命令等动作时调用)。
|
|
316
|
+
* 行文本只允许非敏感内容(命令/操作摘要),绝不写入密钥/密码/补录值;
|
|
317
|
+
* Dry Run / 分析阶段未注入(undefined),调用方可空调用。
|
|
318
|
+
*/
|
|
319
|
+
onLog?: (line: string) => void;
|
|
320
|
+
/**
|
|
321
|
+
* 当前计划项的中止信号(executeImportPlan 注入;适配器在启动子进程时传给宿主 install)。
|
|
322
|
+
* 用户点击「跳过当前插件」时宿主 abort 该信号 → 子进程被 kill → 该项标记为 user-skipped。
|
|
323
|
+
* 非插件项 / Dry Run 阶段为 undefined。
|
|
324
|
+
*/
|
|
325
|
+
signal?: AbortSignal;
|
|
326
|
+
}
|
|
327
|
+
export type SnapshotEntryKind = 'settingsNamespace' | 'credential' | 'patchLine' | 'file' | 'workspaceRecord';
|
|
328
|
+
export interface SnapshotEntry {
|
|
329
|
+
kind: SnapshotEntryKind;
|
|
330
|
+
adapter: SectionId;
|
|
331
|
+
ref: string;
|
|
332
|
+
/** 原值(credential 条目不含值,仅 existed 标志) */
|
|
333
|
+
before: unknown;
|
|
334
|
+
revision?: number;
|
|
335
|
+
/** file 条目:原文件副本在快照存储中的位置 */
|
|
336
|
+
copiedTo?: string;
|
|
337
|
+
/** credential/file 条目:原目标是否存在 */
|
|
338
|
+
existed?: boolean;
|
|
339
|
+
/** 所属快照 id(file 条目回滚读取 blob 时使用) */
|
|
340
|
+
snapshotId?: string;
|
|
341
|
+
}
|
|
342
|
+
/** 快照生命周期状态(M1 增强;旧快照无此字段,视为未知/兼容) */
|
|
343
|
+
export type SnapshotStatus = 'pending' | 'done' | 'rolled-back';
|
|
344
|
+
/** 快照 readiness(Phase 4):CREATING = 未完成不可用;READY = 已验证可恢复。旧快照无此字段 → LEGACY。 */
|
|
345
|
+
export type SnapshotReadiness = 'CREATING' | 'READY';
|
|
346
|
+
/** 快照完整性 manifest(Phase 4,F1):blob hashes + 破坏性内容 hash。 */
|
|
347
|
+
export interface SnapshotManifest {
|
|
348
|
+
schemaVersion: number;
|
|
349
|
+
snapshotId: string;
|
|
350
|
+
entryCount: number;
|
|
351
|
+
/** blobPath → sha256(blob 完整性) */
|
|
352
|
+
blobHashes: Record<string, string>;
|
|
353
|
+
/** 破坏性内容(entries + hostFileBackups + beforePlugins)的 sha256;稳定(不含 readiness/status) */
|
|
354
|
+
metadataHash: string;
|
|
355
|
+
}
|
|
356
|
+
/** 宿主整文件备份登记(M1):导入前对 $DSH_HOME 关键文件的整文件快照。
|
|
357
|
+
* relPath 相对 $DSH_HOME(如 settings.yaml / cordis.patch.yml / profiles/<p>/cordis.patch.yml),
|
|
358
|
+
* blobPath 为快照内 blob 路径(existed=false 时为空串,表示该文件当时不存在)。 */
|
|
359
|
+
export interface HostFileBackup {
|
|
360
|
+
relPath: string;
|
|
361
|
+
blobPath: string;
|
|
362
|
+
existed: boolean;
|
|
363
|
+
}
|
|
364
|
+
export interface Snapshot {
|
|
365
|
+
id: string;
|
|
366
|
+
createdAt: string;
|
|
367
|
+
sourceZip: string;
|
|
368
|
+
entries: SnapshotEntry[];
|
|
369
|
+
/** 生命周期状态:pending(已生成,导入未完成)/ done(导入成功)/ rolled-back(失败已回滚)。旧快照缺省 */
|
|
370
|
+
status?: SnapshotStatus;
|
|
371
|
+
/** 导入前已安装插件清单(M2 restore 撤销插件时与当前已装对比)。旧快照缺省 */
|
|
372
|
+
beforePlugins?: PluginInfo[];
|
|
373
|
+
/** 宿主整文件备份(settings.yaml / settings.json / cordis.patch.yml / profiles/<p>/cordis.patch.yml)。旧快照缺省 */
|
|
374
|
+
hostFileBackups?: HostFileBackup[];
|
|
375
|
+
/** 置顶标记(P1-⑧):置顶快照在保留清理(自动删最旧)中豁免,需用户手动删除 */
|
|
376
|
+
pinned?: boolean;
|
|
377
|
+
/** 绑定 upgrade operation(journal.operationId ↔ snapshot.operationId) */
|
|
378
|
+
operationId?: string;
|
|
379
|
+
/** 来源操作类型(import/profile-switch/sync-apply/reinstall) */
|
|
380
|
+
operationType?: string;
|
|
381
|
+
/** 环境绑定(journal.environmentFingerprint ↔ snapshot.environmentFingerprint) */
|
|
382
|
+
environmentFingerprint?: string;
|
|
383
|
+
/** ownership epoch(journal.ownerInstanceId ↔ snapshot.ownerInstanceId) */
|
|
384
|
+
ownerInstanceId?: string;
|
|
385
|
+
/** readiness:CREATING = 未完成不可用;READY = 已验证可恢复。旧快照缺省 → LEGACY */
|
|
386
|
+
readiness?: SnapshotReadiness;
|
|
387
|
+
/** 完整性 manifest(blob hashes + 破坏性内容 hash) */
|
|
388
|
+
manifest?: SnapshotManifest;
|
|
389
|
+
}
|
|
390
|
+
/** 快照存储(默认文件实现见 core/backup.ts;测试可用内存实现) */
|
|
391
|
+
export interface SnapshotStore {
|
|
392
|
+
save(snapshot: Snapshot, blobs?: Map<string, Uint8Array>): Promise<string>;
|
|
393
|
+
load(id: string): Promise<Snapshot>;
|
|
394
|
+
readBlob(id: string, blobPath: string): Promise<Uint8Array>;
|
|
395
|
+
/** 标记快照生命周期状态(导入成功→done;失败回滚→rolled-back;持久化由实现负责) */
|
|
396
|
+
updateStatus(id: string, status: SnapshotStatus): Promise<void>;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Phase 4 生产 journal↔snapshot 绑定 context(由宿主注入引擎,引擎在首 destructive side effect 前调用)。
|
|
400
|
+
* 保证「快照 durable+verified 且 journal 已知」先于任何写。结构上兼容 phase3-host 的 JournalRunContext;
|
|
401
|
+
* 这里用最小接口避免 core 引擎依赖 phase3 宿主实现(显式 ctx,无 process-global)。
|
|
402
|
+
*/
|
|
403
|
+
/** 逐计划项 WAL step 记录(P2-B,Phase 8):供 reconcile 判精度。 */
|
|
404
|
+
export interface JournalStepRecord {
|
|
405
|
+
/** 稳定 step id(= plan item id;跨进程稳定)。 */
|
|
406
|
+
id: string;
|
|
407
|
+
adapter: string;
|
|
408
|
+
kind: string;
|
|
409
|
+
/** 目标引用(文件类项 = 绝对目标路径,供 reconcile 指纹判定;非文件项可为空串)。 */
|
|
410
|
+
ref: string;
|
|
411
|
+
/** 外部副作用(非文件项,如 settings/plugins/patchLine)→ reconcile 一律保守。 */
|
|
412
|
+
external: boolean;
|
|
413
|
+
status?: 'planned' | 'done' | 'failed' | 'skipped' | 'attention';
|
|
414
|
+
/** side effect 前目标内容指纹(null = 不可指纹)。 */
|
|
415
|
+
beforeFp?: string | null;
|
|
416
|
+
/** side effect 后重读磁盘指纹(null = 不可指纹)。 */
|
|
417
|
+
afterFp?: string | null;
|
|
418
|
+
/** 该项的结论文案(issue #35:安装失败与「用户跳过」必须可区分)。 */
|
|
419
|
+
message?: string | null;
|
|
420
|
+
}
|
|
421
|
+
export interface TransactionSnapshotContext {
|
|
422
|
+
operationId: string;
|
|
423
|
+
operationType: string;
|
|
424
|
+
environmentFingerprint: string;
|
|
425
|
+
ownerInstanceId: string;
|
|
426
|
+
/** 记录 journal.snapshotId 并推进 SNAPSHOT_CREATED(快照已 durable+verified 后调用)。 */
|
|
427
|
+
bindSnapshot: (snapshotId: string) => Promise<void>;
|
|
428
|
+
/** 首个 destructive side effect 前调用:SNAPSHOT_CREATED→APPLYING。 */
|
|
429
|
+
markApplying: () => Promise<void>;
|
|
430
|
+
/**
|
|
431
|
+
* 逐计划项 WAL(P2-B,可选):记录一个将执行/已执行的 step。
|
|
432
|
+
* 文件类项带 beforeFp/afterFp(可证明);非文件项 external=true(reconcile 维持保守)。
|
|
433
|
+
* 不实现/不传 = 无逐项 journal(opaque intent,保持 Phase 3 行为)。
|
|
434
|
+
*/
|
|
435
|
+
recordStep?: (step: JournalStepRecord) => Promise<void>;
|
|
436
|
+
}
|
|
437
|
+
export interface RollbackReport {
|
|
438
|
+
full: boolean;
|
|
439
|
+
restored: string[];
|
|
440
|
+
failed: {
|
|
441
|
+
item: string;
|
|
442
|
+
reason: string;
|
|
443
|
+
manualHint?: string;
|
|
444
|
+
}[];
|
|
445
|
+
}
|
|
446
|
+
export interface CompatibilityInput {
|
|
447
|
+
sourceDsh: string;
|
|
448
|
+
targetDsh: string;
|
|
449
|
+
sourcePlatform: string;
|
|
450
|
+
targetPlatform: string;
|
|
451
|
+
schemaVersion: number;
|
|
452
|
+
missingSections: SectionId[];
|
|
453
|
+
}
|
|
454
|
+
export type CompatibilityScore = 'excellent' | 'good' | 'partial' | 'unsupported';
|
|
455
|
+
export interface ExportReport {
|
|
456
|
+
included: {
|
|
457
|
+
section: SectionId;
|
|
458
|
+
counts: Record<string, number>;
|
|
459
|
+
}[];
|
|
460
|
+
excluded: SectionId[];
|
|
461
|
+
security: {
|
|
462
|
+
secretsExcluded: boolean;
|
|
463
|
+
containsSecrets: boolean;
|
|
464
|
+
encrypted: boolean;
|
|
465
|
+
redactedHits: number;
|
|
466
|
+
/** 本次导出镜像到本机 vault 的敏感文件数(文件级 vault;0 或缺失 = 未镜像) */
|
|
467
|
+
vaultRefreshed?: number;
|
|
468
|
+
};
|
|
469
|
+
file: {
|
|
470
|
+
name: string;
|
|
471
|
+
sizeBytes: number;
|
|
472
|
+
};
|
|
473
|
+
warnings: string[];
|
|
474
|
+
}
|
|
475
|
+
export type Portability = 'portable' | 'deviceSpecific' | 'platformSpecific';
|
|
476
|
+
export interface ConfigAdapter<TSection = unknown> {
|
|
477
|
+
readonly id: SectionId;
|
|
478
|
+
readonly displayName: string;
|
|
479
|
+
readonly defaultIncluded: boolean;
|
|
480
|
+
readonly portability: Portability;
|
|
481
|
+
/** 读取当前 DSH 该类别配置 → 导出数据(无秘密值) */
|
|
482
|
+
export(ctx: HostContext, options: ExportOptions): Promise<ExportSection<TSection>>;
|
|
483
|
+
/** 分析导入数据与目标 DSH 的差异 → 计划项(纯计算,零写入) */
|
|
484
|
+
analyzeImport(data: TSection, ctx: ImportContext): Promise<PlanItem[]>;
|
|
485
|
+
/** 执行单个计划项(Importer 引擎按阶段调度) */
|
|
486
|
+
applyItem(item: PlanItem, ctx: ImportContext): Promise<ApplyResult>;
|
|
487
|
+
/** 结构校验 */
|
|
488
|
+
validate(data: TSection, msg?: MsgFunc): Promise<ValidationResult>;
|
|
489
|
+
/** 可选:导入前快照(缺省用引擎通用快照) */
|
|
490
|
+
snapshot?(targets: SnapshotTarget[], ctx: HostContext): Promise<SnapshotEntry[]>;
|
|
491
|
+
/** 可选:针对本 adapter 的补偿动作 */
|
|
492
|
+
rollback?(entries: SnapshotEntry[], ctx: HostContext): Promise<void>;
|
|
493
|
+
}
|
|
494
|
+
export interface EncryptionProvider {
|
|
495
|
+
encrypt(plaintext: string): Promise<{
|
|
496
|
+
blob: Uint8Array;
|
|
497
|
+
info: EncryptionInfo;
|
|
498
|
+
}>;
|
|
499
|
+
/** authTag 校验失败必须抛错 */
|
|
500
|
+
decrypt(blob: Uint8Array, info: EncryptionInfo, password: string): Promise<string>;
|
|
501
|
+
}
|
|
502
|
+
/** 导入被确认前拒绝执行(安全阀) */
|
|
503
|
+
export declare class ImportNotConfirmedError extends Error {
|
|
504
|
+
constructor(msg?: MsgFunc);
|
|
505
|
+
}
|
|
506
|
+
/** 导入失败:触发回滚后抛出,携带结果供 UI 展示 */
|
|
507
|
+
export declare class ImportFailedError extends Error {
|
|
508
|
+
readonly result: ImportResult;
|
|
509
|
+
constructor(message: string, result: ImportResult);
|
|
510
|
+
}
|
|
511
|
+
/** 当前计划项被用户跳过(导入中点击「跳过当前插件」中止子进程)。
|
|
512
|
+
* 宿主 install 中止时抛出;引擎在 applyOne 捕获并记为 skipped + skippedByUser。 */
|
|
513
|
+
export declare class ImportUserSkippedError extends Error {
|
|
514
|
+
constructor(msg?: MsgFunc);
|
|
515
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { zhMsg } from './messages.js';
|
|
2
|
+
/* ---------------- 错误类型 ---------------- */
|
|
3
|
+
/** 导入被确认前拒绝执行(安全阀) */
|
|
4
|
+
export class ImportNotConfirmedError extends Error {
|
|
5
|
+
constructor(msg) {
|
|
6
|
+
super((msg ?? zhMsg)('import.notConfirmed'));
|
|
7
|
+
this.name = 'ImportNotConfirmedError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** 导入失败:触发回滚后抛出,携带结果供 UI 展示 */
|
|
11
|
+
export class ImportFailedError extends Error {
|
|
12
|
+
result;
|
|
13
|
+
constructor(message, result) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = 'ImportFailedError';
|
|
16
|
+
this.result = result;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** 当前计划项被用户跳过(导入中点击「跳过当前插件」中止子进程)。
|
|
20
|
+
* 宿主 install 中止时抛出;引擎在 applyOne 捕获并记为 skipped + skippedByUser。 */
|
|
21
|
+
export class ImportUserSkippedError extends Error {
|
|
22
|
+
constructor(msg) {
|
|
23
|
+
super((msg ?? zhMsg)('import.userSkipped'));
|
|
24
|
+
this.name = 'ImportUserSkippedError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 撤销 / 重做语义(Phase 1 P0-2)。
|
|
3
|
+
*
|
|
4
|
+
* 与竞品 dsh-undo-savepoint 的语义对齐(其「撤销不会撤销掉自己」的等价物在本仓库
|
|
5
|
+
* 由两处保证:`pre-restore` 快照自身不参与候选,以及恢复后按内容指纹做回声抑制):
|
|
6
|
+
*
|
|
7
|
+
* 自动快照在变更**之后**采集,因此「最新快照」通常等于当前状态。
|
|
8
|
+
* 真实撤销 = 回退到与当前状态**内容不同**的最新快照(跳过等于当前状态的那些)。
|
|
9
|
+
* 全部相同 → 明确返回「没有可撤销的变化」,而不是做一次空操作。
|
|
10
|
+
*
|
|
11
|
+
* 重做的护栏:撤销时先落一个 `pre-restore` 快照记录「撤销前状态」;
|
|
12
|
+
* 一旦其后产生任何更新的快照(= 用户又改了),重做即失效——避免把用户的
|
|
13
|
+
* 新改动覆盖回旧状态。
|
|
14
|
+
*
|
|
15
|
+
* 本模块是**纯规划**:不读盘、不写盘、不碰 adapter。执行侧见 config-snapshot.ts。
|
|
16
|
+
*/
|
|
17
|
+
import { type ConfigState } from './config-state.ts';
|
|
18
|
+
/** 快照种类。pre-restore 为撤销/还原自身的记账快照,永不作为撤销目标。 */
|
|
19
|
+
export type ConfigSnapshotKind = 'manual' | 'auto' | 'undo' | 'pre-restore' | 'baseline';
|
|
20
|
+
/** 规划所需的最小快照视图(携带其采集到的状态) */
|
|
21
|
+
export interface UndoCandidate {
|
|
22
|
+
id: string;
|
|
23
|
+
createdAt: string;
|
|
24
|
+
kind: ConfigSnapshotKind;
|
|
25
|
+
/** 该快照采集时的配置状态(缺省 = 旧格式快照,无法参与内容比对) */
|
|
26
|
+
state?: ConfigState;
|
|
27
|
+
/** pre-restore 是否已被重做消费 */
|
|
28
|
+
consumed?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export type UndoPlan = {
|
|
31
|
+
kind: 'undo';
|
|
32
|
+
targetId: string;
|
|
33
|
+
skippedNewer: number;
|
|
34
|
+
reason: 'content-differs';
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'none';
|
|
37
|
+
reason: 'no-snapshots' | 'already-at-state';
|
|
38
|
+
};
|
|
39
|
+
export type RedoPlan = {
|
|
40
|
+
kind: 'redo';
|
|
41
|
+
targetId: string;
|
|
42
|
+
reason: 'unconsumed-pre-restore';
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'none';
|
|
45
|
+
reason: 'no-pre-restore' | 'superseded-by-newer-change';
|
|
46
|
+
};
|
|
47
|
+
/** 按 createdAt 倒序(新→旧);同刻按 id 稳定排序保证确定性。 */
|
|
48
|
+
export declare function sortNewestFirst<T extends {
|
|
49
|
+
createdAt: string;
|
|
50
|
+
id: string;
|
|
51
|
+
}>(items: readonly T[]): T[];
|
|
52
|
+
/**
|
|
53
|
+
* 规划一次撤销:返回第一个内容与 current 不同的快照。
|
|
54
|
+
* `skippedNewer` = 跳过的「与当前状态相同」的更新快照数(通常 ≥1,因为自动快照
|
|
55
|
+
* 落在变更之后)。
|
|
56
|
+
*/
|
|
57
|
+
export declare function planUndo(current: ConfigState, snapshots: readonly UndoCandidate[]): UndoPlan;
|
|
58
|
+
/** 是否存在可撤销的变化(供 UI 按钮可用性;等价于 planUndo 是否命中)。 */
|
|
59
|
+
export declare function canUndo(current: ConfigState, snapshots: readonly UndoCandidate[]): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* 规划一次重做:取最新的未消费 pre-restore。
|
|
62
|
+
* 若其后存在任何更新的快照(含未消费的 pre-restore)→ superseded-by-newer-change。
|
|
63
|
+
*/
|
|
64
|
+
export declare function planRedo(snapshots: readonly UndoCandidate[]): RedoPlan;
|
|
65
|
+
/** 是否存在可重做的撤销(供 UI 按钮可用性)。 */
|
|
66
|
+
export declare function canRedo(snapshots: readonly UndoCandidate[]): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* 撤销后需要标记为「已被跨过」的快照 id 列表。
|
|
69
|
+
* 语义:撤销回退到 targetId 之后,比 targetId 更新、且内容等于**撤销前状态**的那些
|
|
70
|
+
* 快照,代表的是被撤销掉的那一步;重做回到撤销前状态后应清除该标记。
|
|
71
|
+
* 返回 targetId 之后(更旧侧不涉及)需要标记的 id。
|
|
72
|
+
*/
|
|
73
|
+
export declare function steppedIds(snapshots: readonly UndoCandidate[], targetId: string, beforeState: ConfigState): string[];
|