dsh-config-manager 0.1.71 → 0.1.72
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 +111 -96
- package/README.zh-CN.md +207 -86
- package/lib/adapters/agent-instructions.js +1 -1
- package/lib/adapters/file-collection.js +1 -1
- package/lib/adapters/index.d.ts +1 -1
- package/lib/adapters/index.js +1 -1
- package/lib/adapters/link-report.d.ts +1 -0
- package/lib/adapters/link-report.js +27 -3
- package/lib/adapters/messages.d.ts +18 -0
- package/lib/adapters/messages.js +50 -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 +7 -1
- package/lib/adapters/self.js +1 -1
- package/lib/adapters/sessions.d.ts +1 -0
- package/lib/adapters/sessions.js +4 -2
- 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 +1349 -490
- package/lib/client.js +43047 -36738
- package/lib/core/backup-plan.js +30 -17
- package/lib/core/backup-verify.js +24 -23
- package/lib/core/backup.d.ts +5 -0
- package/lib/core/backup.js +51 -25
- package/lib/core/boot-rescue.js +4 -3
- package/lib/core/boot-safety.js +2 -1
- package/lib/core/command-rollback.d.ts +178 -0
- package/lib/core/command-rollback.js +289 -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 +292 -0
- package/lib/core/messages-core.js +615 -0
- package/lib/core/messages.d.ts +60 -2
- package/lib/core/messages.js +116 -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/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-ignore-rules.d.ts +31 -0
- package/lib/core/rollback-ignore-rules.js +140 -0
- package/lib/core/rollback-point.d.ts +1208 -0
- package/lib/core/rollback-point.js +2993 -0
- 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 +18 -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.js +7 -6
- 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 +223 -7
- package/lib/index.js +729 -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 +42 -0
- package/lib/routes/messages.js +100 -0
- package/lib/routes/profiles.js +12 -6
- package/lib/routes/recovery.js +378 -114
- package/lib/routes/snapshots.js +51 -4
- package/lib/routes/sync.js +68 -16
- 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 +41 -14
- package/lib/schema/section-registry.js +35 -29
- 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 +37 -15
- package/lib/sync/sync-engine.js +67 -37
- 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/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/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 +24 -20
- package/lib/ui/foreign-view.d.ts +5 -1
- package/lib/ui/foreign-view.js +26 -2
- package/lib/ui/i18n.d.ts +65 -0
- package/lib/ui/i18n.js +114 -0
- 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 +756 -0
- package/lib/ui/rollback-view.js +724 -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/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 +1 -1
- package/src/adapters/link-report.test.ts +22 -2
- package/src/adapters/link-report.ts +29 -4
- package/src/adapters/messages.ts +54 -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 +8 -2
- package/src/adapters/sessions.ts +4 -2
- package/src/adapters/settings.test.ts +38 -1
- 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 +391 -0
- package/src/client/chat/RollbackDiffTab.tsx +61 -0
- package/src/client/chat/RollbackFileIcon.tsx +96 -0
- package/src/client/chat/RollbackReviewDialog.tsx +591 -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 +173 -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 +164 -0
- package/src/client/chat/rollback-entry-view.test.ts +1469 -0
- package/src/client/chat/rollback-entry-view.ts +941 -0
- package/src/client/chat/sidebar-slots.ts +37 -0
- package/src/client/common/ConfirmDialog.tsx +7 -3
- package/src/client/common/ContentPicker.tsx +48 -10
- package/src/client/common/DiffTable.tsx +97 -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 +78 -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 +28 -0
- package/src/client/common/ui.tsx +73 -10
- package/src/client/config-manager.module.css +996 -21
- 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 +186 -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 +54 -5
- 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 +665 -0
- package/src/client/recovery/RollbackDiffPane.tsx +58 -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 +116 -6
- package/src/client/recovery/recovery-locales.test.ts +299 -0
- package/src/client/recovery/recovery-locales.ts +488 -149
- package/src/client/recovery/recovery-panel-layout.test.ts +132 -2
- package/src/client/recovery/rollback-file-changes.test.ts +73 -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/backup-plan.test.ts +28 -0
- package/src/core/backup-plan.ts +29 -17
- package/src/core/backup-verify.ts +24 -23
- package/src/core/backup.test.ts +76 -0
- package/src/core/backup.ts +55 -25
- 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 +402 -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 +657 -0
- package/src/core/messages.ts +123 -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/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-ignore-rules.ts +126 -0
- package/src/core/rollback-point.test.ts +2603 -0
- package/src/core/rollback-point.ts +3755 -0
- 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 +18 -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.ts +7 -6
- 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 +813 -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 +104 -0
- package/src/routes/profiles.ts +12 -6
- package/src/routes/recovery.test.ts +405 -1
- package/src/routes/recovery.ts +377 -109
- package/src/routes/snapshots.ts +51 -4
- package/src/routes/sync.ts +67 -16
- package/src/schema/config.ts +53 -20
- package/src/schema/index.ts +7 -5
- package/src/schema/manifest.ts +19 -18
- package/src/schema/messages.ts +120 -0
- package/src/schema/registry.test.ts +19 -5
- package/src/schema/section-registry.ts +64 -39
- 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-engine-download-tombstone.test.ts +1 -1
- package/src/sync/sync-engine.test.ts +226 -8
- package/src/sync/sync-engine.ts +103 -41
- 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/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/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 +24 -20
- package/src/ui/foreign-view.test.ts +43 -0
- package/src/ui/foreign-view.ts +30 -3
- package/src/ui/i18n.ts +125 -0
- 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 +819 -0
- package/src/ui/rollback-view.ts +1339 -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/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
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/market/** 的领域消息目录(zh 源语言 / en 镜像)——「英文界面零中文」迁移(t5)。
|
|
3
|
+
*
|
|
4
|
+
* 口径(与 src/core/messages.ts 一致,见 docs/design/2026-10-08-i18n-en-hardcoding.md):
|
|
5
|
+
* - zh 值 = 迁移前的既有中文文案**逐字不变**(既有测试断言依赖它,只允许新增 en);
|
|
6
|
+
* - en 值类型为 Record<keyof typeof zh, string> —— 缺键/多键即编译错误;
|
|
7
|
+
* - 动态明细一律走 {param} 插值传参,不得丢信息;
|
|
8
|
+
* - 本目录经 registerMessageCatalog 注册(模块加载即注册),查找顺序在既有基础目录之后;
|
|
9
|
+
* - zh 对象字面量必须叫 \`zh\`(守卫 E3 目录 zh 区豁免;改名会让本文件自身变成数百条命中)。
|
|
10
|
+
*
|
|
11
|
+
* 使用者:\`marketMsg\`(本域唯一出口)——它 import 了 engineMsg,因此 import 本函数即完成注册,
|
|
12
|
+
* 不会出现「用了键但目录没注册」的裸键名输出。
|
|
13
|
+
*
|
|
14
|
+
* 注意:本模块被市场层(src/market/**)import,而市场层只在宿主/CLI 半加载;
|
|
15
|
+
* 浏览器半对 src/market/types.ts、my-repo.ts 只有 \`import type\`(编译期擦除),故不进 client bundle。
|
|
16
|
+
*/
|
|
17
|
+
import { engineMsg, registerMessageCatalog } from '../core/engine-locale.ts';
|
|
18
|
+
import type { MsgParams } from '../core/msg-types.ts';
|
|
19
|
+
|
|
20
|
+
export const zh = {
|
|
21
|
+
// ---------- market/types.ts:itemId 校验 ----------
|
|
22
|
+
'market.types.itemIdInvalid': '非法市场条目 id: {id}(仅允许字母数字开头,字符限 . _ -)',
|
|
23
|
+
|
|
24
|
+
// ---------- market/url.ts:仓库地址 scheme ----------
|
|
25
|
+
'market.url.schemeUnsupported': '市场仓库地址仅支持 http(s)(拒绝 git@/ssh 等形态)',
|
|
26
|
+
|
|
27
|
+
// ---------- market/git-file-writer.ts:git 写入器 ----------
|
|
28
|
+
'market.gitWriter.repoUrlEmpty': '仓库地址不能为空',
|
|
29
|
+
'market.gitWriter.repoUrlInvalid': '仓库地址非法: {reason}',
|
|
30
|
+
'market.gitWriter.repoUrlScheme': '仅支持 http(s) 仓库地址(token 经 credential helper 注入,不拼入 URL)',
|
|
31
|
+
'market.gitWriter.credentialsRequired': 'credentials provider 必填',
|
|
32
|
+
'market.gitWriter.workDirEmpty': 'workDir 不能为空',
|
|
33
|
+
'market.gitWriter.entriesEmpty': 'entries 不能为空',
|
|
34
|
+
'market.gitWriter.checkoutFailed': '切换分支失败({stderr})',
|
|
35
|
+
'market.gitWriter.addFailed': 'git add 失败({stderr})',
|
|
36
|
+
'market.gitWriter.commitFailed': 'git commit 失败({stderr})',
|
|
37
|
+
'market.gitWriter.pushFailed': 'git push 失败({stderr})',
|
|
38
|
+
'market.gitWriter.commandFailed': 'git {args} 失败: {stderr}',
|
|
39
|
+
'market.gitWriter.workDirNotEmpty': '工作副本目录非空且不是 git 仓库: {workDir}',
|
|
40
|
+
'market.gitWriter.cloneFailed': '克隆仓库失败({stderr})',
|
|
41
|
+
'market.gitWriter.identityFailed': '配置提交身份失败({stderr})',
|
|
42
|
+
'market.gitWriter.pullFailed': '拉取远端失败({stderr})',
|
|
43
|
+
'market.gitWriter.upstreamAddFailed': '添加 upstream 远端失败({stderr})',
|
|
44
|
+
'market.gitWriter.upstreamFetchFailed': '拉取官方仓库失败({stderr})',
|
|
45
|
+
'market.gitWriter.defaultBranchUnknown': '无法确定远端默认分支(origin/main 或 origin/master)',
|
|
46
|
+
|
|
47
|
+
// ---------- market/github-repos.ts:GitHub REST 封装 ----------
|
|
48
|
+
'market.github.invalidResponseShape': 'GitHub API 返回了无法识别的数据结构',
|
|
49
|
+
'market.github.missingField': 'GitHub API 响应缺少必要字段 {key}',
|
|
50
|
+
'market.github.reposNotArray': 'GitHub repos 响应不是数组',
|
|
51
|
+
'market.github.notAFile': 'GitHub contents 路径不是文件(目录 / 子模块不可作为文本读取)',
|
|
52
|
+
'market.github.missingFileContent': 'GitHub contents 响应缺少文件内容',
|
|
53
|
+
'market.github.unsupportedEncoding': '不支持的 contents 编码:{encoding}',
|
|
54
|
+
'market.github.pullsNotArray': 'GitHub pulls 响应不是数组',
|
|
55
|
+
'market.github.forkNameConflict': '你的同名仓库已存在但不是本市场的 fork,无法自动收录,请改名或删除后重试',
|
|
56
|
+
'market.github.forkTimeout': 'fork 创建超时(GitHub 异步创建,请稍后重试)',
|
|
57
|
+
'market.github.noToken': 'GitHub token 未配置(请先登录)',
|
|
58
|
+
'market.github.requestFailed': 'GitHub API 请求失败:{reason}',
|
|
59
|
+
'market.github.invalidStars': 'GitHub API 响应缺少有效的 stargazers_count',
|
|
60
|
+
'market.github.apiError': 'GitHub API 错误(HTTP {status})',
|
|
61
|
+
'market.github.apiErrorWithMessage': 'GitHub API 错误(HTTP {status}):{message}',
|
|
62
|
+
'market.github.unparsableResponse': 'GitHub API 返回了无法解析的响应,请稍后重试',
|
|
63
|
+
|
|
64
|
+
// ---------- market/index-parser.ts:index.json(L1)字段 ----------
|
|
65
|
+
'market.index.fieldMustBeString': '{path} 必须是字符串',
|
|
66
|
+
'market.index.fieldMustBeStringArray': '{path} 必须是字符串数组',
|
|
67
|
+
'market.index.mustBeObject': '{path} 必须是对象',
|
|
68
|
+
'market.index.unknownFields': '{path} 含未知字段: {fields}',
|
|
69
|
+
'market.index.idInvalid': '{path}.id 非法: {id}(仅允许字母数字开头,字符限 . _ -)',
|
|
70
|
+
'market.index.nameEmpty': '{path}.name 必须是非空字符串',
|
|
71
|
+
'market.index.contentEmpty': 'index.json 内容为空',
|
|
72
|
+
'market.index.parseFailed': 'index.json 解析失败: {reason}',
|
|
73
|
+
'market.index.rootNotObject': 'index.json 必须是对象',
|
|
74
|
+
'market.index.rootUnknownFields': 'index.json 含未知字段: {fields}',
|
|
75
|
+
'market.index.schemaVersion': 'index.json schemaVersion 必须是 {expected}(收到 {actual})',
|
|
76
|
+
'market.index.itemsMissing': 'index.json 缺少 items 数组',
|
|
77
|
+
|
|
78
|
+
// ---------- market/index-parser.ts:items/<id>/manifest.json(L2)字段 ----------
|
|
79
|
+
'market.manifest.contentEmpty': 'manifest.json 内容为空',
|
|
80
|
+
'market.manifest.parseFailed': 'manifest.json 解析失败: {reason}',
|
|
81
|
+
'market.manifest.rootNotObject': 'manifest.json 必须是对象',
|
|
82
|
+
'market.manifest.unknownFields': 'manifest.json 含未知字段: {fields}',
|
|
83
|
+
'market.manifest.schemaVersion': 'manifest.json schemaVersion 必须是 {expected}(收到 {actual})',
|
|
84
|
+
'market.manifest.idInvalid': 'manifest.json.id 非法: {id}',
|
|
85
|
+
'market.manifest.nameEmpty': 'manifest.json.name 必须是非空字符串',
|
|
86
|
+
'market.manifest.versionEmpty': 'manifest.json.version 必须是非空字符串',
|
|
87
|
+
'market.manifest.sectionsNotArray': 'manifest.json.sections 必须是字符串数组',
|
|
88
|
+
'market.manifest.unknownSection': 'manifest.json.sections 含未知分区: {section}',
|
|
89
|
+
'market.manifest.modeInvalid': 'manifest.json.mode 非法: {mode}(仅接受 migrate | share)',
|
|
90
|
+
'market.manifest.checksumsNotObject': 'manifest.json.checksums 必须是对象',
|
|
91
|
+
'market.manifest.checksumsUnknownFields': 'manifest.json.checksums 含未知字段: {fields}',
|
|
92
|
+
'market.manifest.checksumsZipEmpty': 'manifest.json.checksums.zip 必须是非空字符串',
|
|
93
|
+
'market.manifest.provenanceNotObject': 'manifest.json.provenance 必须是对象',
|
|
94
|
+
'market.manifest.provenanceUnknownFields': 'manifest.json.provenance 含未知字段: {fields}',
|
|
95
|
+
'market.manifest.provenanceSourceNotString': 'manifest.json.provenance.source 必须是字符串',
|
|
96
|
+
'market.manifest.provenanceNoteNotString': 'manifest.json.provenance.note 必须是字符串',
|
|
97
|
+
|
|
98
|
+
// ---------- market/prepare.ts:发布包生成 ----------
|
|
99
|
+
'market.prepare.nameRequired': 'name 必填',
|
|
100
|
+
'market.prepare.repoUrlInvalid': 'repoUrl 非法: {reason}',
|
|
101
|
+
'market.prepare.zipTooLarge': 'config.zip 体积 {size} 超过上限 {max} 字节',
|
|
102
|
+
'market.prepare.zipParseFailed': 'config.zip 安全解析失败: {reason}',
|
|
103
|
+
'market.prepare.zipMissingManifest': 'config.zip 缺少内部 manifest.json(须为导出/备份格式)',
|
|
104
|
+
'market.prepare.zipManifestInvalid': 'config.zip 内部 manifest 无效: {reason}',
|
|
105
|
+
'market.prepare.zipContainsSecrets': 'zip 声明 containsSecrets=true,市场通道永不携带秘密,拒绝发布',
|
|
106
|
+
'market.prepare.zipNoSections': 'zip 无启用分区,无可发布内容',
|
|
107
|
+
'market.prepare.bannedSections': 'zip 包含禁止分区 {sections}(sessions=历史会话 / pluginFiles=任意文件 / self=本地环境),市场条目禁止携带',
|
|
108
|
+
'market.prepare.shareNonPortableSections': '分享模式禁止携带设备/平台相关分区 {sections}(含凭据状态 / 会话 / MCP / 工作区等),请仅导出通用可移植分区',
|
|
109
|
+
'market.prepare.localTarballsRejected': 'zip 的 plugins 分区携带 {count} 个本地插件 tarball(localTarballs),禁止发布到市场(内嵌插件代码不可经公开仓库审阅;本地插件迁移请用自己的备份)',
|
|
110
|
+
'market.prepare.patchFilesRejected': 'zip 的 plugins 分区携带 {count} 个 pnpm patch 文件(patchFiles),禁止发布到市场(会在安装时改写依赖代码;请用自己的备份迁移)',
|
|
111
|
+
'market.prepare.sensitiveContent': '检测到疑似敏感内容({hits}),市场条目禁止携带凭据,请脱敏后重试',
|
|
112
|
+
// 命中清单的连接符也是本地化呈现的一部分(英文用半角分号 + 空格)
|
|
113
|
+
'market.prepare.scanHitSeparator': ';',
|
|
114
|
+
'market.prepare.warningPublicMarket': '条目将发布至公共网络市场,未经官方审核(供应链警示)',
|
|
115
|
+
'market.prepare.warningUntrustedInput': '发布内容为不可信输入,下载方导入前会逐项核对',
|
|
116
|
+
|
|
117
|
+
// ---------- market/security.ts:下载侧安全校验 ----------
|
|
118
|
+
'market.security.manifestIdMismatch': '清单 id 与请求条目不一致: {manifestId} ≠ {itemId}',
|
|
119
|
+
'market.security.zipTooLarge': 'config.zip 体积 {size} 超过上限 {max} 字节',
|
|
120
|
+
'market.security.zipShaMismatch': '清单声明的 config.zip SHA-256 与实际不符',
|
|
121
|
+
'market.security.zipParseFailed': 'config.zip 安全解析失败: {reason}',
|
|
122
|
+
'market.security.zipMissingManifest': 'config.zip 缺少内部 manifest.json',
|
|
123
|
+
'market.security.zipManifestInvalid': 'config.zip 内部 manifest 无效: {reason}',
|
|
124
|
+
'market.security.zipContainsSecrets': 'config.zip 声明 containsSecrets=true,市场通道永不携带秘密,拒绝',
|
|
125
|
+
'market.security.checksumMismatch': 'config.zip 内部完整性校验失败: {entries}',
|
|
126
|
+
'market.security.checksumsParseFailed': 'config.zip 内部 checksums 解析失败: {reason}',
|
|
127
|
+
'market.security.bannedSection': 'config.zip 包含禁止分区 {section}(sessions=历史会话 / pluginFiles=任意文件 / self=本地环境),市场条目禁止携带',
|
|
128
|
+
'market.security.emptyFileSection': 'config.zip 中分区 {section} 为空(无文件),导入后不产生任何效果',
|
|
129
|
+
'market.security.missingSectionFile': 'config.zip 缺少分区文件 {path}({section})',
|
|
130
|
+
'market.security.sectionParseFailed': '分区 {section} 数据解析失败: {reason}',
|
|
131
|
+
'market.security.sectionInvalid': '分区 {section} 数据无效: {errors}',
|
|
132
|
+
'market.security.localTarballsRejected': 'config.zip 的 plugins 分区携带 {count} 个本地插件 tarball(localTarballs),市场条目禁止携带内嵌插件代码(供应链防线;本地插件迁移请用自己的备份,不要经公共市场分发)',
|
|
133
|
+
'market.security.patchFilesRejected': 'config.zip 的 plugins 分区携带 {count} 个 pnpm patch 文件(patchFiles),市场条目禁止携带会在安装时改写依赖代码的内容(供应链防线;请用自己的备份迁移)',
|
|
134
|
+
'market.security.sectionsNoIntersection': '清单 sections 与 config.zip 内部 sections 无交集',
|
|
135
|
+
'market.security.warningFromPublicMarket': '条目 {itemId} 来自公共网络市场,未经官方审核(供应链警示)',
|
|
136
|
+
'market.security.warningUntrustedContent': '下载内容为不可信输入,导入前请逐项核对',
|
|
137
|
+
|
|
138
|
+
// ---------- market/my-repo.ts:我的配置仓库(一键上传/更新/删除/收录) ----------
|
|
139
|
+
'market.myRepo.indexName': '我的配置仓库',
|
|
140
|
+
'market.myRepo.repoDescription': '我的配置仓库(dsh-config-manager 自动发布)',
|
|
141
|
+
'market.myRepo.prepareRequired': 'prepare 必填',
|
|
142
|
+
'market.myRepo.restRequired': 'rest 必填',
|
|
143
|
+
'market.myRepo.userIndexUnparsable': '用户仓库 index.json 无法解析(可能被外部修改)',
|
|
144
|
+
'market.myRepo.itemNotFound': '未找到条目 {itemId}(可能已被删除),请刷新列表后重试',
|
|
145
|
+
'market.myRepo.listingTimeout': '等待市场任务超时({itemId})',
|
|
146
|
+
'market.myRepo.itemToDeleteNotFound': '未找到要删除的条目 {itemId}(可能已被删除),请刷新列表后重试',
|
|
147
|
+
'market.myRepo.delistPrSubmitted': '该条目已收录官方市场,已自动提交下架 PR;合并前官方市场可能仍显示该条目',
|
|
148
|
+
'market.myRepo.pendingPrClosed': '已关闭该条目的待审核收录 PR',
|
|
149
|
+
'market.myRepo.itemToUpdateNotFound': '未找到要更新的条目 {itemId}(可能已被移除),请刷新列表后重试',
|
|
150
|
+
'market.myRepo.nameChangedNewItem': '未找到同名已上传条目,名称变化将作为新条目发布',
|
|
151
|
+
'market.myRepo.userIndexUnparsableAborted': '用户仓库 index.json 无法解析(可能被外部修改),已中止,请检查后重试',
|
|
152
|
+
'market.myRepo.officialIndexMissing': '官方市场 index.json 不存在',
|
|
153
|
+
'market.myRepo.officialIndexUnparsable': '官方市场 index.json 无法解析',
|
|
154
|
+
'market.myRepo.preparedManifestInvalid': 'prepare 生成的 manifest 无效',
|
|
155
|
+
'market.myRepo.itemGoneFromUserRepo': '条目 {itemId} 已不在用户仓库(可能已删除),任务终止',
|
|
156
|
+
'market.myRepo.delistPrTitle': '市场下架:{itemId}',
|
|
157
|
+
'market.myRepo.delistPrIntro': '由 dsh-config-manager「删除条目」自动提交。',
|
|
158
|
+
'market.myRepo.delistPrItemLine': '- 条目:{itemId}',
|
|
159
|
+
'market.myRepo.delistPrAction': '- 操作:从官方市场 index.json 移除该条目(下架)',
|
|
160
|
+
'market.myRepo.delistPrContent': '- 内容:原条目内容位于用户公开仓库,已随删除移除',
|
|
161
|
+
'market.myRepo.listPrTitle': '市场收录:{itemId} v{version}',
|
|
162
|
+
'market.myRepo.listPrIntro': '由 dsh-config-manager「一键上传」自动提交。',
|
|
163
|
+
'market.myRepo.listPrItemLine': '- 条目:{itemId} v{version}',
|
|
164
|
+
'market.myRepo.listPrHosting': '- 内容托管:用户公开仓库(见 index.json 条目 repo 字段)',
|
|
165
|
+
'market.myRepo.listPrValidation': '- 校验:dsh-config-market CI(validate.yml)将自动执行 8 道校验与秘密扫描',
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export const en: Record<keyof typeof zh, string> = {
|
|
169
|
+
// ---------- market/types.ts ----------
|
|
170
|
+
'market.types.itemIdInvalid': 'Invalid market item id: {id} (must start with a letter or digit; allowed characters are . _ -)',
|
|
171
|
+
|
|
172
|
+
// ---------- market/url.ts ----------
|
|
173
|
+
'market.url.schemeUnsupported': 'Market repository URLs support http(s) only (git@/ssh forms are rejected)',
|
|
174
|
+
|
|
175
|
+
// ---------- market/git-file-writer.ts ----------
|
|
176
|
+
'market.gitWriter.repoUrlEmpty': 'Repository URL must not be empty',
|
|
177
|
+
'market.gitWriter.repoUrlInvalid': 'Invalid repository URL: {reason}',
|
|
178
|
+
'market.gitWriter.repoUrlScheme': 'Only http(s) repository URLs are supported (the token is injected through the credential helper, never embedded in the URL)',
|
|
179
|
+
'market.gitWriter.credentialsRequired': 'credentials provider is required',
|
|
180
|
+
'market.gitWriter.workDirEmpty': 'workDir must not be empty',
|
|
181
|
+
'market.gitWriter.entriesEmpty': 'entries must not be empty',
|
|
182
|
+
'market.gitWriter.checkoutFailed': 'Failed to switch branch ({stderr})',
|
|
183
|
+
'market.gitWriter.addFailed': 'git add failed ({stderr})',
|
|
184
|
+
'market.gitWriter.commitFailed': 'git commit failed ({stderr})',
|
|
185
|
+
'market.gitWriter.pushFailed': 'git push failed ({stderr})',
|
|
186
|
+
'market.gitWriter.commandFailed': 'git {args} failed: {stderr}',
|
|
187
|
+
'market.gitWriter.workDirNotEmpty': 'The working copy directory is not empty and is not a git repository: {workDir}',
|
|
188
|
+
'market.gitWriter.cloneFailed': 'Failed to clone the repository ({stderr})',
|
|
189
|
+
'market.gitWriter.identityFailed': 'Failed to configure the commit identity ({stderr})',
|
|
190
|
+
'market.gitWriter.pullFailed': 'Failed to pull from the remote ({stderr})',
|
|
191
|
+
'market.gitWriter.upstreamAddFailed': 'Failed to add the upstream remote ({stderr})',
|
|
192
|
+
'market.gitWriter.upstreamFetchFailed': 'Failed to fetch the official repository ({stderr})',
|
|
193
|
+
'market.gitWriter.defaultBranchUnknown': 'Cannot determine the remote default branch (origin/main or origin/master)',
|
|
194
|
+
|
|
195
|
+
// ---------- market/github-repos.ts ----------
|
|
196
|
+
'market.github.invalidResponseShape': 'The GitHub API returned an unrecognized data structure',
|
|
197
|
+
'market.github.missingField': 'GitHub API response is missing the required field {key}',
|
|
198
|
+
'market.github.reposNotArray': 'GitHub repos response is not an array',
|
|
199
|
+
'market.github.notAFile': 'GitHub contents path is not a file (directories / submodules cannot be read as text)',
|
|
200
|
+
'market.github.missingFileContent': 'GitHub contents response is missing the file content',
|
|
201
|
+
'market.github.unsupportedEncoding': 'Unsupported contents encoding: {encoding}',
|
|
202
|
+
'market.github.pullsNotArray': 'GitHub pulls response is not an array',
|
|
203
|
+
'market.github.forkNameConflict': 'A repository with the same name already exists but is not a fork of this market, so it cannot be listed automatically; rename or delete it and retry',
|
|
204
|
+
'market.github.forkTimeout': 'Fork creation timed out (GitHub creates it asynchronously, please retry later)',
|
|
205
|
+
'market.github.noToken': 'GitHub token is not configured (please sign in first)',
|
|
206
|
+
'market.github.requestFailed': 'GitHub API request failed: {reason}',
|
|
207
|
+
'market.github.invalidStars': 'GitHub API response is missing a valid stargazers_count',
|
|
208
|
+
'market.github.apiError': 'GitHub API error (HTTP {status})',
|
|
209
|
+
'market.github.apiErrorWithMessage': 'GitHub API error (HTTP {status}): {message}',
|
|
210
|
+
'market.github.unparsableResponse': 'The GitHub API returned a response that could not be parsed, please retry later',
|
|
211
|
+
|
|
212
|
+
// ---------- market/index-parser.ts (L1) ----------
|
|
213
|
+
'market.index.fieldMustBeString': '{path} must be a string',
|
|
214
|
+
'market.index.fieldMustBeStringArray': '{path} must be an array of strings',
|
|
215
|
+
'market.index.mustBeObject': '{path} must be an object',
|
|
216
|
+
'market.index.unknownFields': '{path} contains unknown fields: {fields}',
|
|
217
|
+
'market.index.idInvalid': '{path}.id is invalid: {id} (must start with a letter or digit; allowed characters are . _ -)',
|
|
218
|
+
'market.index.nameEmpty': '{path}.name must be a non-empty string',
|
|
219
|
+
'market.index.contentEmpty': 'index.json content is empty',
|
|
220
|
+
'market.index.parseFailed': 'index.json parsing failed: {reason}',
|
|
221
|
+
'market.index.rootNotObject': 'index.json must be an object',
|
|
222
|
+
'market.index.rootUnknownFields': 'index.json contains unknown fields: {fields}',
|
|
223
|
+
'market.index.schemaVersion': 'index.json schemaVersion must be {expected} (received {actual})',
|
|
224
|
+
'market.index.itemsMissing': 'index.json is missing the items array',
|
|
225
|
+
|
|
226
|
+
// ---------- market/index-parser.ts (L2) ----------
|
|
227
|
+
'market.manifest.contentEmpty': 'manifest.json content is empty',
|
|
228
|
+
'market.manifest.parseFailed': 'manifest.json parsing failed: {reason}',
|
|
229
|
+
'market.manifest.rootNotObject': 'manifest.json must be an object',
|
|
230
|
+
'market.manifest.unknownFields': 'manifest.json contains unknown fields: {fields}',
|
|
231
|
+
'market.manifest.schemaVersion': 'manifest.json schemaVersion must be {expected} (received {actual})',
|
|
232
|
+
'market.manifest.idInvalid': 'manifest.json.id is invalid: {id}',
|
|
233
|
+
'market.manifest.nameEmpty': 'manifest.json.name must be a non-empty string',
|
|
234
|
+
'market.manifest.versionEmpty': 'manifest.json.version must be a non-empty string',
|
|
235
|
+
'market.manifest.sectionsNotArray': 'manifest.json.sections must be an array of strings',
|
|
236
|
+
'market.manifest.unknownSection': 'manifest.json.sections contains an unknown section: {section}',
|
|
237
|
+
'market.manifest.modeInvalid': 'manifest.json.mode is invalid: {mode} (only migrate | share are accepted)',
|
|
238
|
+
'market.manifest.checksumsNotObject': 'manifest.json.checksums must be an object',
|
|
239
|
+
'market.manifest.checksumsUnknownFields': 'manifest.json.checksums contains unknown fields: {fields}',
|
|
240
|
+
'market.manifest.checksumsZipEmpty': 'manifest.json.checksums.zip must be a non-empty string',
|
|
241
|
+
'market.manifest.provenanceNotObject': 'manifest.json.provenance must be an object',
|
|
242
|
+
'market.manifest.provenanceUnknownFields': 'manifest.json.provenance contains unknown fields: {fields}',
|
|
243
|
+
'market.manifest.provenanceSourceNotString': 'manifest.json.provenance.source must be a string',
|
|
244
|
+
'market.manifest.provenanceNoteNotString': 'manifest.json.provenance.note must be a string',
|
|
245
|
+
|
|
246
|
+
// ---------- market/prepare.ts ----------
|
|
247
|
+
'market.prepare.nameRequired': 'name is required',
|
|
248
|
+
'market.prepare.repoUrlInvalid': 'Invalid repoUrl: {reason}',
|
|
249
|
+
'market.prepare.zipTooLarge': 'config.zip size {size} exceeds the limit of {max} bytes',
|
|
250
|
+
'market.prepare.zipParseFailed': 'config.zip failed hardened parsing: {reason}',
|
|
251
|
+
'market.prepare.zipMissingManifest': 'config.zip is missing the internal manifest.json (it must be in export/backup format)',
|
|
252
|
+
'market.prepare.zipManifestInvalid': 'config.zip internal manifest is invalid: {reason}',
|
|
253
|
+
'market.prepare.zipContainsSecrets': 'The zip declares containsSecrets=true; the market channel never carries secrets — refusing to publish',
|
|
254
|
+
'market.prepare.zipNoSections': 'The zip has no enabled sections, so there is nothing to publish',
|
|
255
|
+
'market.prepare.bannedSections': 'The zip contains banned sections {sections} (sessions=conversation history / pluginFiles=arbitrary files / self=local environment); market items must not carry them',
|
|
256
|
+
'market.prepare.shareNonPortableSections': 'Share mode forbids device/platform-specific sections {sections} (credential status / sessions / MCP / workspaces and the like); export portable sections only',
|
|
257
|
+
'market.prepare.localTarballsRejected': 'The plugins section of the zip carries {count} local plugin tarball(s) (localTarballs), which must not be published to the market (embedded plugin code cannot be reviewed through a public repository; migrate local plugins with your own backup)',
|
|
258
|
+
'market.prepare.patchFilesRejected': 'The plugins section of the zip carries {count} pnpm patch file(s) (patchFiles), which must not be published to the market (they rewrite dependency code at install time; migrate with your own backup)',
|
|
259
|
+
'market.prepare.sensitiveContent': 'Suspected sensitive content detected ({hits}); market items must not carry credentials — redact and retry',
|
|
260
|
+
'market.prepare.scanHitSeparator': '; ',
|
|
261
|
+
'market.prepare.warningPublicMarket': 'The item will be published to a public network market without official review (supply-chain warning)',
|
|
262
|
+
'market.prepare.warningUntrustedInput': 'Published content is untrusted input; downloaders verify every item before importing',
|
|
263
|
+
|
|
264
|
+
// ---------- market/security.ts ----------
|
|
265
|
+
'market.security.manifestIdMismatch': 'Manifest id does not match the requested item: {manifestId} ≠ {itemId}',
|
|
266
|
+
'market.security.zipTooLarge': 'config.zip size {size} exceeds the limit of {max} bytes',
|
|
267
|
+
'market.security.zipShaMismatch': 'The config.zip SHA-256 declared in the manifest does not match the actual file',
|
|
268
|
+
'market.security.zipParseFailed': 'config.zip failed hardened parsing: {reason}',
|
|
269
|
+
'market.security.zipMissingManifest': 'config.zip is missing the internal manifest.json',
|
|
270
|
+
'market.security.zipManifestInvalid': 'config.zip internal manifest is invalid: {reason}',
|
|
271
|
+
'market.security.zipContainsSecrets': 'config.zip declares containsSecrets=true; the market channel never carries secrets — rejected',
|
|
272
|
+
'market.security.checksumMismatch': 'config.zip internal integrity check failed: {entries}',
|
|
273
|
+
'market.security.checksumsParseFailed': 'config.zip internal checksums parsing failed: {reason}',
|
|
274
|
+
'market.security.bannedSection': 'config.zip contains a banned section {section} (sessions=conversation history / pluginFiles=arbitrary files / self=local environment); market items must not carry it',
|
|
275
|
+
'market.security.emptyFileSection': 'Section {section} in config.zip is empty (no files); importing it produces no effect',
|
|
276
|
+
'market.security.missingSectionFile': 'config.zip is missing the section file {path} ({section})',
|
|
277
|
+
'market.security.sectionParseFailed': 'Section {section} data parsing failed: {reason}',
|
|
278
|
+
'market.security.sectionInvalid': 'Section {section} data is invalid: {errors}',
|
|
279
|
+
'market.security.localTarballsRejected': 'The plugins section of config.zip carries {count} local plugin tarball(s) (localTarballs); market items must not carry embedded plugin code (supply-chain defense; migrate local plugins with your own backup instead of distributing them through a public market)',
|
|
280
|
+
'market.security.patchFilesRejected': 'The plugins section of config.zip carries {count} pnpm patch file(s) (patchFiles); market items must not carry content that rewrites dependency code at install time (supply-chain defense; migrate with your own backup)',
|
|
281
|
+
'market.security.sectionsNoIntersection': 'The manifest sections and the sections inside config.zip have no intersection',
|
|
282
|
+
'market.security.warningFromPublicMarket': 'Item {itemId} comes from a public network market without official review (supply-chain warning)',
|
|
283
|
+
'market.security.warningUntrustedContent': 'Downloaded content is untrusted input; verify every item before importing',
|
|
284
|
+
|
|
285
|
+
// ---------- market/my-repo.ts ----------
|
|
286
|
+
'market.myRepo.indexName': 'My configs repository',
|
|
287
|
+
'market.myRepo.repoDescription': 'My configs repository (published automatically by dsh-config-manager)',
|
|
288
|
+
'market.myRepo.prepareRequired': 'prepare is required',
|
|
289
|
+
'market.myRepo.restRequired': 'rest is required',
|
|
290
|
+
'market.myRepo.userIndexUnparsable': 'The user repository index.json could not be parsed (it may have been modified externally)',
|
|
291
|
+
'market.myRepo.itemNotFound': 'Item {itemId} was not found (it may have been deleted); refresh the list and retry',
|
|
292
|
+
'market.myRepo.listingTimeout': 'Timed out waiting for the market task ({itemId})',
|
|
293
|
+
'market.myRepo.itemToDeleteNotFound': 'The item to delete, {itemId}, was not found (it may have been deleted); refresh the list and retry',
|
|
294
|
+
'market.myRepo.delistPrSubmitted': 'This item is listed in the official market, so a delist PR was submitted automatically; the official market may still show the item until the PR is merged',
|
|
295
|
+
'market.myRepo.pendingPrClosed': 'The pending listing PR for this item was closed',
|
|
296
|
+
'market.myRepo.itemToUpdateNotFound': 'The item to update, {itemId}, was not found (it may have been removed); refresh the list and retry',
|
|
297
|
+
'market.myRepo.nameChangedNewItem': 'No uploaded item with the same name was found; the name change will be published as a new item',
|
|
298
|
+
'market.myRepo.userIndexUnparsableAborted': 'The user repository index.json could not be parsed (it may have been modified externally); aborted — please check and retry',
|
|
299
|
+
'market.myRepo.officialIndexMissing': 'The official market index.json does not exist',
|
|
300
|
+
'market.myRepo.officialIndexUnparsable': 'The official market index.json could not be parsed',
|
|
301
|
+
'market.myRepo.preparedManifestInvalid': 'The manifest generated by prepare is invalid',
|
|
302
|
+
'market.myRepo.itemGoneFromUserRepo': 'Item {itemId} is no longer in the user repository (it may have been deleted); the task stopped',
|
|
303
|
+
'market.myRepo.delistPrTitle': 'Market delist: {itemId}',
|
|
304
|
+
'market.myRepo.delistPrIntro': 'Submitted automatically by dsh-config-manager "Delete item".',
|
|
305
|
+
'market.myRepo.delistPrItemLine': '- Item: {itemId}',
|
|
306
|
+
'market.myRepo.delistPrAction': '- Action: remove the item from the official market index.json (delist)',
|
|
307
|
+
'market.myRepo.delistPrContent': '- Content: the original item content lives in the user public repository and was removed together with the deletion',
|
|
308
|
+
'market.myRepo.listPrTitle': 'Market listing: {itemId} v{version}',
|
|
309
|
+
'market.myRepo.listPrIntro': 'Submitted automatically by dsh-config-manager "One-click upload".',
|
|
310
|
+
'market.myRepo.listPrItemLine': '- Item: {itemId} v{version}',
|
|
311
|
+
'market.myRepo.listPrHosting': '- Content hosting: user public repository (see the repo field of the index.json entry)',
|
|
312
|
+
'market.myRepo.listPrValidation': '- Validation: the dsh-config-market CI (validate.yml) runs 8 checks plus a secret scan automatically',
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
registerMessageCatalog({ id: 'market', zh, en });
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* 本域唯一出口:取一条 src/market/** 的文案(键名受类型约束,拼错即编译错误)。
|
|
319
|
+
*
|
|
320
|
+
* 为什么不让调用方直接 import engineMsg:import 本函数即保证目录已注册(模块加载期注册一次),
|
|
321
|
+
* 否则会出现「用了键但注册表里没有 → 输出裸键名」的静默失败。
|
|
322
|
+
*/
|
|
323
|
+
export function marketMsg(key: keyof typeof zh, params?: MsgParams): string {
|
|
324
|
+
return engineMsg(key, params);
|
|
325
|
+
}
|
package/src/market/my-repo.ts
CHANGED
|
@@ -42,6 +42,7 @@ import { stringifyJsonSafe } from '../utils/json.ts';
|
|
|
42
42
|
import { sha256Hex } from '../utils/hashing.ts';
|
|
43
43
|
import { redact } from '../security/redaction.ts';
|
|
44
44
|
import type { SectionId } from '../schema/types.ts';
|
|
45
|
+
import { marketMsg } from './messages-market.ts';
|
|
45
46
|
|
|
46
47
|
/* ---------------------------------------------------------------- 常量(固定规则,无配置入口) */
|
|
47
48
|
|
|
@@ -50,8 +51,10 @@ import type { SectionId } from '../schema/types.ts';
|
|
|
50
51
|
|
|
51
52
|
/** 用户公开仓库固定名:<login>/dsh-configs(系统按规则生成,不可配置) */
|
|
52
53
|
export const USER_CONFIGS_REPO = 'dsh-configs';
|
|
53
|
-
/** 用户仓库 index.json
|
|
54
|
-
export
|
|
54
|
+
/** 用户仓库 index.json 的名称/描述(展示用;按当前界面语言在**取用时**解析,不冻结在模块加载期) */
|
|
55
|
+
export function userIndexName(): string {
|
|
56
|
+
return marketMsg('market.myRepo.indexName');
|
|
57
|
+
}
|
|
55
58
|
/** PR 分支固定名模式:dsh-market-sync/<itemId>(收录) */
|
|
56
59
|
export const PR_BRANCH_PREFIX = 'dsh-market-sync';
|
|
57
60
|
/** 下架 PR 分支固定名模式:dsh-market-delist/<itemId>(删除已收录条目;独立分支避免与收录分支混淆,
|
|
@@ -274,7 +277,7 @@ export function bumpVersion(version: string): string {
|
|
|
274
277
|
|
|
275
278
|
/** 空用户索引(首次上传时创建) */
|
|
276
279
|
function emptyIndex(): MarketIndex {
|
|
277
|
-
return { schemaVersion: MARKET_INDEX_SCHEMA_VERSION, name:
|
|
280
|
+
return { schemaVersion: MARKET_INDEX_SCHEMA_VERSION, name: userIndexName(), items: [] };
|
|
278
281
|
}
|
|
279
282
|
|
|
280
283
|
/** upsert 条目:同 id 覆盖(保持原位置),否则追加 */
|
|
@@ -345,10 +348,10 @@ export class MyRepoService {
|
|
|
345
348
|
|
|
346
349
|
constructor(options: MyRepoServiceOptions) {
|
|
347
350
|
if (options.prepare === null || typeof options.prepare !== 'function') {
|
|
348
|
-
throw new MyRepoError('
|
|
351
|
+
throw new MyRepoError(marketMsg('market.myRepo.prepareRequired'));
|
|
349
352
|
}
|
|
350
353
|
if (options.rest === null || typeof options.rest !== 'object') {
|
|
351
|
-
throw new MyRepoError('
|
|
354
|
+
throw new MyRepoError(marketMsg('market.myRepo.restRequired'));
|
|
352
355
|
}
|
|
353
356
|
this.prepare = options.prepare;
|
|
354
357
|
this.rest = options.rest;
|
|
@@ -376,7 +379,7 @@ export class MyRepoService {
|
|
|
376
379
|
if (indexText === null) return []; // 从未上传
|
|
377
380
|
const parsed = parseMarketIndex(indexText);
|
|
378
381
|
if (!parsed.ok || parsed.index === null) {
|
|
379
|
-
throw new MyRepoError('
|
|
382
|
+
throw new MyRepoError(marketMsg('market.myRepo.userIndexUnparsable'), 'index_invalid');
|
|
380
383
|
}
|
|
381
384
|
// 收录状态:官方 index 含该 id → listed;否则按设计 §4.5 以 head=<login>:<branch>
|
|
382
385
|
// 过滤 open PR(避免跨用户同名分支误报)→ pr-pending;否则 not-listed
|
|
@@ -462,7 +465,7 @@ export class MyRepoService {
|
|
|
462
465
|
const { index } = await this.readUserIndex(login);
|
|
463
466
|
const item = index.items.find((it) => it.id === itemId);
|
|
464
467
|
if (item === undefined) {
|
|
465
|
-
throw new MyRepoError(
|
|
468
|
+
throw new MyRepoError(marketMsg('market.myRepo.itemNotFound', { itemId }), 'item_not_found');
|
|
466
469
|
}
|
|
467
470
|
const repoUrl = userConfigsRepoUrl(login);
|
|
468
471
|
this.launchListing({
|
|
@@ -483,7 +486,7 @@ export class MyRepoService {
|
|
|
483
486
|
const job = this.listingJobs.get(itemId);
|
|
484
487
|
if (job !== undefined && job.status !== 'pending') return this.toListingStatus(job);
|
|
485
488
|
if (Date.now() >= deadline) {
|
|
486
|
-
throw new MyRepoError(
|
|
489
|
+
throw new MyRepoError(marketMsg('market.myRepo.listingTimeout', { itemId }), 'internal');
|
|
487
490
|
}
|
|
488
491
|
await new Promise((resolve) => setTimeout(resolve, 25));
|
|
489
492
|
}
|
|
@@ -509,7 +512,7 @@ export class MyRepoService {
|
|
|
509
512
|
const { index } = await this.readUserIndex(login);
|
|
510
513
|
const item = index.items.find((it) => it.id === itemId);
|
|
511
514
|
if (item === undefined) {
|
|
512
|
-
throw new MyRepoError(
|
|
515
|
+
throw new MyRepoError(marketMsg('market.myRepo.itemToDeleteNotFound', { itemId }), 'item_not_found');
|
|
513
516
|
}
|
|
514
517
|
|
|
515
518
|
// ② 移除条目 + 删除 items/<itemId>/ 目录 → 写回 index.json(per-login 串行)
|
|
@@ -548,7 +551,7 @@ export class MyRepoService {
|
|
|
548
551
|
delisted: true,
|
|
549
552
|
prNumber: null,
|
|
550
553
|
prUrl: null,
|
|
551
|
-
warnings: ['
|
|
554
|
+
warnings: [marketMsg('market.myRepo.delistPrSubmitted')],
|
|
552
555
|
};
|
|
553
556
|
}
|
|
554
557
|
// 未收录 → 关闭待审核的收录 PR(如有)
|
|
@@ -564,7 +567,7 @@ export class MyRepoService {
|
|
|
564
567
|
delisted: false,
|
|
565
568
|
prNumber: pr.number,
|
|
566
569
|
prUrl: pr.htmlUrl,
|
|
567
|
-
warnings: ['
|
|
570
|
+
warnings: [marketMsg('market.myRepo.pendingPrClosed')],
|
|
568
571
|
};
|
|
569
572
|
}
|
|
570
573
|
return { ok: true, itemId, delisted: false, prNumber: null, prUrl: null, warnings: [] };
|
|
@@ -616,11 +619,11 @@ export class MyRepoService {
|
|
|
616
619
|
version = bumpVersion(existing.version ?? '0.0.0');
|
|
617
620
|
} else if (explicitId !== null) {
|
|
618
621
|
// 明确要求更新一个不存在的 id → 报错(避免静默新建导致用户以为更新成功)
|
|
619
|
-
throw new MyRepoError(
|
|
622
|
+
throw new MyRepoError(marketMsg('market.myRepo.itemToUpdateNotFound', { itemId: explicitId }), 'item_not_found');
|
|
620
623
|
} else {
|
|
621
624
|
itemId = uniqueItemId(baseId, ids); // 名称变化 → 作为新条目
|
|
622
625
|
version = '1.0.0';
|
|
623
|
-
warnings.push('
|
|
626
|
+
warnings.push(marketMsg('market.myRepo.nameChangedNewItem'));
|
|
624
627
|
}
|
|
625
628
|
} else {
|
|
626
629
|
itemId = uniqueItemId(baseId, ids);
|
|
@@ -711,7 +714,7 @@ export class MyRepoService {
|
|
|
711
714
|
if (text === null) return { index: emptyIndex(), exists: false };
|
|
712
715
|
const parsed = parseMarketIndex(text);
|
|
713
716
|
if (!parsed.ok || parsed.index === null) {
|
|
714
|
-
throw new MyRepoError('
|
|
717
|
+
throw new MyRepoError(marketMsg('market.myRepo.userIndexUnparsableAborted'), 'index_invalid');
|
|
715
718
|
}
|
|
716
719
|
return { index: parsed.index, exists: true };
|
|
717
720
|
}
|
|
@@ -720,11 +723,11 @@ export class MyRepoService {
|
|
|
720
723
|
private async readOfficialIndex(): Promise<{ index: MarketIndex }> {
|
|
721
724
|
const text = await this.rest.readFile(MARKET_UPSTREAM_OWNER, MARKET_UPSTREAM_REPO, 'index.json');
|
|
722
725
|
if (text === null) {
|
|
723
|
-
throw new MyRepoError('
|
|
726
|
+
throw new MyRepoError(marketMsg('market.myRepo.officialIndexMissing'), 'official_index_missing');
|
|
724
727
|
}
|
|
725
728
|
const parsed = parseMarketIndex(text);
|
|
726
729
|
if (!parsed.ok || parsed.index === null) {
|
|
727
|
-
throw new MyRepoError('
|
|
730
|
+
throw new MyRepoError(marketMsg('market.myRepo.officialIndexUnparsable'), 'official_index_invalid');
|
|
728
731
|
}
|
|
729
732
|
return { index: parsed.index };
|
|
730
733
|
}
|
|
@@ -733,7 +736,7 @@ export class MyRepoService {
|
|
|
733
736
|
private parsePreparedManifest(manifestText: string): MarketItemManifest {
|
|
734
737
|
const parsed = parseMarketItemManifest(manifestText);
|
|
735
738
|
if (!parsed.ok || parsed.manifest === null) {
|
|
736
|
-
throw new MyRepoError('
|
|
739
|
+
throw new MyRepoError(marketMsg('market.myRepo.preparedManifestInvalid'), 'internal');
|
|
737
740
|
}
|
|
738
741
|
return parsed.manifest;
|
|
739
742
|
}
|
|
@@ -751,7 +754,7 @@ export class MyRepoService {
|
|
|
751
754
|
fork: false,
|
|
752
755
|
};
|
|
753
756
|
}
|
|
754
|
-
return this.rest.createPublicRepo(USER_CONFIGS_REPO, '
|
|
757
|
+
return this.rest.createPublicRepo(USER_CONFIGS_REPO, marketMsg('market.myRepo.repoDescription'));
|
|
755
758
|
}
|
|
756
759
|
|
|
757
760
|
/** ⑨ ensure PR:open PR(head=<login>:<branch>)存在 → 复用;否则 openPullRequest(base=main)。
|
|
@@ -770,26 +773,26 @@ export class MyRepoService {
|
|
|
770
773
|
return this.rest.openPullRequest({
|
|
771
774
|
head,
|
|
772
775
|
base: 'main',
|
|
773
|
-
title:
|
|
776
|
+
title: marketMsg('market.myRepo.delistPrTitle', { itemId }),
|
|
774
777
|
body: [
|
|
775
|
-
|
|
778
|
+
marketMsg('market.myRepo.delistPrIntro'),
|
|
776
779
|
'',
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
+
marketMsg('market.myRepo.delistPrItemLine', { itemId }),
|
|
781
|
+
marketMsg('market.myRepo.delistPrAction'),
|
|
782
|
+
marketMsg('market.myRepo.delistPrContent'),
|
|
780
783
|
].join('\n'),
|
|
781
784
|
});
|
|
782
785
|
}
|
|
783
786
|
return this.rest.openPullRequest({
|
|
784
787
|
head,
|
|
785
788
|
base: 'main',
|
|
786
|
-
title:
|
|
789
|
+
title: marketMsg('market.myRepo.listPrTitle', { itemId, version }),
|
|
787
790
|
body: [
|
|
788
|
-
|
|
791
|
+
marketMsg('market.myRepo.listPrIntro'),
|
|
789
792
|
'',
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
+
marketMsg('market.myRepo.listPrItemLine', { itemId, version }),
|
|
794
|
+
marketMsg('market.myRepo.listPrHosting'),
|
|
795
|
+
marketMsg('market.myRepo.listPrValidation'),
|
|
793
796
|
].join('\n'),
|
|
794
797
|
});
|
|
795
798
|
}
|
|
@@ -844,7 +847,7 @@ export class MyRepoService {
|
|
|
844
847
|
const { index } = await this.readUserIndex(job.login);
|
|
845
848
|
const item = index.items.find((it) => it.id === job.itemId);
|
|
846
849
|
if (item === undefined) {
|
|
847
|
-
throw new MyRepoError(
|
|
850
|
+
throw new MyRepoError(marketMsg('market.myRepo.itemGoneFromUserRepo', { itemId: job.itemId }), 'item_not_found');
|
|
848
851
|
}
|
|
849
852
|
updatedOfficial = upsertIndexItem(officialIndex.index, { ...item, repo: job.repoUrl });
|
|
850
853
|
commitMsg = `market: ${item.version !== undefined && item.version !== '' ? 'update' : 'add'} ${job.itemId} v${job.version}`;
|