dsh-config-manager 0.1.71 → 0.1.73
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/README.md +149 -98
- package/README.zh-CN.md +245 -88
- package/lib/adapters/agent-instructions.js +1 -1
- package/lib/adapters/file-collection.js +1 -1
- package/lib/adapters/index.d.ts +2 -1
- package/lib/adapters/index.js +6 -1
- package/lib/adapters/link-report.d.ts +1 -0
- package/lib/adapters/link-report.js +27 -3
- package/lib/adapters/messages.d.ts +21 -0
- package/lib/adapters/messages.js +57 -0
- package/lib/adapters/plugin-data.d.ts +114 -0
- package/lib/adapters/plugin-data.js +309 -0
- package/lib/adapters/plugin-files.js +3 -2
- package/lib/adapters/plugins.js +4 -3
- package/lib/adapters/prompts.d.ts +1 -0
- package/lib/adapters/prompts.js +7 -1
- package/lib/adapters/self.d.ts +8 -2
- package/lib/adapters/self.js +3 -2
- package/lib/adapters/sessions.d.ts +1 -0
- package/lib/adapters/sessions.js +4 -2
- package/lib/adapters/test-helpers.d.ts +9 -0
- package/lib/adapters/test-helpers.js +14 -0
- package/lib/adapters/ui.d.ts +2 -2
- package/lib/adapters/ui.js +25 -25
- package/lib/adapters/workspaces.d.ts +1 -0
- package/lib/adapters/workspaces.js +7 -3
- package/lib/cli/actions.d.ts +9 -1
- package/lib/cli/actions.js +5 -2
- package/lib/cli/help.js +23 -10
- package/lib/cli/index.d.ts +23 -0
- package/lib/cli/index.js +90 -32
- package/lib/cli/sessions-inspect.js +3 -1
- package/lib/cli/sessions-repair.js +25 -6
- package/lib/cli/web/page.d.ts +12 -0
- package/lib/cli/web/page.js +21 -12
- package/lib/cli/web/routes.js +2 -2
- package/lib/cli/web/server.js +4 -4
- package/lib/client.d.ts +1442 -494
- package/lib/client.js +15326 -8520
- package/lib/core/analyzer.d.ts +11 -2
- package/lib/core/analyzer.js +31 -8
- package/lib/core/backup-plan.d.ts +10 -0
- package/lib/core/backup-plan.js +51 -20
- package/lib/core/backup-verify.js +24 -23
- package/lib/core/backup.d.ts +25 -1
- package/lib/core/backup.js +99 -28
- package/lib/core/boot-rescue.js +4 -3
- package/lib/core/boot-safety.js +2 -1
- package/lib/core/command-rollback.d.ts +182 -0
- package/lib/core/command-rollback.js +293 -0
- package/lib/core/consult-source.js +7 -6
- package/lib/core/disk-usage.d.ts +74 -10
- package/lib/core/disk-usage.js +67 -4
- package/lib/core/engine-locale.d.ts +87 -0
- package/lib/core/engine-locale.js +125 -0
- package/lib/core/exporter.js +3 -3
- package/lib/core/fork-reconcile.d.ts +128 -0
- package/lib/core/fork-reconcile.js +150 -0
- package/lib/core/journal.js +6 -5
- package/lib/core/local-plugin-host.js +3 -2
- package/lib/core/local-plugin-pack.js +11 -6
- package/lib/core/messages-core.d.ts +294 -0
- package/lib/core/messages-core.js +619 -0
- package/lib/core/messages.d.ts +61 -2
- package/lib/core/messages.js +118 -13
- package/lib/core/migration-consult.js +21 -20
- package/lib/core/migration-history.js +19 -5
- package/lib/core/model-tools.d.ts +0 -22
- package/lib/core/model-tools.js +50 -27
- package/lib/core/phase3-host.js +30 -5
- package/lib/core/plugin-cli.js +18 -19
- package/lib/core/plugin-data-registry.d.ts +124 -0
- package/lib/core/plugin-data-registry.js +198 -0
- package/lib/core/reconcile.d.ts +2 -14
- package/lib/core/reconcile.js +87 -17
- package/lib/core/recovery-orchestrator.js +19 -18
- package/lib/core/reinstall.d.ts +4 -0
- package/lib/core/reinstall.js +26 -21
- package/lib/core/restore.js +20 -17
- package/lib/core/rollback-gate.d.ts +33 -0
- package/lib/core/rollback-gate.js +57 -0
- package/lib/core/rollback-ignore-rules.d.ts +31 -0
- package/lib/core/rollback-ignore-rules.js +140 -0
- package/lib/core/rollback-ledger.d.ts +248 -0
- package/lib/core/rollback-ledger.js +1282 -0
- package/lib/core/rollback-point.d.ts +1391 -0
- package/lib/core/rollback-point.js +3503 -0
- package/lib/core/rollback.js +6 -4
- package/lib/core/run-registry.js +6 -5
- package/lib/core/session-health.d.ts +15 -0
- package/lib/core/session-meta.d.ts +42 -2
- package/lib/core/session-meta.js +140 -1
- package/lib/core/session-title.d.ts +28 -0
- package/lib/core/session-title.js +185 -0
- package/lib/core/startup-barrier.d.ts +24 -0
- package/lib/core/startup-barrier.js +22 -0
- package/lib/core/transaction-coordinator.js +4 -3
- package/lib/core/types.d.ts +37 -1
- package/lib/core/validator.js +5 -4
- package/lib/core/verify-recovery.js +31 -30
- package/lib/foreign/bundle.js +3 -2
- package/lib/foreign/continue.js +2 -1
- package/lib/foreign/crush.js +2 -1
- package/lib/foreign/gemini.js +2 -1
- package/lib/foreign/goose.js +2 -1
- package/lib/foreign/kilocode.js +2 -1
- package/lib/foreign/kimi.js +2 -1
- package/lib/foreign/messages.d.ts +15 -0
- package/lib/foreign/messages.js +40 -0
- package/lib/foreign/mimocode.js +2 -1
- package/lib/foreign/openclaw.js +2 -1
- package/lib/foreign/opencode.js +2 -1
- package/lib/foreign/pi.js +2 -1
- package/lib/foreign/qoder.js +2 -1
- package/lib/foreign/qwen.js +2 -1
- package/lib/foreign/registry.d.ts +1 -1
- package/lib/foreign/registry.js +8 -7
- package/lib/foreign/teleagent.js +2 -1
- package/lib/foreign/workbuddy.js +2 -1
- package/lib/foreign/zcode.js +2 -1
- package/lib/foreign/zed.js +2 -1
- package/lib/index.d.ts +227 -7
- package/lib/index.js +799 -54
- package/lib/market/git-file-writer.js +20 -19
- package/lib/market/github-repos.js +35 -19
- package/lib/market/index-parser.js +31 -30
- package/lib/market/messages-market.d.ts +138 -0
- package/lib/market/messages-market.js +305 -0
- package/lib/market/my-repo.d.ts +2 -2
- package/lib/market/my-repo.js +32 -29
- package/lib/market/prepare.js +18 -15
- package/lib/market/security.js +20 -19
- package/lib/market/types.js +2 -1
- package/lib/market/url.js +2 -1
- package/lib/migrations/index.js +6 -5
- package/lib/migrations/messages-migrations.d.ts +32 -0
- package/lib/migrations/messages-migrations.js +58 -0
- package/lib/profiles/dsh-profile-launcher.js +2 -1
- package/lib/profiles/dsh-profile-runtime.js +2 -1
- package/lib/profiles/messages.d.ts +7 -0
- package/lib/profiles/messages.js +27 -0
- package/lib/routes/backup.js +18 -2
- package/lib/routes/import.js +3 -3
- package/lib/routes/index.d.ts +1 -1
- package/lib/routes/kit.d.ts +3 -2
- package/lib/routes/kit.js +6 -1
- package/lib/routes/market.js +1 -1
- package/lib/routes/messages.d.ts +43 -0
- package/lib/routes/messages.js +102 -0
- package/lib/routes/prefs.js +26 -3
- package/lib/routes/profiles.js +12 -6
- package/lib/routes/recovery.d.ts +21 -0
- package/lib/routes/recovery.js +478 -94
- package/lib/routes/snapshots.js +51 -4
- package/lib/routes/sync.js +79 -17
- package/lib/schema/config.d.ts +11 -1
- package/lib/schema/config.js +52 -20
- package/lib/schema/index.d.ts +8 -6
- package/lib/schema/index.js +8 -6
- package/lib/schema/manifest.js +19 -18
- package/lib/schema/messages.d.ts +47 -0
- package/lib/schema/messages.js +110 -0
- package/lib/schema/section-registry.d.ts +42 -15
- package/lib/schema/section-registry.js +67 -32
- package/lib/schema/types.d.ts +1 -1
- package/lib/schema/versions.js +6 -5
- package/lib/security/encryption.js +16 -15
- package/lib/security/integrity.js +8 -7
- package/lib/security/messages.d.ts +30 -0
- package/lib/security/messages.js +77 -0
- package/lib/security/redaction.js +12 -0
- package/lib/security/secret-scanner.js +16 -13
- package/lib/security/vault.js +2 -1
- package/lib/security/zip-security.js +4 -3
- package/lib/sync/ancestor.js +2 -1
- package/lib/sync/autosync-config.d.ts +11 -0
- package/lib/sync/autosync-config.js +12 -0
- package/lib/sync/autosync-scheduler.d.ts +11 -1
- package/lib/sync/autosync-scheduler.js +115 -76
- package/lib/sync/backup-files.js +3 -2
- package/lib/sync/backup-scheduler.js +6 -5
- package/lib/sync/blob-store.js +2 -1
- package/lib/sync/git/git-transport.d.ts +55 -0
- package/lib/sync/git/git-transport.js +152 -2
- package/lib/sync/github-auth.js +10 -9
- package/lib/sync/layout.js +13 -12
- package/lib/sync/messages.d.ts +63 -0
- package/lib/sync/messages.js +149 -0
- package/lib/sync/review-queue.js +6 -5
- package/lib/sync/s3/messages.d.ts +7 -0
- package/lib/sync/s3/messages.js +16 -0
- package/lib/sync/s3/s3-providers.d.ts +4 -1
- package/lib/sync/s3/s3-providers.js +5 -5
- package/lib/sync/s3/s3-transport.js +1 -1
- package/lib/sync/s3/sigv4.js +2 -1
- package/lib/sync/snapshot-crypto.js +6 -5
- package/lib/sync/snapshot-json.js +3 -2
- package/lib/sync/sync-engine.d.ts +58 -22
- package/lib/sync/sync-engine.js +119 -48
- package/lib/sync/sync-history.js +7 -6
- package/lib/sync/sync-selection.d.ts +15 -4
- package/lib/sync/sync-selection.js +17 -5
- package/lib/sync/ui-prefs.d.ts +22 -0
- package/lib/sync/ui-prefs.js +28 -0
- package/lib/sync/webdav/webdav-transport.d.ts +1 -0
- package/lib/sync/webdav/webdav-transport.js +4 -1
- package/lib/ui/artifact-view.js +4 -3
- package/lib/ui/commands.d.ts +1 -1
- package/lib/ui/commands.js +10 -0
- package/lib/ui/diff-view.d.ts +10 -0
- package/lib/ui/diff-view.js +17 -0
- package/lib/ui/disk-usage-view.d.ts +33 -4
- package/lib/ui/disk-usage-view.js +29 -1
- package/lib/ui/errors.d.ts +1 -1
- package/lib/ui/errors.js +4 -3
- package/lib/ui/export-flow.js +26 -20
- package/lib/ui/foreign-view.d.ts +5 -1
- package/lib/ui/foreign-view.js +26 -2
- package/lib/ui/i18n.d.ts +68 -1
- package/lib/ui/i18n.js +120 -2
- package/lib/ui/import-wizard.d.ts +7 -0
- package/lib/ui/import-wizard.js +13 -10
- package/lib/ui/progress.d.ts +2 -2
- package/lib/ui/progress.js +1 -2
- package/lib/ui/report.d.ts +5 -5
- package/lib/ui/report.js +6 -6
- package/lib/ui/rollback-view.d.ts +815 -0
- package/lib/ui/rollback-view.js +738 -0
- package/lib/ui/selection-model.d.ts +41 -0
- package/lib/ui/selection-model.js +30 -0
- package/lib/ui/session-inventory-view.d.ts +97 -3
- package/lib/ui/session-inventory-view.js +76 -2
- package/lib/ui/session-issue-labels.d.ts +43 -0
- package/lib/ui/session-issue-labels.js +48 -0
- package/lib/ui/sync-settings-view.d.ts +33 -0
- package/lib/ui/sync-settings-view.js +40 -0
- package/lib/ui/test-helpers.js +2 -1
- package/lib/ui/types.d.ts +8 -3
- package/lib/ui/types.js +1 -1
- package/lib/utils/atomic-write.js +6 -5
- package/lib/utils/bundle-scan.d.ts +11 -1
- package/lib/utils/bundle-scan.js +12 -1
- package/lib/utils/env-lock.d.ts +10 -0
- package/lib/utils/env-lock.js +73 -46
- package/lib/utils/json.js +6 -5
- package/lib/utils/messages-utils.d.ts +96 -0
- package/lib/utils/messages-utils.js +216 -0
- package/lib/utils/proxy.js +18 -5
- package/lib/utils/recursive-walk.d.ts +22 -0
- package/lib/utils/recursive-walk.js +75 -1
- package/lib/utils/session-log-repair.js +10 -9
- package/lib/utils/zip.js +27 -26
- package/package.json +12 -2
- package/src/adapters/agent-instructions.ts +1 -1
- package/src/adapters/file-collection.test.ts +1 -0
- package/src/adapters/file-collection.ts +1 -1
- package/src/adapters/files.test.ts +27 -0
- package/src/adapters/index.ts +6 -1
- package/src/adapters/link-report.test.ts +22 -2
- package/src/adapters/link-report.ts +29 -4
- package/src/adapters/messages.ts +61 -0
- package/src/adapters/plugin-data.test.ts +225 -0
- package/src/adapters/plugin-data.ts +351 -0
- package/src/adapters/plugin-files.ts +3 -2
- package/src/adapters/plugins.ts +4 -3
- package/src/adapters/prompts.ts +7 -1
- package/src/adapters/self.test.ts +26 -0
- package/src/adapters/self.ts +10 -3
- package/src/adapters/sessions.ts +4 -2
- package/src/adapters/settings.test.ts +38 -1
- package/src/adapters/test-helpers.ts +15 -0
- package/src/adapters/ui.test.ts +2 -2
- package/src/adapters/ui.ts +27 -26
- package/src/adapters/workspaces.ts +7 -3
- package/src/cli/actions.test.ts +28 -0
- package/src/cli/actions.ts +11 -2
- package/src/cli/help.ts +23 -10
- package/src/cli/index-guards.test.ts +193 -0
- package/src/cli/index.ts +106 -31
- package/src/cli/sessions-inspect.test.ts +15 -1
- package/src/cli/sessions-inspect.ts +3 -1
- package/src/cli/sessions-repair.test.ts +84 -0
- package/src/cli/sessions-repair.ts +33 -7
- package/src/cli/web/console-route-parity.test.ts +115 -0
- package/src/cli/web/page.ts +23 -12
- package/src/cli/web/routes.ts +2 -1
- package/src/cli/web/server.ts +4 -4
- package/src/cli/web/web.test.ts +2 -2
- package/src/client/ConfigManagerSection.tsx +30 -2
- package/src/client/about/AboutPanel.tsx +2 -2
- package/src/client/about/PluginUpdateDialog.tsx +1 -1
- package/src/client/about/ReleaseNotesDialog.tsx +2 -2
- package/src/client/about/about-view.test.ts +13 -3
- package/src/client/about/about-view.ts +10 -6
- package/src/client/about/release-notes-view.test.ts +14 -4
- package/src/client/about/release-notes-view.ts +4 -2
- package/src/client/api.ts +18 -6
- package/src/client/chat/ChatEntryView.tsx +411 -0
- package/src/client/chat/RollbackDiffTab.tsx +108 -0
- package/src/client/chat/RollbackFileIcon.tsx +96 -0
- package/src/client/chat/RollbackReviewDialog.tsx +607 -0
- package/src/client/chat/chat-entry-view.test.ts +1174 -0
- package/src/client/chat/chat-entry-view.ts +758 -0
- package/src/client/chat/chat-locales.ts +152 -0
- package/src/client/chat/chat-node-registration.ts +64 -0
- package/src/client/chat/chat-point-window.ts +183 -0
- package/src/client/chat/chat-slots.ts +107 -0
- package/src/client/chat/rollback-diff-tab.test.ts +105 -0
- package/src/client/chat/rollback-diff-tab.ts +174 -0
- package/src/client/chat/rollback-entry-view.test.ts +1469 -0
- package/src/client/chat/rollback-entry-view.ts +946 -0
- package/src/client/chat/sidebar-slots.ts +59 -0
- package/src/client/common/ConfirmDialog.tsx +7 -3
- package/src/client/common/ContentPicker.tsx +48 -10
- package/src/client/common/DiffTable.tsx +133 -0
- package/src/client/common/ErrorBanner.tsx +4 -4
- package/src/client/common/Icon.tsx +2 -0
- package/src/client/common/Modal.tsx +8 -1
- package/src/client/common/ProgressBar.tsx +8 -2
- package/src/client/common/ReportView.tsx +4 -4
- package/src/client/common/RunsCenter.tsx +1 -0
- package/src/client/common/client-route-parity.test.ts +84 -0
- package/src/client/common/info-hint-guard.test.ts +46 -13
- package/src/client/common/picker-lazy-units.test.ts +42 -0
- package/src/client/common/plan-text-redaction.test.ts +17 -6
- package/src/client/common/progress-view-edge.test.ts +8 -7
- package/src/client/common/progress-view.test.ts +9 -9
- package/src/client/common/progress-view.ts +2 -2
- package/src/client/common/routes.ts +38 -0
- package/src/client/common/section-labels.test.ts +1 -0
- package/src/client/common/section-labels.ts +2 -0
- package/src/client/common/ui.tsx +73 -10
- package/src/client/config-manager.module.css +1109 -31
- package/src/client/css-scale-guard.test.ts +30 -0
- package/src/client/environment/EnvironmentPanel.tsx +11 -4
- package/src/client/environment/maintenance/DiskUsageCard.tsx +23 -2
- package/src/client/export/ExportView.tsx +13 -8
- package/src/client/history/HistoryPanel.tsx +4 -3
- package/src/client/history/history-api.ts +2 -2
- package/src/client/history/history-locales.ts +5 -1
- package/src/client/home/HomePanel.tsx +29 -8
- package/src/client/import/ForeignImportView.tsx +4 -5
- package/src/client/import/ImportWizardView.tsx +5 -3
- package/src/client/import/import-wizard-split.test.ts +3 -1
- package/src/client/import/import-wizard-steps.tsx +9 -9
- package/src/client/index.ts +232 -3
- package/src/client/library/LibraryActions.tsx +32 -7
- package/src/client/library/LibraryPanel.tsx +23 -3
- package/src/client/library/RestorePlanView.tsx +9 -66
- package/src/client/locales.ts +62 -9
- package/src/client/lucide-icons.d.ts +1 -0
- package/src/client/market/MarketPanel.tsx +13 -2
- package/src/client/market/MyConfigsView.tsx +5 -4
- package/src/client/market/MyConfigsWizard.tsx +10 -8
- package/src/client/market/market-api.test.ts +9 -8
- package/src/client/market/market-api.ts +2 -2
- package/src/client/market/market-locales.ts +3 -0
- package/src/client/market/market-view.test.ts +6 -6
- package/src/client/market/market-view.ts +3 -3
- package/src/client/market/my-configs-api.ts +2 -2
- package/src/client/market/my-configs-view.test.ts +23 -22
- package/src/client/market/my-configs-view.ts +8 -8
- package/src/client/recovery/IncompleteCopiesSection.tsx +2 -1
- package/src/client/recovery/RecoveryPanel.tsx +442 -283
- package/src/client/recovery/RollbackCard.tsx +859 -0
- package/src/client/recovery/RollbackDiffPane.tsx +69 -0
- package/src/client/recovery/RollbackFileChanges.tsx +163 -0
- package/src/client/recovery/incident-api.ts +2 -2
- package/src/client/recovery/recovery-api.ts +144 -6
- package/src/client/recovery/recovery-locales.test.ts +299 -0
- package/src/client/recovery/recovery-locales.ts +520 -149
- package/src/client/recovery/recovery-panel-layout.test.ts +132 -2
- package/src/client/recovery/rollback-enabled.ts +41 -0
- package/src/client/recovery/rollback-file-changes.test.ts +114 -0
- package/src/client/recovery/session-dialog-mount.test.ts +54 -0
- package/src/client/run-store.ts +84 -21
- package/src/client/sync/AutosyncCard.tsx +25 -1
- package/src/client/sync/ChannelClearConfirmDialog.tsx +6 -3
- package/src/client/sync/ChannelConfigDialog.tsx +10 -10
- package/src/client/sync/DecryptPasswordCard.tsx +2 -2
- package/src/client/sync/SecurityOptionsCard.tsx +27 -17
- package/src/client/sync/SyncChannelEntryCard.tsx +14 -2
- package/src/client/sync/SyncConfirmView.tsx +46 -8
- package/src/client/sync/SyncLogList.tsx +1 -1
- package/src/client/sync/SyncPanel.tsx +31 -23
- package/src/client/sync/SyncRepositoryPicker.tsx +3 -5
- package/src/client/sync/SyncSectionPickerDialog.tsx +11 -2
- package/src/client/sync/SyncSettingsView.test.ts +20 -1
- package/src/client/sync/UnreadableSnapshotsBanner.tsx +1 -1
- package/src/client/sync/WorkDirCard.tsx +112 -0
- package/src/client/sync/history-model.test.ts +42 -9
- package/src/client/sync/history-model.ts +30 -15
- package/src/client/sync/sync-api.test.ts +57 -33
- package/src/client/sync/sync-api.ts +80 -6
- package/src/client/sync/sync-locales.ts +104 -3
- package/src/client/sync/sync-view-v2.test.ts +65 -13
- package/src/client/sync/sync-view.test.ts +107 -52
- package/src/client/sync/sync-view.ts +124 -41
- package/src/core/analyzer.ts +31 -9
- package/src/core/backup-plan.test.ts +48 -5
- package/src/core/backup-plan.ts +51 -20
- package/src/core/backup-verify.ts +24 -23
- package/src/core/backup.test.ts +76 -0
- package/src/core/backup.ts +105 -29
- package/src/core/boot-rescue.ts +4 -3
- package/src/core/boot-safety.ts +2 -1
- package/src/core/command-rollback.test.ts +536 -0
- package/src/core/command-rollback.ts +406 -0
- package/src/core/consult-source.ts +7 -6
- package/src/core/disk-usage.test.ts +257 -1
- package/src/core/disk-usage.ts +134 -14
- package/src/core/engine-locale.test.ts +593 -0
- package/src/core/engine-locale.ts +175 -0
- package/src/core/exporter.ts +3 -3
- package/src/core/fork-reconcile.test.ts +279 -0
- package/src/core/fork-reconcile.ts +234 -0
- package/src/core/journal.ts +6 -5
- package/src/core/local-plugin-host.ts +3 -2
- package/src/core/local-plugin-pack.ts +11 -6
- package/src/core/messages-core.ts +661 -0
- package/src/core/messages.ts +125 -17
- package/src/core/migration-consult.ts +21 -20
- package/src/core/migration-history.ts +19 -5
- package/src/core/model-tools.ts +28 -27
- package/src/core/phase3-host.ts +21 -5
- package/src/core/phase3-p2b-fingerprint.test.ts +22 -0
- package/src/core/plugin-cli.ts +18 -19
- package/src/core/plugin-data-registry.test.ts +113 -0
- package/src/core/plugin-data-registry.ts +261 -0
- package/src/core/reconcile.test.ts +117 -0
- package/src/core/reconcile.ts +85 -17
- package/src/core/recovery-orchestrator.ts +19 -18
- package/src/core/reinstall.ts +26 -21
- package/src/core/restore.ts +20 -17
- package/src/core/rollback-file-diff.test.ts +159 -0
- package/src/core/rollback-gate.test.ts +66 -0
- package/src/core/rollback-gate.ts +61 -0
- package/src/core/rollback-ignore-rules.ts +126 -0
- package/src/core/rollback-ledger.test.ts +655 -0
- package/src/core/rollback-ledger.ts +1314 -0
- package/src/core/rollback-point.test.ts +2853 -0
- package/src/core/rollback-point.ts +4340 -0
- package/src/core/rollback.ts +5 -3
- package/src/core/run-registry.ts +6 -5
- package/src/core/session-health.ts +15 -0
- package/src/core/session-meta.test.ts +117 -1
- package/src/core/session-meta.ts +149 -2
- package/src/core/session-title.test.ts +127 -0
- package/src/core/session-title.ts +189 -0
- package/src/core/startup-barrier.test.ts +69 -0
- package/src/core/startup-barrier.ts +27 -0
- package/src/core/transaction-coordinator.ts +4 -3
- package/src/core/types.ts +37 -1
- package/src/core/validator.ts +5 -4
- package/src/core/verify-recovery.ts +31 -30
- package/src/foreign/bundle.ts +3 -2
- package/src/foreign/continue.ts +2 -1
- package/src/foreign/crush.ts +2 -1
- package/src/foreign/file-budget.test.ts +2 -0
- package/src/foreign/gemini.ts +2 -1
- package/src/foreign/goose.ts +2 -1
- package/src/foreign/kilocode.ts +2 -1
- package/src/foreign/kimi.ts +2 -1
- package/src/foreign/messages.ts +44 -0
- package/src/foreign/mimocode.ts +2 -1
- package/src/foreign/openclaw.ts +2 -1
- package/src/foreign/opencode.ts +2 -1
- package/src/foreign/pi.ts +2 -1
- package/src/foreign/qoder.ts +2 -1
- package/src/foreign/qwen.ts +2 -1
- package/src/foreign/registry.test.ts +1 -1
- package/src/foreign/registry.ts +8 -7
- package/src/foreign/teleagent.ts +2 -1
- package/src/foreign/workbuddy.ts +2 -1
- package/src/foreign/zcode.ts +2 -1
- package/src/foreign/zed.ts +2 -1
- package/src/index.facade.test.ts +340 -1
- package/src/index.ts +876 -57
- package/src/market/git-file-writer.ts +20 -19
- package/src/market/github-repos.test.ts +23 -0
- package/src/market/github-repos.ts +37 -19
- package/src/market/index-parser.ts +31 -30
- package/src/market/messages-market.ts +325 -0
- package/src/market/my-repo.ts +32 -29
- package/src/market/prepare.ts +18 -15
- package/src/market/security.ts +20 -19
- package/src/market/types.ts +2 -1
- package/src/market/url.ts +2 -1
- package/src/migrations/index.ts +6 -5
- package/src/migrations/messages-migrations.ts +59 -0
- package/src/profiles/dsh-profile-launcher.ts +2 -1
- package/src/profiles/dsh-profile-runtime.ts +2 -1
- package/src/profiles/messages.ts +31 -0
- package/src/routes/backup.ts +18 -2
- package/src/routes/import.ts +3 -3
- package/src/routes/index.ts +1 -1
- package/src/routes/kit.ts +9 -3
- package/src/routes/market.ts +1 -1
- package/src/routes/messages.ts +106 -0
- package/src/routes/prefs.ts +31 -2
- package/src/routes/profiles.ts +12 -6
- package/src/routes/recovery.test.ts +405 -1
- package/src/routes/recovery.ts +477 -94
- package/src/routes/snapshots.ts +51 -4
- package/src/routes/sync.ts +82 -17
- package/src/schema/config.ts +53 -20
- package/src/schema/index.ts +7 -5
- package/src/schema/manifest-schema.test.ts +4 -4
- package/src/schema/manifest.ts +19 -18
- package/src/schema/messages.ts +120 -0
- package/src/schema/registry.test.ts +28 -7
- package/src/schema/section-registry.ts +96 -42
- package/src/schema/types.ts +2 -1
- package/src/schema/versions.ts +6 -5
- package/src/security/encryption.ts +16 -15
- package/src/security/integrity.ts +8 -7
- package/src/security/messages.ts +87 -0
- package/src/security/redaction.test.ts +17 -1
- package/src/security/redaction.ts +13 -0
- package/src/security/secret-scanner.ts +19 -12
- package/src/security/security.test.ts +47 -0
- package/src/security/vault.ts +2 -1
- package/src/security/zip-security.ts +4 -3
- package/src/sync/ancestor.ts +2 -1
- package/src/sync/autosync-config.ts +21 -0
- package/src/sync/autosync-scheduler.test.ts +63 -7
- package/src/sync/autosync-scheduler.ts +118 -78
- package/src/sync/backup-files.ts +3 -2
- package/src/sync/backup-scheduler.ts +6 -5
- package/src/sync/blob-store.ts +2 -1
- package/src/sync/git/git-transport.test.ts +170 -8
- package/src/sync/git/git-transport.ts +176 -2
- package/src/sync/github-auth.ts +10 -9
- package/src/sync/layout.ts +13 -12
- package/src/sync/messages.ts +153 -0
- package/src/sync/review-queue.ts +6 -5
- package/src/sync/s3/messages.ts +16 -0
- package/src/sync/s3/s3-providers.ts +9 -6
- package/src/sync/s3/s3-transport.ts +1 -1
- package/src/sync/s3/sigv4.ts +3 -1
- package/src/sync/snapshot-crypto.ts +6 -5
- package/src/sync/snapshot-json.ts +3 -2
- package/src/sync/sync-credentials.test.ts +119 -0
- package/src/sync/sync-engine-download-tombstone.test.ts +1 -1
- package/src/sync/sync-engine.test.ts +226 -8
- package/src/sync/sync-engine.ts +154 -52
- package/src/sync/sync-history.ts +7 -6
- package/src/sync/sync-selection.test.ts +12 -2
- package/src/sync/sync-selection.ts +18 -5
- package/src/sync/transport.test.ts +1 -0
- package/src/sync/ui-prefs.test.ts +44 -1
- package/src/sync/ui-prefs.ts +39 -0
- package/src/sync/webdav/webdav-transport.ts +4 -1
- package/src/ui/artifact-view.ts +4 -3
- package/src/ui/commands.test.ts +1 -0
- package/src/ui/commands.ts +11 -1
- package/src/ui/diff-view.test.ts +9 -1
- package/src/ui/diff-view.ts +22 -0
- package/src/ui/disk-usage-view.test.ts +113 -6
- package/src/ui/disk-usage-view.ts +63 -7
- package/src/ui/errors.ts +4 -3
- package/src/ui/export-flow.ts +26 -20
- package/src/ui/foreign-view.test.ts +43 -0
- package/src/ui/foreign-view.ts +30 -3
- package/src/ui/i18n.ts +131 -2
- package/src/ui/import-wizard.ts +18 -10
- package/src/ui/progress.ts +2 -2
- package/src/ui/report.ts +7 -6
- package/src/ui/rollback-view.test.ts +836 -0
- package/src/ui/rollback-view.ts +1405 -0
- package/src/ui/selection-model.test.ts +33 -1
- package/src/ui/selection-model.ts +53 -0
- package/src/ui/session-inventory-view.test.ts +109 -0
- package/src/ui/session-inventory-view.ts +138 -3
- package/src/ui/session-issue-labels.test.ts +51 -0
- package/src/ui/session-issue-labels.ts +70 -0
- package/src/ui/sync-settings-view.test.ts +36 -0
- package/src/ui/sync-settings-view.ts +49 -0
- package/src/ui/test-helpers.ts +2 -1
- package/src/ui/types.ts +10 -4
- package/src/utils/atomic-write.ts +6 -5
- package/src/utils/bundle-scan.test.ts +2 -2
- package/src/utils/bundle-scan.ts +12 -1
- package/src/utils/env-lock.ts +83 -49
- package/src/utils/json.ts +7 -5
- package/src/utils/messages-utils.ts +232 -0
- package/src/utils/proxy.test.ts +25 -0
- package/src/utils/proxy.ts +19 -5
- package/src/utils/recursive-walk.test.ts +43 -0
- package/src/utils/recursive-walk.ts +75 -1
- package/src/utils/session-log-repair.ts +10 -9
- package/src/utils/zip.ts +27 -26
- package/lib/core/checkpoint.d.ts +0 -362
- package/lib/core/checkpoint.js +0 -1309
- package/src/core/checkpoint.test.ts +0 -665
- package/src/core/checkpoint.ts +0 -1614
package/lib/utils/zip.js
CHANGED
|
@@ -17,6 +17,7 @@ import path from 'node:path';
|
|
|
17
17
|
import zlib from 'node:zlib';
|
|
18
18
|
import { parseJsonSafe } from './json.js';
|
|
19
19
|
import { isPathSafe, isSameOrChild } from './paths.js';
|
|
20
|
+
import { utilsMsg } from './messages-utils.js';
|
|
20
21
|
export const DEFAULT_ZIP_SAFETY_LIMITS = {
|
|
21
22
|
maxEntries: 10_000,
|
|
22
23
|
maxTotalBytes: 500 * 1024 * 1024,
|
|
@@ -78,7 +79,7 @@ export function assertZipEntryCount(count, limits = {}) {
|
|
|
78
79
|
const readSideMax = DEFAULT_ZIP_SAFETY_LIMITS.maxEntries;
|
|
79
80
|
const max = Math.min(limits.maxEntries ?? readSideMax, readSideMax, ZIP_MAX_WRITABLE_ENTRIES);
|
|
80
81
|
if (count > max) {
|
|
81
|
-
throw new ZipSafetyError(
|
|
82
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.entryCountWriteExceeded', { count, max }));
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
/* ---------------- 写出侧布局片段(zipToBuffer 与 writeZip 共用,避免两份布局漂移) ----------------
|
|
@@ -171,7 +172,7 @@ export function zipToBuffer(entries, limits = {}) {
|
|
|
171
172
|
const { time, date } = dosDateTime();
|
|
172
173
|
for (const entry of entries) {
|
|
173
174
|
if (!isPathSafe(entry.name)) {
|
|
174
|
-
throw new ZipSafetyError(
|
|
175
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.unsafeEntryNameWrite', { name: entry.name }));
|
|
175
176
|
}
|
|
176
177
|
const nameBuf = Buffer.from(entry.name, 'utf8');
|
|
177
178
|
const data = Buffer.isBuffer(entry.data) ? entry.data : Buffer.from(entry.data);
|
|
@@ -206,7 +207,7 @@ export async function writeZip(zipPath, entries, limits = {}) {
|
|
|
206
207
|
// 先全量校验条目名:不安全的名字在**落任何字节之前**拒绝(与 zipToBuffer 的拒绝顺序一致)
|
|
207
208
|
const prepared = entries.map((entry) => {
|
|
208
209
|
if (!isPathSafe(entry.name))
|
|
209
|
-
throw new ZipSafetyError(
|
|
210
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.unsafeEntryNameWrite', { name: entry.name }));
|
|
210
211
|
return {
|
|
211
212
|
nameBuf: Buffer.from(entry.name, 'utf8'),
|
|
212
213
|
data: Buffer.isBuffer(entry.data) ? entry.data : Buffer.from(entry.data),
|
|
@@ -342,11 +343,11 @@ export class ZipArchive {
|
|
|
342
343
|
out = zlib.inflateRawSync(raw, { maxOutputLength: this.limits.maxSingleBytes });
|
|
343
344
|
}
|
|
344
345
|
catch (err) {
|
|
345
|
-
throw new ZipSafetyError(
|
|
346
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.entryInflateFailed', { name, reason: err instanceof Error ? err.message : String(err) }));
|
|
346
347
|
}
|
|
347
348
|
}
|
|
348
349
|
else {
|
|
349
|
-
throw new ZipSafetyError(
|
|
350
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.unknownCompression', { name, method: meta.method }));
|
|
350
351
|
}
|
|
351
352
|
return this.accept(name, meta, out);
|
|
352
353
|
}
|
|
@@ -372,11 +373,11 @@ export class ZipArchive {
|
|
|
372
373
|
out = await inflateRawAsync(raw, this.limits.maxSingleBytes);
|
|
373
374
|
}
|
|
374
375
|
catch (err) {
|
|
375
|
-
throw new ZipSafetyError(
|
|
376
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.entryInflateFailed', { name, reason: err instanceof Error ? err.message : String(err) }));
|
|
376
377
|
}
|
|
377
378
|
}
|
|
378
379
|
else {
|
|
379
|
-
throw new ZipSafetyError(
|
|
380
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.unknownCompression', { name, method: meta.method }));
|
|
380
381
|
}
|
|
381
382
|
return this.accept(name, meta, out);
|
|
382
383
|
}
|
|
@@ -384,7 +385,7 @@ export class ZipArchive {
|
|
|
384
385
|
metaOf(name) {
|
|
385
386
|
const meta = this.metas.find((m) => m.name === name);
|
|
386
387
|
if (!meta)
|
|
387
|
-
throw new ZipSafetyError(
|
|
388
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.entryMissing', { name }));
|
|
388
389
|
return meta;
|
|
389
390
|
}
|
|
390
391
|
/** 本地文件头校验 + 定位压缩字节区间(越界 → 抛错)。 */
|
|
@@ -392,32 +393,32 @@ export class ZipArchive {
|
|
|
392
393
|
const lhOffset = meta.localOffset;
|
|
393
394
|
const lh = this.buf.subarray(lhOffset, lhOffset + 30);
|
|
394
395
|
if (lh.length < 30 || lh.readUInt32LE(0) !== LOCAL_SIG) {
|
|
395
|
-
throw new ZipSafetyError(
|
|
396
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.localHeaderCorrupt', { name }));
|
|
396
397
|
}
|
|
397
398
|
const nameLen = lh.readUInt16LE(26);
|
|
398
399
|
const extraLen = lh.readUInt16LE(28);
|
|
399
400
|
const dataStart = lhOffset + 30 + nameLen + extraLen;
|
|
400
401
|
if (dataStart + meta.compressedSize > this.buf.length) {
|
|
401
|
-
throw new ZipSafetyError(
|
|
402
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.dataOutOfRange', { name }));
|
|
402
403
|
}
|
|
403
404
|
return this.buf.subarray(dataStart, dataStart + meta.compressedSize);
|
|
404
405
|
}
|
|
405
406
|
/** 解压后的验收:尺寸 → CRC32 → 解压总量预算 → 压缩比(zip bomb)。两处解压路径共用同一套判据。 */
|
|
406
407
|
accept(name, meta, out) {
|
|
407
408
|
if (out.length !== meta.uncompressedSize) {
|
|
408
|
-
throw new ZipSafetyError(
|
|
409
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.sizeMismatch', { name, actual: out.length, expected: meta.uncompressedSize }));
|
|
409
410
|
}
|
|
410
411
|
if (crc32(out) !== meta.crc32) {
|
|
411
|
-
throw new ZipSafetyError(
|
|
412
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.crcMismatch', { name }));
|
|
412
413
|
}
|
|
413
414
|
this.totalUncompressed += out.length;
|
|
414
415
|
if (this.totalUncompressed > this.limits.maxTotalBytes) {
|
|
415
|
-
throw new ZipSafetyError('
|
|
416
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.totalUncompressedExceeded'));
|
|
416
417
|
}
|
|
417
418
|
if (meta.compressedSize > 0) {
|
|
418
419
|
const ratio = out.length / meta.compressedSize;
|
|
419
420
|
if (ratio > this.limits.maxRatio) {
|
|
420
|
-
throw new ZipSafetyError(
|
|
421
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.ratioExceeded', { name, ratio: ratio.toFixed(1) }));
|
|
421
422
|
}
|
|
422
423
|
}
|
|
423
424
|
return out;
|
|
@@ -440,19 +441,19 @@ export function parseZip(buf, limits = {}) {
|
|
|
440
441
|
const merged = { ...DEFAULT_ZIP_SAFETY_LIMITS, ...limits };
|
|
441
442
|
const b = Buffer.isBuffer(buf) ? buf : Buffer.from(buf);
|
|
442
443
|
if (b.length < 22)
|
|
443
|
-
throw new ZipSafetyError('
|
|
444
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.tooSmall'));
|
|
444
445
|
const eocdIdx = b.lastIndexOf(EOCD_SIG);
|
|
445
446
|
if (eocdIdx < 0 || eocdIdx + 22 > b.length) {
|
|
446
|
-
throw new ZipSafetyError('
|
|
447
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.missingEocd'));
|
|
447
448
|
}
|
|
448
449
|
const totalEntries = b.readUInt16LE(eocdIdx + 10);
|
|
449
450
|
const cdSize = b.readUInt32LE(eocdIdx + 12);
|
|
450
451
|
const cdOffset = b.readUInt32LE(eocdIdx + 16);
|
|
451
452
|
if (cdOffset + cdSize > b.length) {
|
|
452
|
-
throw new ZipSafetyError('
|
|
453
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.centralDirOutOfRange'));
|
|
453
454
|
}
|
|
454
455
|
if (totalEntries > merged.maxEntries) {
|
|
455
|
-
throw new ZipSafetyError(
|
|
456
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.entryCountReadExceeded', { count: totalEntries, max: merged.maxEntries }));
|
|
456
457
|
}
|
|
457
458
|
const metas = [];
|
|
458
459
|
/** 已见条目名:重复条目会让「按名读取」产生歧义(读取到哪一个取决于遍历顺序) */
|
|
@@ -461,9 +462,9 @@ export function parseZip(buf, limits = {}) {
|
|
|
461
462
|
let compressedTotal = 0;
|
|
462
463
|
for (let i = 0; i < totalEntries; i++) {
|
|
463
464
|
if (pos + 46 > cdOffset + cdSize)
|
|
464
|
-
throw new ZipSafetyError('
|
|
465
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.centralEntryOutOfRange'));
|
|
465
466
|
if (b.readUInt32LE(pos) !== CENTRAL_SIG)
|
|
466
|
-
throw new ZipSafetyError('
|
|
467
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.centralSignatureCorrupt'));
|
|
467
468
|
const method = b.readUInt16LE(pos + 10);
|
|
468
469
|
const crc = b.readUInt32LE(pos + 16);
|
|
469
470
|
const compSize = b.readUInt32LE(pos + 20);
|
|
@@ -475,21 +476,21 @@ export function parseZip(buf, limits = {}) {
|
|
|
475
476
|
const localOffset = b.readUInt32LE(pos + 42);
|
|
476
477
|
const name = b.subarray(pos + 46, pos + 46 + nameLen).toString('utf8');
|
|
477
478
|
if (!isPathSafe(name))
|
|
478
|
-
throw new ZipSafetyError(
|
|
479
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.unsafeEntryName', { name }));
|
|
479
480
|
// —— 以下三项原属 security/zip-security.ts 的 parseZipHardened,现并入默认解析器 ——
|
|
480
481
|
// (默认值即最严:未注入 parseZipOverride 的调用方不再拿到「弱版」)
|
|
481
482
|
if (seenNames.has(name))
|
|
482
|
-
throw new ZipSafetyError(
|
|
483
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.duplicateEntryName', { name }));
|
|
483
484
|
seenNames.add(name);
|
|
484
485
|
if (((externalAttrs >>> 16) & S_IFMT) === S_IFLNK) {
|
|
485
|
-
throw new ZipSafetyError(
|
|
486
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.symlinkEntryRejected', { name }));
|
|
486
487
|
}
|
|
487
488
|
if (localOffset + 30 > b.length) {
|
|
488
|
-
throw new ZipSafetyError(
|
|
489
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.localHeaderOutOfRange', { name }));
|
|
489
490
|
}
|
|
490
491
|
compressedTotal += compSize;
|
|
491
492
|
if (compressedTotal > merged.maxCompressedBytes) {
|
|
492
|
-
throw new ZipSafetyError('
|
|
493
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.compressedTotalExceeded'));
|
|
493
494
|
}
|
|
494
495
|
metas.push({
|
|
495
496
|
name,
|
|
@@ -518,7 +519,7 @@ export async function safeExtract(zipPath, destDir, limits = {}) {
|
|
|
518
519
|
continue;
|
|
519
520
|
const target = path.join(destDir, ...meta.name.split('/'));
|
|
520
521
|
if (!isSameOrChild(target, destDir)) {
|
|
521
|
-
throw new ZipSafetyError(
|
|
522
|
+
throw new ZipSafetyError(utilsMsg('utils.zip.extractTargetOutOfRange', { name: meta.name }));
|
|
522
523
|
}
|
|
523
524
|
await fs.mkdir(path.dirname(target), { recursive: true });
|
|
524
525
|
await fs.writeFile(target, archive.readEntry(meta.name));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-config-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.73",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Backup, restore, export, import, migrate and sync your DeepSeek Harness (DSH) configuration: settings, plugins, MCP servers, skills, agent presets and workspaces. One-click migration to another machine. DSH 配置一键备份、恢复、导出、导入、迁移与同步插件。",
|
|
6
6
|
"icon": "./icon.svg",
|
|
@@ -99,8 +99,10 @@
|
|
|
99
99
|
"@deepseek-ai/dsh-client-connection": ">=0.1.0-rc.6 <0.3.0-0",
|
|
100
100
|
"@deepseek-ai/dsh-client-locale": ">=0.1.0-rc.6 <0.3.0-0",
|
|
101
101
|
"@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.6 <0.3.0-0",
|
|
102
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.0-rc.6 <0.3.0-0",
|
|
102
103
|
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.6 <0.3.0-0",
|
|
103
104
|
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.6 <0.3.0-0",
|
|
105
|
+
"@deepseek-ai/dsh-commands": ">=0.1.0-rc.6 <0.3.0-0",
|
|
104
106
|
"@deepseek-ai/dsh-credentials": ">=0.1.0-rc.6 <0.3.0-0",
|
|
105
107
|
"@deepseek-ai/dsh-home-paths": ">=0.1.0-rc.6 <0.3.0-0",
|
|
106
108
|
"@deepseek-ai/dsh-host-plugin-inventory": ">=0.1.0-rc.6 <0.3.0-0",
|
|
@@ -125,12 +127,18 @@
|
|
|
125
127
|
"@deepseek-ai/dsh-client-runtime": {
|
|
126
128
|
"optional": true
|
|
127
129
|
},
|
|
130
|
+
"@deepseek-ai/dsh-client-ui-primitives": {
|
|
131
|
+
"optional": true
|
|
132
|
+
},
|
|
128
133
|
"@deepseek-ai/dsh-client-ui-settings": {
|
|
129
134
|
"optional": true
|
|
130
135
|
},
|
|
131
136
|
"@deepseek-ai/dsh-client-ui-slots": {
|
|
132
137
|
"optional": true
|
|
133
138
|
},
|
|
139
|
+
"@deepseek-ai/dsh-commands": {
|
|
140
|
+
"optional": true
|
|
141
|
+
},
|
|
134
142
|
"@deepseek-ai/dsh-credentials": {
|
|
135
143
|
"optional": true
|
|
136
144
|
},
|
|
@@ -167,8 +175,10 @@
|
|
|
167
175
|
"@deepseek-ai/dsh-client-connection": "^0.1.0-rc.6",
|
|
168
176
|
"@deepseek-ai/dsh-client-locale": "^0.2.0-rc.2",
|
|
169
177
|
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
|
|
170
|
-
"@deepseek-ai/dsh-client-ui-
|
|
178
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.2.0-rc.2",
|
|
179
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.2.0-rc.2",
|
|
171
180
|
"@deepseek-ai/dsh-client-ui-slots": "^0.2.0-rc.2",
|
|
181
|
+
"@deepseek-ai/dsh-commands": "^0.2.0-rc.2",
|
|
172
182
|
"@deepseek-ai/dsh-credentials": "^0.1.0-rc.6",
|
|
173
183
|
"@deepseek-ai/dsh-home-paths": "^0.1.0-rc.6",
|
|
174
184
|
"@deepseek-ai/dsh-host-plugin-inventory": "^0.1.0-rc.6",
|
|
@@ -40,7 +40,7 @@ export class AgentInstructionsAdapter extends FileCollectionAdapter {
|
|
|
40
40
|
* (单文件代价可忽略,且 `collect` 之后还要读它)。读不到 → 空清单(与「文件不存在 = 空分区」同语义)。
|
|
41
41
|
*/
|
|
42
42
|
protected override async listRelPaths(ctx: HostContext): Promise<RecursiveListing> {
|
|
43
|
-
const empty: RecursiveListing = { paths: [], skippedLinks: [], followedLinks: 0, unreadableDirs: [] };
|
|
43
|
+
const empty: RecursiveListing = { paths: [], skippedLinks: [], skippedDepDirs: [], followedLinks: 0, unreadableDirs: [] };
|
|
44
44
|
const rel = AgentInstructionsAdapter.FILE;
|
|
45
45
|
try {
|
|
46
46
|
if (ctx.fs.statSize !== undefined) {
|
|
@@ -191,7 +191,7 @@ export abstract class FileCollectionAdapter implements ConfigAdapter<FilesSectio
|
|
|
191
191
|
// issue #37:用「跟随 junction/符号链接」的遍历,并把跟随/跳过的链接写进告警——
|
|
192
192
|
// 此前链接目录及其全部内容被静默排除,备份仍报成功。
|
|
193
193
|
// 枚举走 listRelPaths 钩子(单文件分区覆写它,避免对 home 根整目录递归)。
|
|
194
|
-
let listing: RecursiveListing = { paths: [], skippedLinks: [], followedLinks: 0, unreadableDirs: [] };
|
|
194
|
+
let listing: RecursiveListing = { paths: [], skippedLinks: [], skippedDepDirs: [], followedLinks: 0, unreadableDirs: [] };
|
|
195
195
|
try {
|
|
196
196
|
listing = await this.listRelPaths(ctx);
|
|
197
197
|
} catch {
|
|
@@ -215,6 +215,7 @@ test('issue #37: skills 导出把「跟随/跳过的链接」写进 warnings(
|
|
|
215
215
|
src.fs.listRecursiveDetailed = async () => ({
|
|
216
216
|
paths: ['skills/coding.md', 'skills/shared/inner.md'],
|
|
217
217
|
skippedLinks: [{ path: 'skills/broken', reason: 'broken' }],
|
|
218
|
+
skippedDepDirs: [],
|
|
218
219
|
followedLinks: 1,
|
|
219
220
|
unreadableDirs: [],
|
|
220
221
|
});
|
|
@@ -225,6 +226,32 @@ test('issue #37: skills 导出把「跟随/跳过的链接」写进 warnings(
|
|
|
225
226
|
assert.equal(out.warnings.some((w) => w.includes('skills/broken')), true, '必须点名被跳过的链接');
|
|
226
227
|
});
|
|
227
228
|
|
|
229
|
+
test('issue #76: skills 导出跳过 node_modules 依赖目录,并在导出报告里说明(不静默)', async () => {
|
|
230
|
+
const src = makeContext('win32', 'C:\\Users\\alice');
|
|
231
|
+
await src.fs.writeFile('skills/md2pdf/SKILL.md', Buffer.from('# md2pdf\n', 'utf8'));
|
|
232
|
+
await src.fs.writeFile('skills/md2pdf/package.json', Buffer.from('{"name":"md2pdf"}\n', 'utf8'));
|
|
233
|
+
// 宿主枚举已按 issue #76 排除依赖树,并把它带回来(真实 walk 的形态)
|
|
234
|
+
src.fs.listRecursiveDetailed = async () => ({
|
|
235
|
+
paths: ['skills/md2pdf/SKILL.md', 'skills/md2pdf/package.json'],
|
|
236
|
+
skippedLinks: [],
|
|
237
|
+
skippedDepDirs: [{ path: 'skills/md2pdf/node_modules', files: 11625 }],
|
|
238
|
+
followedLinks: 0,
|
|
239
|
+
unreadableDirs: [],
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const out = await new SkillsAdapter().export(src, { includeSecrets: false });
|
|
243
|
+
assert.deepEqual(
|
|
244
|
+
out.data.files.map((f) => f.relativePath).sort(),
|
|
245
|
+
['md2pdf/SKILL.md', 'md2pdf/package.json'],
|
|
246
|
+
'依赖树不得进包,技能本体与 package.json 必须进',
|
|
247
|
+
);
|
|
248
|
+
const line = out.warnings.find((w) => w.includes('运行时依赖目录')) ?? '';
|
|
249
|
+
assert.ok(line.length > 0, '缺依赖目录告警: ' + out.warnings.join(' | '));
|
|
250
|
+
assert.match(line, /11625 个文件/);
|
|
251
|
+
assert.match(line, /未进备份/);
|
|
252
|
+
assert.doesNotMatch(line, /链接/, '依赖目录不是链接问题,措辞不得混淆');
|
|
253
|
+
});
|
|
254
|
+
|
|
228
255
|
test('agentPresets: 目录 bundle 文件收集与写入(.agent-presets 基准目录)', async () => {
|
|
229
256
|
const src = makeContext('win32', 'C:\\Users\\alice');
|
|
230
257
|
await src.fs.writeFile('.agent-presets/work/agent.cordis.yml', Buffer.from('services:\n - name: work\n', 'utf8'));
|
package/src/adapters/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import { CredentialsAdapter, type CredentialRefsProvider } from './credentials.t
|
|
|
22
22
|
import { PluginFilesAdapter } from './plugin-files.ts';
|
|
23
23
|
import { SessionsAdapter } from './sessions.ts';
|
|
24
24
|
import { SelfAdapter } from './self.ts';
|
|
25
|
+
import { PluginDataAdapter } from './plugin-data.ts';
|
|
25
26
|
|
|
26
27
|
export interface AdapterRegistryOptions {
|
|
27
28
|
/** settings namespace 清单(宿主从 settings.yaml 顶层 key 解析注入;缺省 [] → settings/ui/credentials 为空) */
|
|
@@ -64,6 +65,9 @@ export function createAdapters(options: AdapterRegistryOptions = {}): ConfigAdap
|
|
|
64
65
|
new WorkspacesAdapter(),
|
|
65
66
|
new CredentialsAdapter({ namespaces, refs: options.credentialsRefs }),
|
|
66
67
|
new PluginFilesAdapter(options.pluginFiles, options.pluginFilesDir),
|
|
68
|
+
// 第三方插件数据(两个分区:配置类 / 大资产类;均 defaultIncluded=false,用户显式勾选)
|
|
69
|
+
new PluginDataAdapter('pluginData'),
|
|
70
|
+
new PluginDataAdapter('pluginAssets'),
|
|
67
71
|
];
|
|
68
72
|
// self 分区:插件自身配置(同步/市场/偏好),portable 默认包含;'' = 不挂载
|
|
69
73
|
if (options.selfDir !== '') {
|
|
@@ -77,7 +81,7 @@ export type { NamespaceProvider } from './settings.ts';
|
|
|
77
81
|
export type { CredentialRefsProvider } from './credentials.ts';
|
|
78
82
|
|
|
79
83
|
export { SettingsAdapter } from './settings.ts';
|
|
80
|
-
export { UiAdapter, isUiNamespace, KNOWN_UI_NAMESPACE_PREFIXES,
|
|
84
|
+
export { UiAdapter, isUiNamespace, KNOWN_UI_NAMESPACE_PREFIXES, uiMigrationNotes } from './ui.ts';
|
|
81
85
|
export { ProvidersAdapter, DEFAULT_PROVIDER_NAMESPACES, type ProviderExportEntry, type ProviderExportSection } from './providers.ts';
|
|
82
86
|
export { PluginsAdapter, USER_PATCH_FILE } from './plugins.ts';
|
|
83
87
|
export type { LocalPluginPackHook } from './plugins.ts';
|
|
@@ -91,6 +95,7 @@ export { CredentialsAdapter, defaultCredentialRefs } from './credentials.ts';
|
|
|
91
95
|
export { PluginFilesAdapter, DEFAULT_PLUGIN_FILE_WHITELIST } from './plugin-files.ts';
|
|
92
96
|
export { SessionsAdapter } from './sessions.ts';
|
|
93
97
|
export { SelfAdapter, SELF_CONFIG_FILES } from './self.ts';
|
|
98
|
+
export { PluginDataAdapter, type PluginDataAdapterOptions, type PluginDataEntry } from './plugin-data.ts';
|
|
94
99
|
export { FileCollectionAdapter } from './file-collection.ts';
|
|
95
100
|
/* JSON 分区共享校验骨架(本导出是其接入点)。收敛轨迹:
|
|
96
101
|
* · t31 抽出骨架,settings / ui / providers / plugins / mcp / prompts / credentials /
|
|
@@ -8,7 +8,7 @@ import { zhMsg } from '../core/messages.ts';
|
|
|
8
8
|
import type { FileSystemFacade } from '../core/types.ts';
|
|
9
9
|
import type { RecursiveListing } from '../utils/recursive-walk.ts';
|
|
10
10
|
|
|
11
|
-
const clean: RecursiveListing = { paths: ['skills/a.md'], skippedLinks: [], followedLinks: 0, unreadableDirs: [] };
|
|
11
|
+
const clean: RecursiveListing = { paths: ['skills/a.md'], skippedLinks: [], skippedDepDirs: [], followedLinks: 0, unreadableDirs: [] };
|
|
12
12
|
|
|
13
13
|
test('linkWarnings:无链接 → 零告警(不制造噪音)', () => {
|
|
14
14
|
assert.deepEqual(linkWarnings(zhMsg, 'Skills', clean), []);
|
|
@@ -26,6 +26,7 @@ test('linkWarnings:跳过项按原因归并,给出数量、原因与路径',
|
|
|
26
26
|
const out = linkWarnings(zhMsg, 'Skills', {
|
|
27
27
|
paths: [],
|
|
28
28
|
followedLinks: 1,
|
|
29
|
+
skippedDepDirs: [],
|
|
29
30
|
unreadableDirs: [],
|
|
30
31
|
skippedLinks: [
|
|
31
32
|
{ path: 'skills/self', reason: 'loop' },
|
|
@@ -48,7 +49,7 @@ test('linkWarnings:跳过项按原因归并,给出数量、原因与路径',
|
|
|
48
49
|
|
|
49
50
|
test('linkWarnings:目录读取失败也必须告警(其内容同样未进备份)', () => {
|
|
50
51
|
const out = linkWarnings(zhMsg, 'Skills', {
|
|
51
|
-
paths: [], followedLinks: 0, skippedLinks: [], unreadableDirs: ['skills/locked', 'skills/denied'],
|
|
52
|
+
paths: [], followedLinks: 0, skippedLinks: [], skippedDepDirs: [], unreadableDirs: ['skills/locked', 'skills/denied'],
|
|
52
53
|
});
|
|
53
54
|
assert.equal(out.length, 1);
|
|
54
55
|
assert.match(out[0]!, /2 个目录读取失败/);
|
|
@@ -61,5 +62,24 @@ test('listFilesDetailed:宿主未实现 detailed 时回退到 listRecursive(
|
|
|
61
62
|
const listing = await listFilesDetailed(fs, 'skills');
|
|
62
63
|
assert.deepEqual(listing.paths, ['skills/x.md']);
|
|
63
64
|
assert.deepEqual(listing.skippedLinks, []);
|
|
65
|
+
assert.deepEqual(listing.skippedDepDirs, []);
|
|
64
66
|
assert.equal(listing.followedLinks, 0);
|
|
65
67
|
});
|
|
68
|
+
|
|
69
|
+
test('issue #76:跳过的 node_modules 依赖目录必须告警(点名路径 + 文件数 + 可重建说明)', () => {
|
|
70
|
+
const out = linkWarnings(zhMsg, 'Skills', {
|
|
71
|
+
...clean,
|
|
72
|
+
skippedDepDirs: [
|
|
73
|
+
{ path: 'skills/md2pdf/node_modules', files: 11625 },
|
|
74
|
+
{ path: 'skills/other/node_modules', files: null },
|
|
75
|
+
],
|
|
76
|
+
});
|
|
77
|
+
assert.equal(out.length, 1, '汇总成一条,不逐目录刷屏');
|
|
78
|
+
const line = out[0]!;
|
|
79
|
+
assert.match(line, /2 个运行时依赖目录/);
|
|
80
|
+
assert.match(line, /未进备份/);
|
|
81
|
+
assert.match(line, /skills\/md2pdf\/node_modules/);
|
|
82
|
+
assert.match(line, /11625 个文件/);
|
|
83
|
+
assert.match(line, /文件数未统计/, '计数预算耗尽时不得猜一个数(更不得写成 0)');
|
|
84
|
+
assert.match(line, /重新安装依赖/);
|
|
85
|
+
});
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { FileSystemFacade } from '../core/types.ts';
|
|
11
11
|
import type { MsgFunc } from '../core/messages.ts';
|
|
12
|
-
|
|
12
|
+
// t6:注册 adapters 域追加目录(本模块只消费注入的 msg,故只引它的注册副作用)。
|
|
13
|
+
import './messages.ts';
|
|
14
|
+
import type { RecursiveListing, SkippedDepDir, SkippedLink } from '../utils/recursive-walk.ts';
|
|
13
15
|
|
|
14
16
|
/** 跳过原因 → 消息 key(与 SkippedLink.reason 一一对应,穷尽映射) */
|
|
15
17
|
const REASON_KEY: Record<SkippedLink['reason'], string> = {
|
|
@@ -23,10 +25,27 @@ const REASON_KEY: Record<SkippedLink['reason'], string> = {
|
|
|
23
25
|
/** 单条原因下最多列出的路径数(其余折叠为计数,避免把报告撑爆) */
|
|
24
26
|
const MAX_PATHS_PER_REASON = 5
|
|
25
27
|
|
|
28
|
+
/**
|
|
29
|
+
* 被跳过的依赖目录 → 详情片段(路径 + 文件数,issue #76)。
|
|
30
|
+
*
|
|
31
|
+
* 文件数是**量级说明**而非完整性判据:计数预算耗尽时如实写「未统计」,绝不猜一个数
|
|
32
|
+
* (把未知写成 0 会被读成「这个目录是空的」)。
|
|
33
|
+
*/
|
|
34
|
+
function depDirDetail(msg: MsgFunc, dirs: SkippedDepDir[]): string {
|
|
35
|
+
const shown = dirs.slice(0, MAX_PATHS_PER_REASON).map((dir) => {
|
|
36
|
+
const files = dir.files === null
|
|
37
|
+
? msg('adapter.depsDirFilesUnknown')
|
|
38
|
+
: msg('adapter.depsDirFiles', { count: String(dir.files) })
|
|
39
|
+
return msg('adapter.linkDirEntry', { path: dir.path, files })
|
|
40
|
+
})
|
|
41
|
+
const more = dirs.length - shown.length
|
|
42
|
+
return (more > 0 ? [...shown, `(+ ${more})`] : shown).join(', ')
|
|
43
|
+
}
|
|
44
|
+
|
|
26
45
|
/** 取遍历结果:宿主未实现 listRecursiveDetailed(旧版/测试 mock)时回退,行为与旧版一致。 */
|
|
27
46
|
export async function listFilesDetailed(fs: FileSystemFacade, dir: string): Promise<RecursiveListing> {
|
|
28
47
|
if (fs.listRecursiveDetailed !== undefined) return fs.listRecursiveDetailed(dir)
|
|
29
|
-
return { paths: await fs.listRecursive(dir), skippedLinks: [], followedLinks: 0, unreadableDirs: [] }
|
|
48
|
+
return { paths: await fs.listRecursive(dir), skippedLinks: [], skippedDepDirs: [], followedLinks: 0, unreadableDirs: [] }
|
|
30
49
|
}
|
|
31
50
|
|
|
32
51
|
/** 把遍历结果转成告警行(无链接时返回空数组 —— 不制造噪音)。 */
|
|
@@ -45,8 +64,8 @@ export function linkWarnings(msg: MsgFunc, type: string, listing: RecursiveListi
|
|
|
45
64
|
const detail = [...byReason.entries()].map(([reason, paths]) => {
|
|
46
65
|
const shown = paths.slice(0, MAX_PATHS_PER_REASON).join(', ')
|
|
47
66
|
const more = paths.length > MAX_PATHS_PER_REASON ? ` (+ ${paths.length - MAX_PATHS_PER_REASON})` : ''
|
|
48
|
-
return
|
|
49
|
-
}).join('
|
|
67
|
+
return msg('adapter.linkSkipLine', { reason: msg(REASON_KEY[reason]), count: paths.length, paths: shown, more })
|
|
68
|
+
}).join(msg('adapter.listSeparator'))
|
|
50
69
|
out.push(msg('adapter.linksSkipped', { type, count: String(listing.skippedLinks.length), detail }))
|
|
51
70
|
}
|
|
52
71
|
if (listing.unreadableDirs.length > 0) {
|
|
@@ -57,5 +76,11 @@ export function linkWarnings(msg: MsgFunc, type: string, listing: RecursiveListi
|
|
|
57
76
|
type, count: String(listing.unreadableDirs.length), detail: `${shown}${more}`,
|
|
58
77
|
}))
|
|
59
78
|
}
|
|
79
|
+
// issue #76:运行时依赖目录整棵跳过(内容未进备份)——与链接/不可读目录同等对待:必须可见,绝不静默。
|
|
80
|
+
if (listing.skippedDepDirs.length > 0) {
|
|
81
|
+
out.push(msg('adapter.depsDirsSkipped', {
|
|
82
|
+
type, count: String(listing.skippedDepDirs.length), detail: depDirDetail(msg, listing.skippedDepDirs),
|
|
83
|
+
}))
|
|
84
|
+
}
|
|
60
85
|
return out
|
|
61
86
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters 域(src/adapters/**)的追加消息目录(zh 源 / en 镜像),归 t6 作用域。
|
|
3
|
+
*
|
|
4
|
+
* 为什么不在 \`src/core/messages.ts\` 追加:该文件不在本作用域的 inScope 内,且既有 372 键有冻结指纹。
|
|
5
|
+
* 本模块经 \`registerMessageCatalog\` 注册**追加目录**:engineMsg / makeMsg 的查找顺序是
|
|
6
|
+
* 「既有目录 → en 下回退既有 zh → 注册目录 → 键名」,所以本域新键只在既有目录未命中时生效,
|
|
7
|
+
* 不可能遮蔽 core 的既有 adapter.* 键。
|
|
8
|
+
*
|
|
9
|
+
* 纪律:zh 值 = 改动前的既有中文文案**逐字原样**;en 为 \`Record<keyof typeof zh, string>\`(缺键即编译错)。
|
|
10
|
+
* **导入本模块即完成注册**:本域消费面是注入的 ctx.msg(MsgFunc)与 engineMsg,两者都查注册目录。
|
|
11
|
+
*/
|
|
12
|
+
import { engineMsg as engineMsgOf, registerMessageCatalog } from '../core/engine-locale.ts';
|
|
13
|
+
import type { MsgFunc } from '../core/msg-types.ts';
|
|
14
|
+
|
|
15
|
+
export const zh = {
|
|
16
|
+
// ---------- 链接 / 依赖目录报告(issue #37 / #76)----------
|
|
17
|
+
'adapter.linkDirEntry': '{path}({files})',
|
|
18
|
+
'adapter.linkSkipLine': '{reason} {count} 个: {paths}{more}',
|
|
19
|
+
'adapter.listSeparator': ';',
|
|
20
|
+
// ---------- pluginFiles / tarball ----------
|
|
21
|
+
'adapter.pluginFilesCollectDirInvalid': 'pluginFiles collectDir 非法(须为相对 ~/.dsh 根的安全路径): {dir}',
|
|
22
|
+
'adapter.tarballRelPathInvalid': '非法 tarball 相对路径: {path}',
|
|
23
|
+
'adapter.localTarballUnpackFailed': '本地插件 {name} 的 tarball 解包失败,回退原始 spec:{err}',
|
|
24
|
+
// ---------- prompts 计划项明细 ----------
|
|
25
|
+
'adapter.promptDiffDetail': '行 {line} current={current} imported={imported}',
|
|
26
|
+
// ---------- 会话连带失败明细 ----------
|
|
27
|
+
'adapter.sessionUncoupledNote': '{id}({reason})',
|
|
28
|
+
// ---------- 工作区告警拼接 ----------
|
|
29
|
+
'adapter.workspaceNotesParen': '({notes})',
|
|
30
|
+
// ---------- localStorage 等 Host 无通道的 UI 状态说明 ----------
|
|
31
|
+
'adapter.uiLocalStorageTaskBoard': '任务看板数据存于浏览器 localStorage,Host 侧无访问通道,需在目标机器重新配置',
|
|
32
|
+
'adapter.uiLocalStoragePanel': '面板宽度/折叠状态存于浏览器 localStorage,Host 侧无访问通道,需在目标机器重新配置',
|
|
33
|
+
'adapter.uiLocalStorageGeneric': '浏览器端 UI 状态无法经 Host API 迁移',
|
|
34
|
+
// ---------- pluginData / pluginAssets(第三方插件数据迁移) ----------
|
|
35
|
+
'adapter.pluginDataEnvOverridden': '{path} 的位置被环境变量 {env} 覆盖,本次已跳过(不猜它指向哪里)',
|
|
36
|
+
'adapter.pluginDataPathNotAllowed': '路径不在第三方插件数据的允许范围内,已拒绝写入: {path}',
|
|
37
|
+
'adapter.pluginDataNoOsHome': '第三方插件的数据在系统主目录下,但当前宿主没有提供该目录的文件通道(旧版本宿主):本次不读取也不导入 / third-party plugin data lives under the system home directory, but this host offers no file channel for it (older host): nothing is read or imported this time',
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
export const en: Record<keyof typeof zh, string> = {
|
|
41
|
+
'adapter.linkDirEntry': '{path} ({files})',
|
|
42
|
+
'adapter.linkSkipLine': '{reason} {count} item(s): {paths}{more}',
|
|
43
|
+
'adapter.listSeparator': '; ',
|
|
44
|
+
'adapter.pluginFilesCollectDirInvalid': 'pluginFiles collectDir is invalid (must be a safe path relative to the ~/.dsh root): {dir}',
|
|
45
|
+
'adapter.tarballRelPathInvalid': 'Invalid relative tarball path: {path}',
|
|
46
|
+
'adapter.localTarballUnpackFailed': 'Failed to unpack the tarball of local plugin {name}; falling back to the original spec: {err}',
|
|
47
|
+
'adapter.promptDiffDetail': 'line {line} current={current} imported={imported}',
|
|
48
|
+
'adapter.sessionUncoupledNote': '{id} ({reason})',
|
|
49
|
+
'adapter.workspaceNotesParen': ' ({notes})',
|
|
50
|
+
'adapter.uiLocalStorageTaskBoard': 'Task-board data lives in the browser localStorage and the host has no access path; reconfigure it on the target machine',
|
|
51
|
+
'adapter.uiLocalStoragePanel': 'Panel width/collapsed state lives in the browser localStorage and the host has no access path; reconfigure it on the target machine',
|
|
52
|
+
'adapter.uiLocalStorageGeneric': 'Browser-side UI state cannot be migrated through the host API',
|
|
53
|
+
'adapter.pluginDataEnvOverridden': "the location of {path} is overridden by the {env} environment variable; skipped this time (the new location is never guessed)",
|
|
54
|
+
'adapter.pluginDataPathNotAllowed': 'the path is outside the range allowed for third-party plugin data and was refused: {path}',
|
|
55
|
+
'adapter.pluginDataNoOsHome': 'third-party plugin data lives under the system home directory, but this host offers no file channel for it (older host): nothing is read or imported this time',
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
registerMessageCatalog({ id: 'adapters-domain', zh, en });
|
|
59
|
+
|
|
60
|
+
/** 本域活翻译器(与 core 的 engineMsg 同一实现;导入本模块即完成目录注册)。 */
|
|
61
|
+
export const engineMsg: MsgFunc = engineMsgOf;
|