dsh-config-manager 0.1.69 → 0.1.71
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 +59 -18
- package/README.zh-CN.md +29 -9
- package/lib/adapters/credentials.js +6 -3
- package/lib/adapters/file-collection.d.ts +21 -1
- package/lib/adapters/file-collection.js +32 -8
- package/lib/adapters/mcp.d.ts +12 -2
- package/lib/adapters/mcp.js +30 -13
- package/lib/adapters/plugin-files.d.ts +8 -0
- package/lib/adapters/plugin-files.js +36 -4
- package/lib/adapters/plugins.d.ts +28 -2
- package/lib/adapters/plugins.js +204 -55
- package/lib/adapters/prompts.d.ts +12 -2
- package/lib/adapters/prompts.js +34 -19
- package/lib/adapters/providers.js +5 -4
- package/lib/adapters/self.d.ts +20 -0
- package/lib/adapters/self.js +73 -0
- package/lib/adapters/sessions.d.ts +8 -0
- package/lib/adapters/sessions.js +47 -1
- package/lib/adapters/settings.d.ts +21 -3
- package/lib/adapters/settings.js +44 -7
- package/lib/adapters/skills.d.ts +36 -4
- package/lib/adapters/skills.js +222 -3
- package/lib/adapters/test-helpers.d.ts +31 -2
- package/lib/adapters/test-helpers.js +42 -5
- package/lib/adapters/workspaces.js +97 -5
- package/lib/cli/actions.d.ts +50 -3
- package/lib/cli/actions.js +103 -11
- package/lib/cli/help.d.ts +65 -0
- package/lib/cli/help.js +517 -0
- package/lib/cli/import-source.d.ts +32 -0
- package/lib/cli/import-source.js +178 -0
- package/lib/cli/index.d.ts +18 -2
- package/lib/cli/index.js +118 -90
- package/lib/cli/web/client-script.d.ts +8 -0
- package/lib/cli/web/client-script.js +11 -0
- package/lib/cli/web/http.d.ts +5 -0
- package/lib/cli/web/http.js +2 -1
- package/lib/cli/web/page.d.ts +16 -6
- package/lib/cli/web/page.js +102 -25
- package/lib/cli/web/routes.js +24 -5
- package/lib/cli/web/server.js +23 -2
- package/lib/client.d.ts +1019 -36
- package/lib/client.js +5522 -1564
- package/lib/core/analyzer.d.ts +15 -1
- package/lib/core/analyzer.js +114 -13
- package/lib/core/backup-plan.js +17 -1
- package/lib/core/backup.d.ts +8 -0
- package/lib/core/backup.js +28 -6
- package/lib/core/cache-cleaner.d.ts +10 -0
- package/lib/core/cache-cleaner.js +63 -22
- package/lib/core/checkpoint.d.ts +362 -0
- package/lib/core/checkpoint.js +1309 -0
- package/lib/core/journal.d.ts +37 -0
- package/lib/core/journal.js +69 -0
- package/lib/core/messages.d.ts +13 -0
- package/lib/core/messages.js +26 -0
- package/lib/core/model-tools.js +3 -0
- package/lib/core/patch-layers.d.ts +83 -0
- package/lib/core/patch-layers.js +110 -0
- package/lib/core/restore.d.ts +21 -0
- package/lib/core/restore.js +37 -3
- package/lib/core/rollback.js +6 -3
- package/lib/core/self-update.d.ts +52 -0
- package/lib/core/self-update.js +70 -0
- package/lib/core/session-health.d.ts +29 -5
- package/lib/core/session-health.js +28 -3
- package/lib/core/types.d.ts +126 -0
- package/lib/foreign/antigravity.d.ts +28 -0
- package/lib/foreign/antigravity.js +157 -0
- package/lib/foreign/bundle.d.ts +25 -0
- package/lib/foreign/bundle.js +79 -0
- package/lib/foreign/chatgpt.d.ts +6 -0
- package/lib/foreign/chatgpt.js +25 -0
- package/lib/foreign/claude-code.d.ts +3 -0
- package/lib/foreign/claude-code.js +85 -0
- package/lib/foreign/claude-sessions.d.ts +108 -0
- package/lib/foreign/claude-sessions.js +299 -0
- package/lib/foreign/cline.d.ts +6 -0
- package/lib/foreign/cline.js +27 -0
- package/lib/foreign/codex.d.ts +83 -0
- package/lib/foreign/codex.js +348 -0
- package/lib/foreign/continue.d.ts +9 -0
- package/lib/foreign/continue.js +65 -0
- package/lib/foreign/copilot.d.ts +39 -0
- package/lib/foreign/copilot.js +95 -0
- package/lib/foreign/crush.d.ts +11 -0
- package/lib/foreign/crush.js +57 -0
- package/lib/foreign/cursor.d.ts +87 -0
- package/lib/foreign/cursor.js +171 -0
- package/lib/foreign/dsh.d.ts +30 -0
- package/lib/foreign/dsh.js +101 -0
- package/lib/foreign/dsh4.d.ts +3 -0
- package/lib/foreign/dsh4.js +13 -0
- package/lib/foreign/gemini.d.ts +7 -0
- package/lib/foreign/gemini.js +44 -0
- package/lib/foreign/goose.d.ts +11 -0
- package/lib/foreign/goose.js +53 -0
- package/lib/foreign/grokbuild.d.ts +8 -0
- package/lib/foreign/grokbuild.js +25 -0
- package/lib/foreign/hermes.d.ts +2 -0
- package/lib/foreign/hermes.js +78 -0
- package/lib/foreign/kernel.d.ts +132 -0
- package/lib/foreign/kernel.js +569 -0
- package/lib/foreign/kilocode.d.ts +11 -0
- package/lib/foreign/kilocode.js +51 -0
- package/lib/foreign/kimi.d.ts +7 -0
- package/lib/foreign/kimi.js +47 -0
- package/lib/foreign/mimocode.d.ts +11 -0
- package/lib/foreign/mimocode.js +51 -0
- package/lib/foreign/openclaw.d.ts +7 -0
- package/lib/foreign/openclaw.js +46 -0
- package/lib/foreign/opencode.d.ts +11 -0
- package/lib/foreign/opencode.js +52 -0
- package/lib/foreign/pi.d.ts +7 -0
- package/lib/foreign/pi.js +48 -0
- package/lib/foreign/platform-paths.d.ts +66 -0
- package/lib/foreign/platform-paths.js +141 -0
- package/lib/foreign/qoder.d.ts +10 -0
- package/lib/foreign/qoder.js +49 -0
- package/lib/foreign/qwen.d.ts +7 -0
- package/lib/foreign/qwen.js +45 -0
- package/lib/foreign/read-antigravity.d.ts +57 -0
- package/lib/foreign/read-antigravity.js +504 -0
- package/lib/foreign/read-chatgpt.d.ts +20 -0
- package/lib/foreign/read-chatgpt.js +509 -0
- package/lib/foreign/read-claude-code.d.ts +24 -0
- package/lib/foreign/read-claude-code.js +234 -0
- package/lib/foreign/read-cline.d.ts +53 -0
- package/lib/foreign/read-cline.js +479 -0
- package/lib/foreign/read-codex.d.ts +75 -0
- package/lib/foreign/read-codex.js +842 -0
- package/lib/foreign/read-continue.d.ts +87 -0
- package/lib/foreign/read-continue.js +489 -0
- package/lib/foreign/read-copilot.d.ts +42 -0
- package/lib/foreign/read-copilot.js +267 -0
- package/lib/foreign/read-crush.d.ts +54 -0
- package/lib/foreign/read-crush.js +478 -0
- package/lib/foreign/read-cursor.d.ts +141 -0
- package/lib/foreign/read-cursor.js +705 -0
- package/lib/foreign/read-dsh.d.ts +43 -0
- package/lib/foreign/read-dsh.js +205 -0
- package/lib/foreign/read-dsh4.d.ts +14 -0
- package/lib/foreign/read-dsh4.js +27 -0
- package/lib/foreign/read-gemini.d.ts +55 -0
- package/lib/foreign/read-gemini.js +273 -0
- package/lib/foreign/read-goose.d.ts +25 -0
- package/lib/foreign/read-goose.js +322 -0
- package/lib/foreign/read-grokbuild.d.ts +34 -0
- package/lib/foreign/read-grokbuild.js +455 -0
- package/lib/foreign/read-hermes.d.ts +74 -0
- package/lib/foreign/read-hermes.js +690 -0
- package/lib/foreign/read-kilocode.d.ts +17 -0
- package/lib/foreign/read-kilocode.js +46 -0
- package/lib/foreign/read-kimi.d.ts +63 -0
- package/lib/foreign/read-kimi.js +719 -0
- package/lib/foreign/read-mimocode.d.ts +12 -0
- package/lib/foreign/read-mimocode.js +56 -0
- package/lib/foreign/read-openclaw.d.ts +51 -0
- package/lib/foreign/read-openclaw.js +445 -0
- package/lib/foreign/read-opencode.d.ts +150 -0
- package/lib/foreign/read-opencode.js +896 -0
- package/lib/foreign/read-pi.d.ts +56 -0
- package/lib/foreign/read-pi.js +411 -0
- package/lib/foreign/read-qoder.d.ts +54 -0
- package/lib/foreign/read-qoder.js +317 -0
- package/lib/foreign/read-qwen.d.ts +40 -0
- package/lib/foreign/read-qwen.js +326 -0
- package/lib/foreign/read-reasonix.d.ts +66 -0
- package/lib/foreign/read-reasonix.js +537 -0
- package/lib/foreign/read-teleagent.d.ts +15 -0
- package/lib/foreign/read-teleagent.js +68 -0
- package/lib/foreign/read-trae.d.ts +67 -0
- package/lib/foreign/read-trae.js +492 -0
- package/lib/foreign/read-vibe.d.ts +28 -0
- package/lib/foreign/read-vibe.js +364 -0
- package/lib/foreign/read-workbuddy.d.ts +49 -0
- package/lib/foreign/read-workbuddy.js +346 -0
- package/lib/foreign/read-zcode.d.ts +12 -0
- package/lib/foreign/read-zcode.js +38 -0
- package/lib/foreign/read-zed.d.ts +30 -0
- package/lib/foreign/read-zed.js +473 -0
- package/lib/foreign/reasonix.d.ts +6 -0
- package/lib/foreign/reasonix.js +20 -0
- package/lib/foreign/registry.d.ts +196 -0
- package/lib/foreign/registry.js +573 -0
- package/lib/foreign/session-ir.d.ts +186 -0
- package/lib/foreign/session-ir.js +427 -0
- package/lib/foreign/session-read.d.ts +102 -0
- package/lib/foreign/session-read.js +254 -0
- package/lib/foreign/session-source.d.ts +216 -0
- package/lib/foreign/session-source.js +453 -0
- package/lib/foreign/source-modules.d.ts +45 -0
- package/lib/foreign/source-modules.js +52 -0
- package/lib/foreign/sqlite.d.ts +61 -0
- package/lib/foreign/sqlite.js +404 -0
- package/lib/foreign/teleagent.d.ts +11 -0
- package/lib/foreign/teleagent.js +53 -0
- package/lib/foreign/trae.d.ts +6 -0
- package/lib/foreign/trae.js +20 -0
- package/lib/foreign/truth-table.d.ts +62 -0
- package/lib/foreign/truth-table.js +333 -0
- package/lib/foreign/types.d.ts +272 -0
- package/lib/foreign/types.js +2 -0
- package/lib/foreign/vibe.d.ts +6 -0
- package/lib/foreign/vibe.js +23 -0
- package/lib/foreign/workbuddy.d.ts +7 -0
- package/lib/foreign/workbuddy.js +45 -0
- package/lib/foreign/zcode.d.ts +11 -0
- package/lib/foreign/zcode.js +51 -0
- package/lib/foreign/zed.d.ts +11 -0
- package/lib/foreign/zed.js +53 -0
- package/lib/index.d.ts +154 -13
- package/lib/index.js +661 -84
- package/lib/market/github-repos.d.ts +28 -0
- package/lib/market/github-repos.js +43 -1
- package/lib/market/types.d.ts +1 -3
- package/lib/profiles/dsh-profile-manager.d.ts +54 -2
- package/lib/profiles/dsh-profile-manager.js +182 -11
- package/lib/profiles/dsh-profile-shared.d.ts +47 -0
- package/lib/profiles/dsh-profile-shared.js +15 -1
- package/lib/profiles/index.d.ts +1 -1
- package/lib/profiles/index.js +1 -1
- package/lib/routes/consult.js +51 -5
- package/lib/routes/foreign-context.d.ts +43 -0
- package/lib/routes/foreign-context.js +65 -0
- package/lib/routes/foreign.d.ts +11 -0
- package/lib/routes/foreign.js +208 -0
- package/lib/routes/import.d.ts +8 -0
- package/lib/routes/import.js +22 -1
- package/lib/routes/index.d.ts +2 -2
- package/lib/routes/index.js +4 -0
- package/lib/routes/kit.d.ts +4 -3
- package/lib/routes/market.js +0 -1
- package/lib/routes/prefs.d.ts +2 -1
- package/lib/routes/prefs.js +14 -2
- package/lib/routes/recovery.js +363 -3
- package/lib/routes/session-export.d.ts +117 -0
- package/lib/routes/session-export.js +270 -0
- package/lib/routes/snapshots.js +12 -2
- package/lib/routes/sync.js +82 -10
- package/lib/security/redaction.d.ts +14 -0
- package/lib/security/redaction.js +24 -9
- package/lib/security/secret-scanner.d.ts +27 -0
- package/lib/security/secret-scanner.js +54 -1
- package/lib/sync/autosync-scheduler.d.ts +13 -1
- package/lib/sync/autosync-scheduler.js +49 -26
- package/lib/sync/backup-files.js +6 -0
- package/lib/sync/gist/gist-transport.d.ts +91 -0
- package/lib/sync/gist/gist-transport.js +406 -0
- package/lib/sync/gist/messages.d.ts +22 -0
- package/lib/sync/gist/messages.js +46 -0
- package/lib/sync/s3/messages.d.ts +53 -0
- package/lib/sync/s3/messages.js +83 -0
- package/lib/sync/s3/s3-providers.d.ts +78 -0
- package/lib/sync/s3/s3-providers.js +156 -0
- package/lib/sync/s3/s3-transport.d.ts +126 -0
- package/lib/sync/s3/s3-transport.js +551 -0
- package/lib/sync/s3/sigv4.d.ts +107 -0
- package/lib/sync/s3/sigv4.js +196 -0
- package/lib/sync/sync-config.d.ts +250 -4
- package/lib/sync/sync-config.js +658 -57
- package/lib/sync/sync-engine.d.ts +1 -0
- package/lib/sync/sync-engine.js +4 -2
- package/lib/sync/sync-history.d.ts +1 -1
- package/lib/sync/webdav/webdav-transport.d.ts +31 -3
- package/lib/sync/webdav/webdav-transport.js +102 -18
- package/lib/ui/commands.d.ts +4 -3
- package/lib/ui/commands.js +41 -9
- package/lib/ui/disk-usage-view.d.ts +44 -0
- package/lib/ui/disk-usage-view.js +55 -1
- package/lib/ui/dsh-profiles-view.d.ts +53 -0
- package/lib/ui/dsh-profiles-view.js +56 -0
- package/lib/ui/foreign-view.d.ts +162 -0
- package/lib/ui/foreign-view.js +225 -0
- package/lib/ui/i18n.d.ts +77 -0
- package/lib/ui/i18n.js +164 -0
- package/lib/ui/session-inventory-view.d.ts +106 -0
- package/lib/ui/session-inventory-view.js +58 -0
- package/lib/ui/session-layout-view.d.ts +265 -0
- package/lib/ui/session-layout-view.js +271 -0
- package/lib/ui/sync-repository-picker.d.ts +98 -0
- package/lib/ui/sync-repository-picker.js +145 -0
- package/lib/ui/sync-settings-view.d.ts +143 -4
- package/lib/ui/sync-settings-view.js +231 -7
- package/lib/ui/types.d.ts +47 -0
- package/lib/utils/asar-read.d.ts +113 -0
- package/lib/utils/asar-read.js +523 -0
- package/lib/utils/env-lock.js +7 -2
- package/lib/utils/patch-yaml.d.ts +25 -0
- package/lib/utils/patch-yaml.js +62 -0
- package/lib/utils/paths.d.ts +10 -1
- package/lib/utils/paths.js +24 -3
- package/lib/utils/recursive-walk.js +12 -13
- package/lib/utils/session-format.d.ts +35 -2
- package/lib/utils/session-format.js +131 -5
- package/lib/utils/session-health-scan.d.ts +7 -1
- package/lib/utils/session-health-scan.js +369 -12
- package/lib/utils/session-layout-repair-service.d.ts +98 -0
- package/lib/utils/session-layout-repair-service.js +457 -0
- package/lib/utils/session-log-repair.d.ts +27 -0
- package/lib/utils/session-log-repair.js +233 -62
- package/lib/utils/session-repair-service.d.ts +32 -3
- package/lib/utils/session-repair-service.js +148 -9
- package/lib/utils/session-row-facts.d.ts +73 -0
- package/lib/utils/session-row-facts.js +182 -0
- package/lib/utils/session-verify.d.ts +118 -0
- package/lib/utils/session-verify.js +705 -0
- package/lib/utils/shared-constants.d.ts +59 -0
- package/lib/utils/shared-constants.js +71 -0
- package/package.json +1 -1
- package/src/adapters/credentials.test.ts +27 -0
- package/src/adapters/credentials.ts +6 -3
- package/src/adapters/file-collection.ts +33 -8
- package/src/adapters/files.test.ts +222 -0
- package/src/adapters/mcp.test.ts +43 -0
- package/src/adapters/mcp.ts +37 -14
- package/src/adapters/plugin-files.ts +34 -4
- package/src/adapters/plugins.test.ts +241 -0
- package/src/adapters/plugins.ts +201 -53
- package/src/adapters/prompts.test.ts +49 -0
- package/src/adapters/prompts.ts +41 -20
- package/src/adapters/providers.test.ts +16 -0
- package/src/adapters/providers.ts +4 -3
- package/src/adapters/self.test.ts +77 -0
- package/src/adapters/self.ts +75 -0
- package/src/adapters/sessions.test.ts +77 -0
- package/src/adapters/sessions.ts +47 -1
- package/src/adapters/settings.test.ts +78 -0
- package/src/adapters/settings.ts +42 -6
- package/src/adapters/skills.ts +221 -3
- package/src/adapters/test-helpers.ts +43 -5
- package/src/adapters/workspaces-dup-id.test.ts +144 -0
- package/src/adapters/workspaces.test.ts +10 -0
- package/src/adapters/workspaces.ts +97 -5
- package/src/cli/actions.test.ts +117 -2
- package/src/cli/actions.ts +132 -12
- package/src/cli/help.ts +570 -0
- package/src/cli/import-source.test.ts +193 -0
- package/src/cli/import-source.ts +229 -0
- package/src/cli/index.ts +129 -94
- package/src/cli/web/client-script.ts +12 -0
- package/src/cli/web/console-fixes.test.ts +36 -0
- package/src/cli/web/http.ts +7 -1
- package/src/cli/web/page.ts +108 -25
- package/src/cli/web/routes.ts +23 -4
- package/src/cli/web/script-anchor.test.ts +33 -0
- package/src/cli/web/server.ts +28 -2
- package/src/cli/web/web.test.ts +447 -4
- package/src/client/ConfigManagerSection.tsx +118 -63
- package/src/client/about/AboutPanel.tsx +42 -3
- package/src/client/about/PluginUpdateDialog.tsx +185 -0
- package/src/client/about/ReleaseBody.tsx +144 -0
- package/src/client/about/ReleaseNotesDialog.tsx +3 -130
- package/src/client/about/about-view.ts +7 -5
- package/src/client/about/plugin-update-view.test.ts +25 -0
- package/src/client/about/plugin-update-view.ts +26 -0
- package/src/client/about/release-notes-view.test.ts +33 -0
- package/src/client/about/release-notes-view.ts +34 -0
- package/src/client/api.ts +145 -1
- package/src/client/common/Icon.tsx +3 -0
- package/src/client/common/RunsCenter.tsx +8 -2
- package/src/client/common/Select.tsx +9 -2
- package/src/client/common/info-hint-guard.test.ts +63 -18
- package/src/client/common/plan-text-redaction.test.ts +193 -8
- package/src/client/common/routes.ts +15 -0
- package/src/client/config-manager.module.css +506 -354
- package/src/client/css-scale-guard.test.ts +122 -0
- package/src/client/css-token-guard.test.ts +82 -0
- package/src/client/environment/EnvironmentPanel.tsx +45 -16
- package/src/client/{snapshots → environment/maintenance}/DiskUsageCard.tsx +21 -17
- package/src/client/environment/profiles-incomplete-ui.test.ts +103 -0
- package/src/client/export/ExportView.tsx +9 -2
- package/src/client/{snapshots → home}/BackupScheduleCard.tsx +13 -4
- package/src/client/home/HomePanel.tsx +69 -157
- package/src/client/icon-layer-guard.test.ts +1 -1
- package/src/client/import/ForeignImportView.tsx +318 -0
- package/src/client/import/ImportWizardView.tsx +3 -1
- package/src/client/import/foreign-import-view-guard.test.ts +195 -0
- package/src/client/import/import-file-select.test.ts +6 -6
- package/src/client/import/import-wizard-steps.tsx +17 -1
- package/src/client/import/use-import-wizard-controller.ts +3 -3
- package/src/client/index.ts +1 -1
- package/src/client/library/LibraryActions.tsx +31 -34
- package/src/client/library/LibraryPanel.tsx +4 -1
- package/src/client/{snapshots → library}/RestorePlanView.tsx +1 -1
- package/src/client/{snapshots → library}/files-layout.test.ts +2 -2
- package/src/client/{snapshots → library}/report-dismiss.test.ts +26 -3
- package/src/client/library/task-panel-visibility.test.ts +25 -17
- package/src/client/locales.ts +278 -36
- package/src/client/lucide-icons.d.ts +1 -0
- package/src/client/market/MarketPanel.tsx +11 -2
- package/src/client/recovery/IncompleteCopiesSection.tsx +132 -0
- package/src/client/recovery/RecoveryPanel.tsx +486 -59
- package/src/client/recovery/recovery-api.ts +30 -0
- package/src/client/recovery/recovery-incomplete-copies.test.ts +151 -0
- package/src/client/recovery/recovery-locales.test.ts +88 -0
- package/src/client/recovery/recovery-locales.ts +321 -6
- package/src/client/recovery/recovery-panel-layout.test.ts +52 -0
- package/src/client/recovery/recovery-view.ts +92 -2
- package/src/client/run-store.test.ts +201 -89
- package/src/client/run-store.ts +114 -143
- package/src/client/session-export/session-export-view.test.ts +103 -0
- package/src/client/session-export/session-export-view.ts +118 -0
- package/src/client/sync/ChannelConfigDialog.tsx +219 -14
- package/src/client/sync/SyncChannelEntryCard.tsx +52 -4
- package/src/client/sync/SyncLogList.tsx +1 -1
- package/src/client/sync/SyncPanel.tsx +166 -102
- package/src/client/sync/SyncRepositoryPicker.tsx +216 -0
- package/src/client/sync/SyncSettingsView.test.ts +6 -1
- package/src/client/sync/history-model.test.ts +94 -57
- package/src/client/sync/history-model.ts +44 -25
- package/src/client/sync/sync-api.test.ts +56 -0
- package/src/client/sync/sync-api.ts +92 -0
- package/src/client/sync/sync-locales.ts +162 -2
- package/src/client/sync/sync-view.test.ts +3 -8
- package/src/client/sync/sync-view.ts +111 -21
- package/src/core/analyzer-cache.test.ts +47 -0
- package/src/core/analyzer.ts +115 -14
- package/src/core/backup-plan.test.ts +35 -0
- package/src/core/backup-plan.ts +19 -1
- package/src/core/backup.test.ts +37 -1
- package/src/core/backup.ts +27 -6
- package/src/core/cache-cleaner.test.ts +120 -1
- package/src/core/cache-cleaner.ts +59 -22
- package/src/core/checkpoint.test.ts +665 -0
- package/src/core/checkpoint.ts +1614 -0
- package/src/core/credential-plan-consistency.test.ts +93 -0
- package/src/core/incident-wiring.test.ts +6 -2
- package/src/core/journal.test.ts +70 -0
- package/src/core/journal.ts +68 -0
- package/src/core/messages.ts +26 -0
- package/src/core/model-tools.ts +3 -0
- package/src/core/patch-layers.test.ts +94 -0
- package/src/core/patch-layers.ts +150 -0
- package/src/core/restore.ts +59 -3
- package/src/core/rollback.ts +6 -3
- package/src/core/section-content-consistency.test.ts +185 -0
- package/src/core/self-update.test.ts +110 -0
- package/src/core/self-update.ts +118 -0
- package/src/core/session-health.test.ts +91 -1
- package/src/core/session-health.ts +56 -9
- package/src/core/types.ts +127 -1
- package/src/foreign/antigravity.test.ts +271 -0
- package/src/foreign/antigravity.ts +188 -0
- package/src/foreign/bundle.ts +108 -0
- package/src/foreign/chatgpt.test.ts +279 -0
- package/src/foreign/chatgpt.ts +30 -0
- package/src/foreign/claude-code.test.ts +234 -0
- package/src/foreign/claude-code.ts +106 -0
- package/src/foreign/claude-sessions-bytes.test.ts +227 -0
- package/src/foreign/claude-sessions.test.ts +180 -0
- package/src/foreign/claude-sessions.ts +461 -0
- package/src/foreign/cline.test.ts +274 -0
- package/src/foreign/cline.ts +32 -0
- package/src/foreign/codex.test.ts +585 -0
- package/src/foreign/codex.ts +409 -0
- package/src/foreign/continue.test.ts +365 -0
- package/src/foreign/continue.ts +73 -0
- package/src/foreign/copilot.test.ts +273 -0
- package/src/foreign/copilot.ts +133 -0
- package/src/foreign/crush.test.ts +234 -0
- package/src/foreign/crush.ts +66 -0
- package/src/foreign/cursor.test.ts +509 -0
- package/src/foreign/cursor.ts +259 -0
- package/src/foreign/dsh.test.ts +198 -0
- package/src/foreign/dsh.ts +117 -0
- package/src/foreign/dsh4.test.ts +127 -0
- package/src/foreign/dsh4.ts +15 -0
- package/src/foreign/file-budget.test.ts +256 -0
- package/src/foreign/fixtures/antigravity/README.md +18 -0
- package/src/foreign/fixtures/antigravity/basic/gemini/antigravity/mcp_config.json +13 -0
- package/src/foreign/fixtures/antigravity/basic/gemini/config/mcp_config.json +24 -0
- package/src/foreign/fixtures/antigravity/empty/gemini/antigravity/mcp_config.json +0 -0
- package/src/foreign/fixtures/antigravity/empty/gemini/antigravity/mcp_oauth_tokens.json +0 -0
- package/src/foreign/fixtures/antigravity/empty/gemini/config/mcp_config.json +0 -0
- package/src/foreign/fixtures/codex/README.md +31 -0
- package/src/foreign/fixtures/codex/basic/.agents/skills/hello/SKILL.md +6 -0
- package/src/foreign/fixtures/codex/basic/.agents/skills/wrapper/nested/SKILL.md +6 -0
- package/src/foreign/fixtures/codex/basic/.codex/AGENTS.md +4 -0
- package/src/foreign/fixtures/codex/basic/.codex/config.toml +28 -0
- package/src/foreign/fixtures/codex/malformed/.codex/config.toml +3 -0
- package/src/foreign/fixtures/codex/override/.codex/AGENTS.md +1 -0
- package/src/foreign/fixtures/codex/override/.codex/AGENTS.override.md +3 -0
- package/src/foreign/fixtures/codex/sessions/.codex/archived_sessions/rollout-2026-10-05T09-00-00-22222222-2222-4222-8222-222222222222.jsonl +2 -0
- package/src/foreign/fixtures/codex/sessions/.codex/sessions/2026/10/06/rollout-2026-10-06T10-00-00-11111111-1111-4111-8111-111111111111.jsonl +15 -0
- package/src/foreign/fixtures/codex/sessions/.codex/sessions/2026/10/06/rollout-2026-10-06T11-00-00-33333333-3333-4333-8333-333333333333.jsonl +2 -0
- package/src/foreign/fixtures/codex/sessions/.codex/sessions/2026/10/06/rollout-2026-10-06T11-30-00-55555555-5555-4555-8555-555555555555.jsonl +2 -0
- package/src/foreign/fixtures/codex/sessions/.codex/sessions/2026/10/06/rollout-2026-10-06T12-00-00-44444444-4444-4444-8444-444444444444.jsonl +2 -0
- package/src/foreign/fixtures/codex/sessions/.codex/sessions/notes.jsonl +1 -0
- package/src/foreign/fixtures/copilot/README.md +22 -0
- package/src/foreign/fixtures/copilot/basic/copilot-instructions.md +3 -0
- package/src/foreign/fixtures/copilot/basic/instructions/empty.instructions.md +1 -0
- package/src/foreign/fixtures/copilot/basic/instructions/repo.instructions.md +5 -0
- package/src/foreign/fixtures/copilot/basic/mcp-config.json +24 -0
- package/src/foreign/fixtures/copilot/basic/skills/hello/SKILL.md +6 -0
- package/src/foreign/fixtures/copilot/overridden/mcp-config.json +10 -0
- package/src/foreign/fixtures/cursor/README.md +17 -0
- package/src/foreign/fixtures/cursor/alt/.cursor/mcp.json +5 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/mcp.json +18 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/rules/agent.mdc +5 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/rules/always.mdc +6 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/rules/auto.mdc +7 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/rules/manual.mdc +3 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/skills/.hidden/SKILL.md +6 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/skills/hello/SKILL.md +6 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/skills/wrapper/nested/SKILL.md +6 -0
- package/src/foreign/fixtures/cursor/basic/.cursor/skills/wrapper/nested/notes.md +1 -0
- package/src/foreign/fixtures/cursor/basic/.cursorrules +1 -0
- package/src/foreign/fixtures/cursor/basic/project/.cursor/mcp.json +9 -0
- package/src/foreign/fixtures/cursor/basic/project/.cursor/rules/project-always.mdc +5 -0
- package/src/foreign/fixtures/cursor/basic/project/.cursor/skills/hello/SKILL.md +6 -0
- package/src/foreign/fixtures/cursor/basic/project/.cursorrules +1 -0
- package/src/foreign/fixtures/cursor/empty/.cursor/mcp.json +0 -0
- package/src/foreign/fixtures/cursor/malformed/.cursor/mcp.json +3 -0
- package/src/foreign/fixtures/cursor/malformed/.cursor/rules/broken.mdc +6 -0
- package/src/foreign/fixtures/cursor/shape/.cursor/mcp.json +3 -0
- package/src/foreign/fixtures/hermes/README.md +14 -0
- package/src/foreign/fixtures/hermes/basic/SOUL.md +3 -0
- package/src/foreign/fixtures/hermes/basic/config.yaml +48 -0
- package/src/foreign/fixtures/hermes/basic/dotenv.fixture +1 -0
- package/src/foreign/fixtures/hermes/basic/memories/MEMORY.md +1 -0
- package/src/foreign/fixtures/hermes/basic/memories/USER.md +1 -0
- package/src/foreign/fixtures/hermes/basic/skills/se-team-design/SKILL.md +6 -0
- package/src/foreign/fixtures/hermes/basic/skills/se-team-design/examples/usage.md +1 -0
- package/src/foreign/fixtures/hermes/basic/skills/software-development/dogfood/SKILL.md +6 -0
- package/src/foreign/fixtures/hermes/basic/skills/software-development/dogfood/notes.md +1 -0
- package/src/foreign/fixtures/hermes/basic/state.db +1 -0
- package/src/foreign/fixtures/hermes/empty/config.yaml +0 -0
- package/src/foreign/gemini.test.ts +291 -0
- package/src/foreign/gemini.ts +52 -0
- package/src/foreign/goose.test.ts +196 -0
- package/src/foreign/goose.ts +62 -0
- package/src/foreign/grokbuild.test.ts +246 -0
- package/src/foreign/grokbuild.ts +30 -0
- package/src/foreign/hermes.test.ts +545 -0
- package/src/foreign/hermes.ts +86 -0
- package/src/foreign/kernel-credentials.test.ts +88 -0
- package/src/foreign/kernel-workspaces.test.ts +88 -0
- package/src/foreign/kernel.ts +584 -0
- package/src/foreign/kilocode.test.ts +186 -0
- package/src/foreign/kilocode.ts +60 -0
- package/src/foreign/kimi.test.ts +259 -0
- package/src/foreign/kimi.ts +55 -0
- package/src/foreign/mcp-value-shape.test.ts +286 -0
- package/src/foreign/mimocode.test.ts +178 -0
- package/src/foreign/mimocode.ts +60 -0
- package/src/foreign/openclaw.test.ts +248 -0
- package/src/foreign/openclaw.ts +54 -0
- package/src/foreign/opencode.test.ts +376 -0
- package/src/foreign/opencode.ts +61 -0
- package/src/foreign/pi.test.ts +275 -0
- package/src/foreign/pi.ts +56 -0
- package/src/foreign/platform-paths.ts +156 -0
- package/src/foreign/qoder.test.ts +266 -0
- package/src/foreign/qoder.ts +57 -0
- package/src/foreign/qwen.test.ts +203 -0
- package/src/foreign/qwen.ts +53 -0
- package/src/foreign/read-antigravity.ts +569 -0
- package/src/foreign/read-chatgpt.ts +506 -0
- package/src/foreign/read-claude-code.ts +264 -0
- package/src/foreign/read-cline.ts +517 -0
- package/src/foreign/read-codex.ts +823 -0
- package/src/foreign/read-continue.ts +557 -0
- package/src/foreign/read-copilot.ts +304 -0
- package/src/foreign/read-crush.ts +503 -0
- package/src/foreign/read-cursor.ts +778 -0
- package/src/foreign/read-dsh.ts +215 -0
- package/src/foreign/read-dsh4.ts +35 -0
- package/src/foreign/read-gemini.ts +306 -0
- package/src/foreign/read-goose.ts +333 -0
- package/src/foreign/read-grokbuild.ts +475 -0
- package/src/foreign/read-hermes.ts +724 -0
- package/src/foreign/read-kilocode.ts +55 -0
- package/src/foreign/read-kimi.ts +768 -0
- package/src/foreign/read-mimocode.ts +66 -0
- package/src/foreign/read-openclaw.ts +505 -0
- package/src/foreign/read-opencode.ts +994 -0
- package/src/foreign/read-pi.ts +459 -0
- package/src/foreign/read-qoder.ts +351 -0
- package/src/foreign/read-qwen.ts +342 -0
- package/src/foreign/read-reasonix.ts +590 -0
- package/src/foreign/read-teleagent.ts +82 -0
- package/src/foreign/read-trae.ts +488 -0
- package/src/foreign/read-vibe.ts +353 -0
- package/src/foreign/read-workbuddy.ts +374 -0
- package/src/foreign/read-zcode.ts +48 -0
- package/src/foreign/read-zed.ts +479 -0
- package/src/foreign/reasonix.test.ts +336 -0
- package/src/foreign/reasonix.ts +25 -0
- package/src/foreign/registry.test.ts +377 -0
- package/src/foreign/registry.ts +750 -0
- package/src/foreign/session-ir.test.ts +189 -0
- package/src/foreign/session-ir.ts +614 -0
- package/src/foreign/session-read.ts +295 -0
- package/src/foreign/session-source.ts +625 -0
- package/src/foreign/skill-file-caps.test.ts +171 -0
- package/src/foreign/source-modules.ts +86 -0
- package/src/foreign/source-registry.test.ts +190 -0
- package/src/foreign/sqlite.test.ts +313 -0
- package/src/foreign/sqlite.ts +446 -0
- package/src/foreign/teleagent.test.ts +147 -0
- package/src/foreign/teleagent.ts +62 -0
- package/src/foreign/trae.test.ts +316 -0
- package/src/foreign/trae.ts +25 -0
- package/src/foreign/truncation-report.test.ts +238 -0
- package/src/foreign/truth-table.ts +453 -0
- package/src/foreign/types.ts +312 -0
- package/src/foreign/vibe.test.ts +209 -0
- package/src/foreign/vibe.ts +28 -0
- package/src/foreign/workbuddy.test.ts +207 -0
- package/src/foreign/workbuddy.ts +53 -0
- package/src/foreign/zcode.test.ts +224 -0
- package/src/foreign/zcode.ts +60 -0
- package/src/foreign/zed.test.ts +240 -0
- package/src/foreign/zed.ts +62 -0
- package/src/index.facade.test.ts +254 -16
- package/src/index.ts +704 -82
- package/src/market/github-repos.test.ts +98 -1
- package/src/market/github-repos.ts +63 -1
- package/src/market/types.ts +3 -3
- package/src/profiles/dsh-profile-incomplete-copy.test.ts +177 -0
- package/src/profiles/dsh-profile-manager.test.ts +37 -0
- package/src/profiles/dsh-profile-manager.ts +188 -13
- package/src/profiles/dsh-profile-shared.ts +55 -1
- package/src/profiles/index.ts +2 -1
- package/src/routes/consult.ts +53 -4
- package/src/routes/foreign-context.ts +89 -0
- package/src/routes/foreign.test.ts +443 -0
- package/src/routes/foreign.ts +226 -0
- package/src/routes/import.ts +23 -1
- package/src/routes/index.ts +6 -2
- package/src/routes/kit.ts +4 -3
- package/src/routes/market.ts +0 -1
- package/src/routes/prefs.ts +15 -1
- package/src/routes/recovery.test.ts +167 -0
- package/src/routes/recovery.ts +331 -1
- package/src/routes/session-export.ts +308 -0
- package/src/routes/snapshots.ts +12 -2
- package/src/routes/sync.ts +91 -7
- package/src/security/redaction.test.ts +149 -0
- package/src/security/redaction.ts +25 -9
- package/src/security/secret-scanner.test.ts +186 -0
- package/src/security/secret-scanner.ts +57 -1
- package/src/sync/autosync-risk-tier.test.ts +61 -0
- package/src/sync/autosync-scheduler.test.ts +48 -1
- package/src/sync/autosync-scheduler.ts +50 -26
- package/src/sync/backup-files.ts +5 -0
- package/src/sync/gist/gist-msgkeys-catalog.test.ts +33 -0
- package/src/sync/gist/gist-msgkeys.test.ts +71 -0
- package/src/sync/gist/gist-transport.test.ts +308 -0
- package/src/sync/gist/gist-transport.ts +550 -0
- package/src/sync/gist/messages.ts +49 -0
- package/src/sync/retention-prune-all-off.test.ts +50 -0
- package/src/sync/s3/cloud-config.test.ts +283 -0
- package/src/sync/s3/messages.ts +102 -0
- package/src/sync/s3/s3-delete-index-404.test.ts +170 -0
- package/src/sync/s3/s3-delete-index-unreadable.test.ts +141 -0
- package/src/sync/s3/s3-msgkeys.test.ts +101 -0
- package/src/sync/s3/s3-providers.ts +213 -0
- package/src/sync/s3/s3-transport.test.ts +394 -0
- package/src/sync/s3/s3-transport.ts +651 -0
- package/src/sync/s3/s3-upload-index-404.test.ts +171 -0
- package/src/sync/s3/sigv4.test.ts +219 -0
- package/src/sync/s3/sigv4.ts +283 -0
- package/src/sync/sync-config.test.ts +237 -5
- package/src/sync/sync-config.ts +841 -52
- package/src/sync/sync-engine-download-tombstone.test.ts +73 -0
- package/src/sync/sync-engine.ts +5 -3
- package/src/sync/sync-history.ts +1 -1
- package/src/sync/webdav/webdav-delete-index-404.test.ts +178 -0
- package/src/sync/webdav/webdav-delete-index-unreadable.test.ts +143 -0
- package/src/sync/webdav/webdav-msgkeys.test.ts +53 -0
- package/src/sync/webdav/webdav-transport.test.ts +9 -5
- package/src/sync/webdav/webdav-transport.ts +99 -17
- package/src/sync/webdav/webdav-upload-index-404.test.ts +177 -0
- package/src/ui/commands.test.ts +4 -1
- package/src/ui/commands.ts +46 -12
- package/src/ui/disk-usage-view.test.ts +63 -1
- package/src/ui/disk-usage-view.ts +93 -1
- package/src/ui/dsh-profiles-incomplete-view.test.ts +102 -0
- package/src/ui/dsh-profiles-view.ts +94 -0
- package/src/ui/foreign-view.test.ts +241 -0
- package/src/ui/foreign-view.ts +362 -0
- package/src/ui/i18n.ts +164 -0
- package/src/ui/mid-ellipsis.test.ts +5 -10
- package/src/ui/session-inventory-view.test.ts +142 -2
- package/src/ui/session-inventory-view.ts +127 -0
- package/src/ui/session-layout-view.test.ts +361 -0
- package/src/ui/session-layout-view.ts +444 -0
- package/src/ui/sync-repository-picker.test.ts +130 -0
- package/src/ui/sync-repository-picker.ts +180 -0
- package/src/ui/sync-settings-view.test.ts +166 -0
- package/src/ui/sync-settings-view.ts +319 -9
- package/src/ui/types.ts +42 -0
- package/src/utils/asar-read.test.ts +330 -0
- package/src/utils/asar-read.ts +606 -0
- package/src/utils/env-lock.test.ts +55 -0
- package/src/utils/env-lock.ts +6 -1
- package/src/utils/patch-yaml.test.ts +112 -0
- package/src/utils/patch-yaml.ts +72 -0
- package/src/utils/paths.test.ts +63 -0
- package/src/utils/paths.ts +25 -3
- package/src/utils/recursive-walk.test.ts +20 -0
- package/src/utils/recursive-walk.ts +12 -13
- package/src/utils/session-format.test.ts +113 -2
- package/src/utils/session-format.ts +127 -5
- package/src/utils/session-health-scan.test.ts +364 -1
- package/src/utils/session-health-scan.ts +434 -15
- package/src/utils/session-layout-repair-service.test.ts +362 -0
- package/src/utils/session-layout-repair-service.ts +568 -0
- package/src/utils/session-log-repair.test.ts +260 -1
- package/src/utils/session-log-repair.ts +294 -55
- package/src/utils/session-repair-service.test.ts +148 -1
- package/src/utils/session-repair-service.ts +165 -10
- package/src/utils/session-row-facts.test.ts +159 -0
- package/src/utils/session-row-facts.ts +187 -0
- package/src/utils/session-verify.test.ts +762 -0
- package/src/utils/session-verify.ts +784 -0
- package/src/utils/shared-constants.ts +82 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 手写 SigV4 签名(AWS SigV4 / 阿里云 OSS4),零第三方依赖(node:crypto 足够)。
|
|
3
|
+
*
|
|
4
|
+
* 为什么手写:竞品 \`@dickpy/dsh-cloud-sync\` v0.20.9(零依赖、lib 2610 行)证明五家 S3 兼容
|
|
5
|
+
* 对象存储共用同一套「派生密钥 → 规范化请求 → 待签字符串 → HMAC」流程,差异只在**方言参数**:
|
|
6
|
+
* - AWS S3 / MinIO / 腾讯云 COS / 七牛 Kodo:\`AWS4-HMAC-SHA256\` + \`x-amz-date\` +
|
|
7
|
+
* \`x-amz-content-sha256\`(载荷 SHA-256 十六进制)+ scope 终止符 \`aws4_request\`,
|
|
8
|
+
* 授权头里用 \`SignedHeaders=host;x-amz-date;...\`(**全部**已发头参与规范化);
|
|
9
|
+
* - 阿里云 OSS:\`OSS4-HMAC-SHA256\` + \`x-oss-date\` + \`x-oss-content-sha256: UNSIGNED-PAYLOAD\`
|
|
10
|
+
* + 派生密钥前缀 \`aliyun_v4\` + 终止符 \`aliyun_v4_request\`,授权头里用
|
|
11
|
+
* \`AdditionalHeaders=<可选头>\`,且**只有** \`content-type\`/\`content-md5\`/\`x-oss-*\` 参与规范化头
|
|
12
|
+
* (\`host\` 默认不参与)。依据 = 阿里云《在 Header 中包含 V4 签名》+ 官方 SDK
|
|
13
|
+
* \`aliyun-oss-java-sdk\` 的 \`OSSV4Signer\`(2026-10 读码确证)。
|
|
14
|
+
* 因此本文件把「同一实现 + 方言参数表」落成 \`SigV4Dialect\`:新增同类厂商只加一行参数。
|
|
15
|
+
*
|
|
16
|
+
* 纪律:
|
|
17
|
+
* - 纯函数 + 可注入时间(\`now\`),同一输入两次签名**逐字相同**(单测钉住);
|
|
18
|
+
* - secretAccessKey 只在内存里参与 HMAC,绝不写入返回值之外的任何地方,也绝不进日志;
|
|
19
|
+
* - 不做任何 I/O:请求头的注入与发送由通道层(s3-transport)负责。
|
|
20
|
+
*/
|
|
21
|
+
import { createHash, createHmac } from 'node:crypto';
|
|
22
|
+
/** 「不校验载荷」的载荷哈希字面量(OSS4 目前只支持该取值)。 */
|
|
23
|
+
export const UNSIGNED_PAYLOAD = 'UNSIGNED-PAYLOAD';
|
|
24
|
+
/** AWS SigV4(S3 / MinIO / COS / Kodo 共用)。 */
|
|
25
|
+
export const AWS_SIG_V4 = {
|
|
26
|
+
id: 'aws4',
|
|
27
|
+
algorithm: 'AWS4-HMAC-SHA256',
|
|
28
|
+
dateHeader: 'x-amz-date',
|
|
29
|
+
contentShaHeader: 'x-amz-content-sha256',
|
|
30
|
+
secretKeyPrefix: 'AWS4',
|
|
31
|
+
terminator: 'aws4_request',
|
|
32
|
+
headerSelection: 'all',
|
|
33
|
+
payloadHash: 'sha256',
|
|
34
|
+
headerListLabel: 'SignedHeaders',
|
|
35
|
+
};
|
|
36
|
+
/** 阿里云 OSS4(OSS 原生 V4;与 AWS 同构但头名/前缀/终止符/载荷形态不同)。 */
|
|
37
|
+
export const OSS_SIG_V4 = {
|
|
38
|
+
id: 'oss4',
|
|
39
|
+
algorithm: 'OSS4-HMAC-SHA256',
|
|
40
|
+
dateHeader: 'x-oss-date',
|
|
41
|
+
contentShaHeader: 'x-oss-content-sha256',
|
|
42
|
+
secretKeyPrefix: 'aliyun_v4',
|
|
43
|
+
terminator: 'aliyun_v4_request',
|
|
44
|
+
headerSelection: 'oss-default',
|
|
45
|
+
payloadHash: 'unsigned',
|
|
46
|
+
headerListLabel: 'AdditionalHeaders',
|
|
47
|
+
};
|
|
48
|
+
/** 方言查表(非法 id 抛错:绝不静默回落成 AWS,否则 OSS 会以「签名不对」的形式失败)。 */
|
|
49
|
+
export function sigV4Dialect(id) {
|
|
50
|
+
if (id === 'aws4')
|
|
51
|
+
return AWS_SIG_V4;
|
|
52
|
+
if (id === 'oss4')
|
|
53
|
+
return OSS_SIG_V4;
|
|
54
|
+
throw new Error('未知签名方言: ' + String(id));
|
|
55
|
+
}
|
|
56
|
+
/** SHA-256 十六进制小写。 */
|
|
57
|
+
export function sha256Hex(data) {
|
|
58
|
+
return createHash('sha256').update(data).digest('hex');
|
|
59
|
+
}
|
|
60
|
+
/** HMAC-SHA256(返回 Buffer,供逐层派生密钥)。 */
|
|
61
|
+
export function hmacSha256(key, data) {
|
|
62
|
+
return createHmac('sha256', key).update(data, 'utf8').digest();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 逐层派生签名密钥:prefix+secret → date → region → service → terminator(RFC/厂商文档同构)。
|
|
66
|
+
* AWS:AWS4+SK → dateStamp → region → service → aws4_request;
|
|
67
|
+
* OSS:aliyun_v4+SK → dateStamp → region → oss → aliyun_v4_request。
|
|
68
|
+
*/
|
|
69
|
+
export function deriveSigningKey(params) {
|
|
70
|
+
const kDate = hmacSha256(params.dialect.secretKeyPrefix + params.secretAccessKey, params.dateStamp);
|
|
71
|
+
const kRegion = hmacSha256(kDate, params.region);
|
|
72
|
+
const kService = hmacSha256(kRegion, params.service);
|
|
73
|
+
return hmacSha256(kService, params.dialect.terminator);
|
|
74
|
+
}
|
|
75
|
+
/** 签名时刻格式 \`YYYYMMDDTHHMMSSZ\`(UTC)。 */
|
|
76
|
+
export function formatAmzDate(date) {
|
|
77
|
+
const iso = date.toISOString(); // 2026-10-05T01:49:10.000Z
|
|
78
|
+
const datePart = iso.slice(0, 10).split('-').join('');
|
|
79
|
+
const timePart = iso.slice(11, 19).split(':').join('');
|
|
80
|
+
return datePart + 'T' + timePart + 'Z';
|
|
81
|
+
}
|
|
82
|
+
/** 签名日期段 \`YYYYMMDD\`(UTC)。 */
|
|
83
|
+
export function formatDateStamp(amzDate) {
|
|
84
|
+
return amzDate.slice(0, 8);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* URI 编码(RFC 3986 未保留字符集 A-Za-z0-9-_.~ 之外一律 %XX 大写)。
|
|
88
|
+
* \`encodeSlash=false\` 时保留路径分隔符(规范化 URI 用),其余场景(查询串)编码它。
|
|
89
|
+
*/
|
|
90
|
+
export function uriEncode(value, encodeSlash) {
|
|
91
|
+
const bytes = Buffer.from(value, 'utf8');
|
|
92
|
+
let out = '';
|
|
93
|
+
for (const byte of bytes) {
|
|
94
|
+
const ch = String.fromCharCode(byte);
|
|
95
|
+
const unreserved = (byte >= 0x41 && byte <= 0x5a) || (byte >= 0x61 && byte <= 0x7a)
|
|
96
|
+
|| (byte >= 0x30 && byte <= 0x39) || ch === '-' || ch === '_' || ch === '.' || ch === '~';
|
|
97
|
+
if (unreserved)
|
|
98
|
+
out += ch;
|
|
99
|
+
else if (ch === '/' && !encodeSlash)
|
|
100
|
+
out += '/';
|
|
101
|
+
else
|
|
102
|
+
out += '%' + byte.toString(16).toUpperCase().padStart(2, '0');
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
/** 安全百分号解码(非法转义原样返回,绝不抛错)。 */
|
|
107
|
+
function safeDecode(value) {
|
|
108
|
+
try {
|
|
109
|
+
return decodeURIComponent(value);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/** 规范化 URI:先解码再逐段编码(避免 URL 归一化后的二次编码),保留分隔符。 */
|
|
116
|
+
export function canonicalUri(pathname) {
|
|
117
|
+
const path = pathname === '' ? '/' : pathname;
|
|
118
|
+
return path.split('/').map((seg) => uriEncode(safeDecode(seg), true)).join('/');
|
|
119
|
+
}
|
|
120
|
+
/** 规范化查询串:按「编码后的键、编码后的值」字典序排序,空值写成 \`key=\`。 */
|
|
121
|
+
export function canonicalQueryString(searchParams) {
|
|
122
|
+
const pairs = [];
|
|
123
|
+
for (const [rawKey, rawValue] of searchParams) {
|
|
124
|
+
pairs.push({ key: uriEncode(rawKey, true), value: uriEncode(rawValue, true) });
|
|
125
|
+
}
|
|
126
|
+
pairs.sort((a, b) => (a.key < b.key ? -1 : a.key > b.key ? 1 : (a.value < b.value ? -1 : a.value > b.value ? 1 : 0)));
|
|
127
|
+
return pairs.map((p) => p.key + '=' + p.value).join('&');
|
|
128
|
+
}
|
|
129
|
+
/** 头值归一:去首尾空白 + 内部连续空白折叠成单空格(SigV4 要求)。 */
|
|
130
|
+
function trimHeaderValue(value) {
|
|
131
|
+
return value.trim().replace(/\s+/g, ' ');
|
|
132
|
+
}
|
|
133
|
+
/** 该头是否按方言参与规范化头集合。 */
|
|
134
|
+
function participates(name, dialect, additional) {
|
|
135
|
+
if (dialect.headerSelection === 'all')
|
|
136
|
+
return true;
|
|
137
|
+
// OSS4:content-type / content-md5 / x-oss-* 默认参与;其余必须是显式附加头
|
|
138
|
+
return name === 'content-type' || name === 'content-md5' || name.startsWith('x-oss-') || additional.includes(name);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 计算一次请求的 SigV4 签名并返回待注入的头。
|
|
142
|
+
* 幂等且无副作用:同一输入(含同一 now)两次调用逐字相同。
|
|
143
|
+
*/
|
|
144
|
+
export function signRequest(input) {
|
|
145
|
+
const dialect = input.dialect;
|
|
146
|
+
const url = new URL(input.url);
|
|
147
|
+
const amzDate = formatAmzDate(input.now ?? new Date());
|
|
148
|
+
const dateStamp = formatDateStamp(amzDate);
|
|
149
|
+
const payloadHash = dialect.payloadHash === 'unsigned'
|
|
150
|
+
? UNSIGNED_PAYLOAD
|
|
151
|
+
: sha256Hex(input.body ?? new Uint8Array(0));
|
|
152
|
+
const additional = (input.additionalSignedHeaders ?? []).map((h) => h.toLowerCase());
|
|
153
|
+
const all = { host: url.host };
|
|
154
|
+
for (const [key, value] of Object.entries(input.headers ?? {}))
|
|
155
|
+
all[key.toLowerCase()] = value;
|
|
156
|
+
all[dialect.dateHeader] = amzDate;
|
|
157
|
+
if (input.includeContentShaHeader !== false)
|
|
158
|
+
all[dialect.contentShaHeader] = payloadHash;
|
|
159
|
+
const names = Object.keys(all).filter((n) => participates(n, dialect, additional)).sort();
|
|
160
|
+
const canonicalHeaderBlock = names.map((n) => n + ':' + trimHeaderValue(all[n] ?? '') + '\n').join('');
|
|
161
|
+
// AWS:SignedHeaders = 参与规范化的全部头;OSS4:AdditionalHeaders = 仅显式附加的可选头
|
|
162
|
+
const headerList = dialect.headerSelection === 'all'
|
|
163
|
+
? names.join(';')
|
|
164
|
+
: additional.filter((n) => names.includes(n)).sort().join(';');
|
|
165
|
+
const canonicalRequest = [
|
|
166
|
+
input.method.toUpperCase(),
|
|
167
|
+
canonicalUri(url.pathname),
|
|
168
|
+
canonicalQueryString(url.searchParams),
|
|
169
|
+
canonicalHeaderBlock,
|
|
170
|
+
headerList,
|
|
171
|
+
payloadHash,
|
|
172
|
+
].join('\n');
|
|
173
|
+
const credentialScope = [dateStamp, input.region, input.service, dialect.terminator].join('/');
|
|
174
|
+
const stringToSign = [dialect.algorithm, amzDate, credentialScope, sha256Hex(canonicalRequest)].join('\n');
|
|
175
|
+
const signingKey = deriveSigningKey({
|
|
176
|
+
secretAccessKey: input.secretAccessKey,
|
|
177
|
+
dateStamp,
|
|
178
|
+
region: input.region,
|
|
179
|
+
service: input.service,
|
|
180
|
+
dialect,
|
|
181
|
+
});
|
|
182
|
+
const signature = createHmac('sha256', signingKey).update(stringToSign, 'utf8').digest('hex');
|
|
183
|
+
const authorization = dialect.algorithm + ' Credential=' + input.accessKeyId + '/' + credentialScope
|
|
184
|
+
+ ', ' + dialect.headerListLabel + '=' + headerList + ', Signature=' + signature;
|
|
185
|
+
return {
|
|
186
|
+
headers: { ...all, authorization },
|
|
187
|
+
authorization,
|
|
188
|
+
canonicalRequest,
|
|
189
|
+
stringToSign,
|
|
190
|
+
credentialScope,
|
|
191
|
+
signature,
|
|
192
|
+
signedHeaders: headerList,
|
|
193
|
+
payloadHash,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=sigv4.js.map
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import type { MsgFunc } from '../core/messages.ts';
|
|
2
|
+
import { SYNC_CHANNELS } from '../utils/shared-constants.ts';
|
|
3
|
+
import { S3_COMPAT_PROVIDERS, GIST_PROVIDER, CLOUD_SYNC_PROVIDERS } from '../utils/shared-constants.ts';
|
|
4
|
+
import type { S3CompatProvider, GistProvider, CloudSyncProvider } from '../utils/shared-constants.ts';
|
|
5
|
+
import type { SigV4DialectId } from './s3/sigv4.ts';
|
|
2
6
|
export declare const SYNC_CONFIG_FILE = "sync-config.json";
|
|
3
7
|
/**
|
|
4
|
-
*
|
|
8
|
+
* 同步通道枚举(**唯一事实源**,t32):所有「有哪些通道 / 通道列表 / 通道判定」的唯一来源。
|
|
9
|
+
*
|
|
10
|
+
* 声明处 = `src/utils/shared-constants.ts`(**零依赖**:client 半可运行时 import 而不带进
|
|
11
|
+
* node 模块);本文件 re-export,宿主侧沿用既有 import 路径即可。
|
|
5
12
|
*
|
|
6
13
|
* 为什么要单一来源:此前 SyncTransportType 在 sync-config / ui-prefs / client sync-api /
|
|
7
14
|
* client sync-view 各自声明一遍,通道数组也在 autosync-scheduler 里写了两遍 ——「改一处漏一处」
|
|
8
|
-
* 的表现是某个通道**静默**不再排期 /
|
|
15
|
+
* 的表现是某个通道**静默**不再排期 / 不再落盘,而不是报错。新增通道只改声明处:typecheck 会在
|
|
9
16
|
* 所有 Record<SyncTransportType, X> 的构造处与穷尽检查处报错。
|
|
10
17
|
*/
|
|
11
|
-
export
|
|
18
|
+
export { SYNC_CHANNELS };
|
|
12
19
|
/** 同步通道类型(由 SYNC_CHANNELS 派生;host 侧与 client 半统一引用)。 */
|
|
13
20
|
export type SyncTransportType = (typeof SYNC_CHANNELS)[number];
|
|
14
21
|
/** 通道值守卫(用于请求体 / localStorage / 磁盘 JSON 的原始输入校验)。 */
|
|
@@ -48,6 +55,10 @@ export interface FullSyncConfig {
|
|
|
48
55
|
transport: SyncTransportType;
|
|
49
56
|
git?: GitConfig;
|
|
50
57
|
webdav?: WebDavConfig;
|
|
58
|
+
/** 云端点通道 s3(活动兼容商;只有非密字段 + 密钥标记,绝无密钥值) */
|
|
59
|
+
s3?: S3ChannelConfig;
|
|
60
|
+
/** 云端点通道 gist(只有非密字段 + 密钥标记,绝无 token 值) */
|
|
61
|
+
gist?: GistChannelConfig;
|
|
51
62
|
}
|
|
52
63
|
/** 持久化的同步通道配置:可辨识联合(schemaVersion 恒 2) */
|
|
53
64
|
export type SyncConfig = {
|
|
@@ -58,6 +69,14 @@ export type SyncConfig = {
|
|
|
58
69
|
schemaVersion: 2;
|
|
59
70
|
transport: 'webdav';
|
|
60
71
|
webdav: WebDavConfig;
|
|
72
|
+
} | {
|
|
73
|
+
schemaVersion: 2;
|
|
74
|
+
transport: 's3';
|
|
75
|
+
s3: S3ChannelConfig;
|
|
76
|
+
} | {
|
|
77
|
+
schemaVersion: 2;
|
|
78
|
+
transport: 'gist';
|
|
79
|
+
gist: GistChannelConfig;
|
|
61
80
|
};
|
|
62
81
|
/** git 通道守卫 */
|
|
63
82
|
export declare function isGitConfig(cfg: SyncConfig): cfg is Extract<SyncConfig, {
|
|
@@ -67,6 +86,14 @@ export declare function isGitConfig(cfg: SyncConfig): cfg is Extract<SyncConfig,
|
|
|
67
86
|
export declare function isWebDavConfig(cfg: SyncConfig): cfg is Extract<SyncConfig, {
|
|
68
87
|
transport: 'webdav';
|
|
69
88
|
}>;
|
|
89
|
+
/** s3 通道守卫(provider 在 cfg.s3.provider:s3 / oss / cos / minio / kodo) */
|
|
90
|
+
export declare function isS3Config(cfg: SyncConfig): cfg is Extract<SyncConfig, {
|
|
91
|
+
transport: 's3';
|
|
92
|
+
}>;
|
|
93
|
+
/** gist 通道守卫 */
|
|
94
|
+
export declare function isGistConfig(cfg: SyncConfig): cfg is Extract<SyncConfig, {
|
|
95
|
+
transport: 'gist';
|
|
96
|
+
}>;
|
|
70
97
|
/**
|
|
71
98
|
* 读取同步通道配置;文件不存在/损坏/不支持 schema → null(视为未配置,UI 显示空表单)。
|
|
72
99
|
* 兼容旧文件:缺 schemaVersion 字段视为 v1(git 通道)。
|
|
@@ -89,7 +116,7 @@ export declare function readSyncConfigFor(dir: string, channel: SyncTransportTyp
|
|
|
89
116
|
* - 另一通道之前配置过 → 一并保留(切换通道不丢失另一通道的 repoUrl/url);
|
|
90
117
|
* - 覆盖旧值;未配置过的字段不写入。
|
|
91
118
|
*/
|
|
92
|
-
export declare function writeSyncConfig(dir: string, cfg: SyncConfig): Promise<void>;
|
|
119
|
+
export declare function writeSyncConfig(dir: string, cfg: SyncConfig, secrets?: CloudSecretWriter): Promise<void>;
|
|
93
120
|
/** 断开单条通道配置的结果(供路由层决定凭据/自动同步/UI 偏好怎么收尾)。 */
|
|
94
121
|
export interface ClearSyncChannelResult {
|
|
95
122
|
/** 该通道之前是否有配置;false = 本来就没配(幂等成功,不算失败) */
|
|
@@ -127,3 +154,222 @@ export declare function validateRepoUrl(repoUrl: string, msg?: MsgFunc): string
|
|
|
127
154
|
* (username[:password]@)的地址,引导用户把口令放 DSH credentials,避免凭据经 URL 泄漏进出入口/日志。
|
|
128
155
|
*/
|
|
129
156
|
export declare function validateWebDavUrl(url: string, msg?: MsgFunc): string | null;
|
|
157
|
+
/** 云端点通道配置文件名(与 sync-config.json 并列,互不影响)。 */
|
|
158
|
+
export declare const CLOUD_SYNC_CONFIG_FILE = "sync-cloud-config.json";
|
|
159
|
+
/** 云端点配置 schema 版本。 */
|
|
160
|
+
export declare const CLOUD_SYNC_CONFIG_SCHEMA_VERSION = 1;
|
|
161
|
+
/**
|
|
162
|
+
* S3 兼容系通道枚举(**唯一声明处已迁到零依赖的 `utils/shared-constants.ts` 的 S3_COMPAT_PROVIDERS**,t88):
|
|
163
|
+
* 五家共用同一份 SigV4 实现,差异只有 endpoint / region / 寻址风格 / 签名方言
|
|
164
|
+
* (见 src/sync/s3/s3-providers.ts 的变体表)。
|
|
165
|
+
*/
|
|
166
|
+
export { S3_COMPAT_PROVIDERS, GIST_PROVIDER, CLOUD_SYNC_PROVIDERS };
|
|
167
|
+
export type { S3CompatProvider, GistProvider, CloudSyncProvider };
|
|
168
|
+
/** 通道值守卫(请求体 / 磁盘 JSON 的原始输入校验)。 */
|
|
169
|
+
export declare function isCloudSyncProvider(value: unknown): value is CloudSyncProvider;
|
|
170
|
+
/** 是否 S3 兼容系通道。 */
|
|
171
|
+
export declare function isS3CompatProvider(value: unknown): value is S3CompatProvider;
|
|
172
|
+
/** 是否 Gist 通道。 */
|
|
173
|
+
export declare function isGistProvider(value: unknown): value is GistProvider;
|
|
174
|
+
/**
|
|
175
|
+
/**
|
|
176
|
+
* 取某云端点通道的密钥槽位引用(不涉及任何值)。
|
|
177
|
+
*
|
|
178
|
+
* 表本身在零依赖的 utils/shared-constants.ts(**唯一声明处**,t88):客户端要显示同一个名字
|
|
179
|
+
* (cloudSecretRefName()),两侧各写一份时「宿主改名、界面还提示旧名」不会红。
|
|
180
|
+
* 命名与既有 syncPasswordRef 同族:DSH_CONFIG_MANAGER_SYNC_<CHANNEL>_<KIND>。
|
|
181
|
+
*/
|
|
182
|
+
export declare function cloudSecretRef(provider: CloudSyncProvider): string;
|
|
183
|
+
/**
|
|
184
|
+
* 密钥**只写**端口:故意不提供 get()——宿主只能写、只能问「有没有」,
|
|
185
|
+
* 通道实现与 UI 都不可能把值回读出来(这是「只写不回读」的结构性保证,不靠纪律)。
|
|
186
|
+
*/
|
|
187
|
+
export interface CloudSecretWriter {
|
|
188
|
+
/** 写入密钥值(仅内存传递;不落盘、不进日志、不回传) */
|
|
189
|
+
set(ref: string, value: string): Promise<void>;
|
|
190
|
+
/** 只问「该槽位有没有值」(绝不返回值本身) */
|
|
191
|
+
has(ref: string): Promise<boolean>;
|
|
192
|
+
}
|
|
193
|
+
/** S3 兼容系通道的非密配置(值里绝不含 AccessKey Secret)。 */
|
|
194
|
+
export interface CloudS3ChannelConfig {
|
|
195
|
+
/** 对象存储端点(http(s),不含凭据、不含桶名;如 https://s3.us-east-1.amazonaws.com) */
|
|
196
|
+
endpoint: string;
|
|
197
|
+
/** V4 签名作用域里的 region(如 us-east-1 / cn-hangzhou / ap-guangzhou) */
|
|
198
|
+
region: string;
|
|
199
|
+
/** 桶名 */
|
|
200
|
+
bucket: string;
|
|
201
|
+
/** 对象键前缀(缺省 dsh-config-manager) */
|
|
202
|
+
prefix?: string;
|
|
203
|
+
/** AccessKey ID(标识符,可回显;**不是**密钥) */
|
|
204
|
+
accessKeyId: string;
|
|
205
|
+
/** path-style 寻址开关(缺省取变体默认:MinIO true,其余 false) */
|
|
206
|
+
pathStyle?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* 显式覆盖变体默认签名方言(缺省 = provider 变体默认;'aws4' = AWS SigV4,'oss4' = 阿里云 OSS4)。
|
|
209
|
+
* 非法的值在解析期被忽略(回落变体默认)—— 该字段是高级覆盖,不是配置错误来源。
|
|
210
|
+
*/
|
|
211
|
+
dialectId?: SigV4DialectId;
|
|
212
|
+
/** 密钥是否已在 DSH credentials 里(**只回标记,不回值**) */
|
|
213
|
+
secretStored?: boolean;
|
|
214
|
+
}
|
|
215
|
+
/** Gist 通道的非密配置(值里绝不含 token)。 */
|
|
216
|
+
export interface CloudGistChannelConfig {
|
|
217
|
+
/** 目标 gist id(十六进制串) */
|
|
218
|
+
gistId: string;
|
|
219
|
+
/** GitHub API 根(缺省 https://api.github.com;GitHub Enterprise 可改) */
|
|
220
|
+
apiBaseUrl?: string;
|
|
221
|
+
/** gist 内文件名前缀(缺省 dsh-sync) */
|
|
222
|
+
filePrefix?: string;
|
|
223
|
+
/** token 是否已在 DSH credentials 里(**只回标记,不回值**) */
|
|
224
|
+
secretStored?: boolean;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* s3 通道(SYNC_CHANNELS 的 's3')的配置 = 具体兼容商的非密配置 + provider 身份。
|
|
228
|
+
* 密钥值绝不在此(只在 DSH credentials 的 cloudSecretRef(provider) 槽位)。
|
|
229
|
+
*/
|
|
230
|
+
export interface S3ChannelConfig extends CloudS3ChannelConfig {
|
|
231
|
+
/** 具体 S3 兼容商(s3 / oss / cos / minio / kodo) */
|
|
232
|
+
provider: S3CompatProvider;
|
|
233
|
+
}
|
|
234
|
+
/** gist 通道(SYNC_CHANNELS 的 'gist')的配置:非密字段;token 只在 DSH credentials。 */
|
|
235
|
+
export type GistChannelConfig = CloudGistChannelConfig;
|
|
236
|
+
/**
|
|
237
|
+
* 每个云端点**通道**当前选用的 provider(保存即选定;断开即移除)。
|
|
238
|
+
* s3 通道 → 五家兼容商之一;gist 通道 → 恒 'gist'。
|
|
239
|
+
* 与 savedProviders 的分工:savedProviders 是「切换 provider 时能自动回填」的记忆,
|
|
240
|
+
* 本字段回答「这条通道现在用哪一个」。
|
|
241
|
+
*/
|
|
242
|
+
export interface CloudActiveProviders {
|
|
243
|
+
s3?: S3CompatProvider;
|
|
244
|
+
gist?: GistProvider;
|
|
245
|
+
}
|
|
246
|
+
/** 按通道分别保存的非密配置(照 cloud-sync 的 savedProviders 模式)。 */
|
|
247
|
+
export interface CloudSavedProviders {
|
|
248
|
+
s3?: CloudS3ChannelConfig;
|
|
249
|
+
oss?: CloudS3ChannelConfig;
|
|
250
|
+
cos?: CloudS3ChannelConfig;
|
|
251
|
+
minio?: CloudS3ChannelConfig;
|
|
252
|
+
kodo?: CloudS3ChannelConfig;
|
|
253
|
+
gist?: CloudGistChannelConfig;
|
|
254
|
+
}
|
|
255
|
+
/** 磁盘上的云端点配置(读侧恒归一为该形态;损坏/不支持的版本 → null)。 */
|
|
256
|
+
export interface CloudSyncConfig {
|
|
257
|
+
schemaVersion: number;
|
|
258
|
+
savedProviders: CloudSavedProviders;
|
|
259
|
+
/** 每条云端点通道当前选用的 provider(缺省 = 旧文件,读侧按「唯一已保存者」推断) */
|
|
260
|
+
active?: CloudActiveProviders;
|
|
261
|
+
}
|
|
262
|
+
/** 某通道读出来的配置(按 provider 收窄的联合)。 */
|
|
263
|
+
export type CloudChannelConfig = {
|
|
264
|
+
provider: S3CompatProvider;
|
|
265
|
+
config: CloudS3ChannelConfig;
|
|
266
|
+
} | {
|
|
267
|
+
provider: GistProvider;
|
|
268
|
+
config: CloudGistChannelConfig;
|
|
269
|
+
};
|
|
270
|
+
/** S3 兼容系通道的回传视图:**只带 secretStored 标记,绝不带密钥值**。 */
|
|
271
|
+
export interface CloudS3ChannelView {
|
|
272
|
+
provider: S3CompatProvider;
|
|
273
|
+
endpoint: string;
|
|
274
|
+
region: string;
|
|
275
|
+
bucket: string;
|
|
276
|
+
prefix: string;
|
|
277
|
+
accessKeyId: string;
|
|
278
|
+
pathStyle: boolean;
|
|
279
|
+
/** 密钥已在 credentials 里(只回布尔) */
|
|
280
|
+
secretStored: boolean;
|
|
281
|
+
}
|
|
282
|
+
/** Gist 通道的回传视图:**只带 secretStored 标记,绝不带 token 值**。 */
|
|
283
|
+
export interface CloudGistChannelView {
|
|
284
|
+
provider: GistProvider;
|
|
285
|
+
gistId: string;
|
|
286
|
+
apiBaseUrl: string;
|
|
287
|
+
filePrefix: string;
|
|
288
|
+
secretStored: boolean;
|
|
289
|
+
}
|
|
290
|
+
/** 回传 UI 的通道视图(按 provider 收窄的联合) */
|
|
291
|
+
export type CloudChannelView = CloudS3ChannelView | CloudGistChannelView;
|
|
292
|
+
/** 写入入参(表单原样;字段按 provider 各自校验)。 */
|
|
293
|
+
export interface CloudChannelWriteInput {
|
|
294
|
+
endpoint?: string;
|
|
295
|
+
region?: string;
|
|
296
|
+
bucket?: string;
|
|
297
|
+
prefix?: string;
|
|
298
|
+
accessKeyId?: string;
|
|
299
|
+
pathStyle?: boolean;
|
|
300
|
+
/** 显式覆盖签名方言(可缺省;仅 'aws4' | 'oss4' 被接受) */
|
|
301
|
+
dialectId?: SigV4DialectId;
|
|
302
|
+
gistId?: string;
|
|
303
|
+
apiBaseUrl?: string;
|
|
304
|
+
filePrefix?: string;
|
|
305
|
+
/** 明文密钥:**只写**(提供即写入 credentials);缺省 = 只更新非密字段,已有密钥不动 */
|
|
306
|
+
secret?: string;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* 云端点配置的**稳定错误码**(不是用户文案)。
|
|
310
|
+
* 与 \`validateRepoUrl\` 返回 \`'repoUrl is required'\` 同口径:码由路由/UI 层映射进字典,
|
|
311
|
+
* 因此本模块不产生任何用户可见字符串。
|
|
312
|
+
*/
|
|
313
|
+
export type CloudConfigIssueCode = 'cloud.providerUnknown' | 'cloud.endpointRequired' | 'cloud.endpointInvalid' | 'cloud.endpointUserinfo' | 'cloud.regionRequired' | 'cloud.bucketRequired' | 'cloud.bucketInvalid' | 'cloud.prefixInvalid' | 'cloud.accessKeyIdRequired' | 'cloud.gistIdRequired' | 'cloud.gistIdInvalid' | 'cloud.apiBaseUrlInvalid' | 'cloud.secretWriterRequired';
|
|
314
|
+
/** 配置校验失败:携带稳定错误码(无用户文案),由上层映射成字典键。 */
|
|
315
|
+
export declare class CloudConfigError extends Error {
|
|
316
|
+
readonly code: CloudConfigIssueCode;
|
|
317
|
+
constructor(code: CloudConfigIssueCode, detail?: string);
|
|
318
|
+
}
|
|
319
|
+
/** 端点校验(http(s)、无 userinfo、无 query/hash);返回错误码或 null。 */
|
|
320
|
+
export declare function validateCloudEndpoint(endpoint: string): CloudConfigIssueCode | null;
|
|
321
|
+
/** region 校验:非空、无空白。 */
|
|
322
|
+
export declare function validateCloudRegion(region: string): CloudConfigIssueCode | null;
|
|
323
|
+
/** 桶名校验。 */
|
|
324
|
+
export declare function validateCloudBucket(bucket: string): CloudConfigIssueCode | null;
|
|
325
|
+
/** 对象键前缀校验(可缺省 = 根前缀;不得以 / 开头、不得含 .. / 反斜杠 / 空段)。 */
|
|
326
|
+
export declare function validateCloudPrefix(prefix: string): CloudConfigIssueCode | null;
|
|
327
|
+
/** gist id 校验。 */
|
|
328
|
+
export declare function validateGistId(gistId: string): CloudConfigIssueCode | null;
|
|
329
|
+
/** GitHub API 根校验(http(s)、无 userinfo)。 */
|
|
330
|
+
export declare function validateCloudApiBaseUrl(url: string): CloudConfigIssueCode | null;
|
|
331
|
+
/** 按通道校验写入入参;返回首个错误码或 null。 */
|
|
332
|
+
export declare function validateCloudChannelInput(provider: CloudSyncProvider, input: CloudChannelWriteInput): CloudConfigIssueCode | null;
|
|
333
|
+
/**
|
|
334
|
+
* 读取云端点配置;文件不存在/损坏/schema 不支持 → null(视为未配置)。
|
|
335
|
+
* **绝不回读密钥值**:只认非密白名单字段 + \`secretStored\` 标记。
|
|
336
|
+
*/
|
|
337
|
+
export declare function readCloudSyncConfig(dir: string): Promise<CloudSyncConfig | null>;
|
|
338
|
+
/** 读取单条云端点通道的配置;该通道未配置/非法 → null。 */
|
|
339
|
+
export declare function readCloudChannelConfig(dir: string, provider: CloudSyncProvider): Promise<CloudChannelConfig | null>;
|
|
340
|
+
/** 已配置的云端点通道清单(供 UI 回填 / 断开时判断是否还剩别的通道)。 */
|
|
341
|
+
export declare function listCloudConfiguredProviders(dir: string): Promise<CloudSyncProvider[]>;
|
|
342
|
+
/** 组装 S3 兼容系回传视图(**只带标记、不带值**)。 */
|
|
343
|
+
export declare function s3ChannelView(provider: S3CompatProvider, config: CloudS3ChannelConfig, secretStored: boolean): CloudS3ChannelView;
|
|
344
|
+
/** 组装 Gist 回传视图(**只带标记、不带值**)。 */
|
|
345
|
+
export declare function gistChannelView(config: CloudGistChannelConfig, secretStored: boolean): CloudGistChannelView;
|
|
346
|
+
/** 组装回传视图(按 provider 分派到具名视图构造器)。 */
|
|
347
|
+
export declare function cloudChannelView(channel: CloudChannelConfig, secretStored: boolean): CloudChannelView;
|
|
348
|
+
/**
|
|
349
|
+
* 保存某云端点通道的配置(自动创建目录;恒写 schemaVersion=1 的 savedProviders)。
|
|
350
|
+
* - 只写当前通道的条目,其它通道原样保留(切换通道不丢失已填的 endpoint/bucket);
|
|
351
|
+
* - 密钥**只写**:提供 input.secret 时经注入的 \`CloudSecretWriter\` 写进 credentials 槽位,
|
|
352
|
+
* 文件里只留 \`secretStored: true\`(值绝不落文件、绝不回传);
|
|
353
|
+
* - 未提供 secret 时只更新非密字段(已有密钥不动,标记按 \`has()\` 现算)。
|
|
354
|
+
*/
|
|
355
|
+
export declare function writeCloudChannelConfig(dir: string, provider: CloudSyncProvider, input: CloudChannelWriteInput, secrets?: CloudSecretWriter): Promise<CloudChannelView>;
|
|
356
|
+
/**
|
|
357
|
+
* 断开某云端点通道:删掉该通道的配置条目;一条不剩则删除整个文件。
|
|
358
|
+
* 幂等:本来没配置 → removed=false 且**不写文件**。
|
|
359
|
+
* 密钥槽位不在这里清除(凭据归凭据层),与 \`clearSyncChannel\` 同口径。
|
|
360
|
+
*/
|
|
361
|
+
export declare function clearCloudChannelConfig(dir: string, provider: CloudSyncProvider): Promise<{
|
|
362
|
+
removed: boolean;
|
|
363
|
+
hasRemaining: boolean;
|
|
364
|
+
}>;
|
|
365
|
+
/**
|
|
366
|
+
* s3 通道当前选用的兼容商:
|
|
367
|
+
* - 有 active.s3 → 用它(且必须仍有已保存配置);
|
|
368
|
+
* - 旧文件(无 active)→ 只有**唯一一家**已保存时据此推断,多家并存时为 null(不猜)。
|
|
369
|
+
*/
|
|
370
|
+
export declare function readActiveS3Provider(dir: string): Promise<S3CompatProvider | null>;
|
|
371
|
+
/**
|
|
372
|
+
* 当前仍配置的通道清单(git/webdav 命名空间 ∪ 云端点已保存的 provider),顺序 = SYNC_CHANNELS。
|
|
373
|
+
* 供路由层判断「还有没有其他通道可用」与断开后回落活动通道。
|
|
374
|
+
*/
|
|
375
|
+
export declare function listConfiguredChannels(dir: string): Promise<SyncTransportType[]>;
|