dsh-desktop-kit 0.0.0-stage → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +152 -2
- package/client.js +4101 -0
- package/cordis.patch.yml +5 -0
- package/docs/ARCHITECTURE.md +114 -0
- package/docs/COMPATIBILITY.md +61 -0
- package/docs/INSTALL.md +84 -0
- package/docs/PRIVACY.md +50 -0
- package/docs/ROADMAP.md +57 -0
- package/docs/TOKENS.md +118 -0
- package/docs/TROUBLESHOOTING.md +68 -0
- package/docs/images/hero.png +0 -0
- package/index.js +84 -0
- package/package.json +70 -4
- package/plugins/dsh-gkb-ru-ui/cordis.patch.yml +6 -0
- package/plugins/dsh-gkb-ru-ui/lib/client.js +1331 -0
- package/plugins/dsh-gkb-ru-ui/lib/index.js +186 -0
- package/plugins/dsh-gkb-ru-ui/lib/skills.js +570 -0
- package/plugins/dsh-gkb-ru-ui/package.json +28 -0
- package/plugins/dsh-gkb-ru-ui/screenshots/01-home-tiles-1440-light.png +0 -0
- package/plugins/dsh-gkb-ru-ui/screenshots/02-skills-1440-light.png +0 -0
- package/plugins/dsh-gkb-ru-ui/screenshots/03-skills-editor-1440-light.png +0 -0
- package/plugins/dsh-gkb-ru-ui/screenshots/04-skills-1440-dark.png +0 -0
- package/plugins/dsh-gkb-ru-ui/screenshots/05-skills-390-light.png +0 -0
- package/plugins/dsh-gkb-ru-ui/screenshots/06-home-tiles-1440-dark.png +0 -0
- package/plugins/dsh-peak-guard/README.md +70 -0
- package/plugins/dsh-peak-guard/client.js +741 -0
- package/plugins/dsh-peak-guard/cordis.patch.yml +5 -0
- package/plugins/dsh-peak-guard/icon.svg +12 -0
- package/plugins/dsh-peak-guard/index.js +2 -0
- package/plugins/dsh-peak-guard/locale/en.json +6 -0
- package/plugins/dsh-peak-guard/locale/ru.json +6 -0
- package/plugins/dsh-peak-guard/locale/zh.json +6 -0
- package/plugins/dsh-peak-guard/package.json +33 -0
- package/plugins/dsh-peak-guard/screenshots/01-real-time-peak-start.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/02-real-time-peak-end.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/03-peak-card-1440-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/04-peak-card-1440-dark.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/05-peak-card-390-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/05-peak-card-768-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/06-peak-card-390-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/07-live-preview-check.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/07-pre-peak-1440-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/08-peak-start-1440-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/09-peak-end-1440-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/10-pre-peak-card-1440-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/11-pre-peak-card-1440-dark.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/12-pre-peak-card-390-light.png +0 -0
- package/plugins/dsh-peak-guard/screenshots/qa-report.json +74 -0
- package/plugins/dsh-profile-transfer/README.md +62 -0
- package/plugins/dsh-profile-transfer/bootstrap/01-INSTALL.cmd +7 -0
- package/plugins/dsh-profile-transfer/bootstrap/README-ARCHIVE.md +54 -0
- package/plugins/dsh-profile-transfer/bootstrap/README-/320/243/320/241/320/242/320/220/320/235/320/236/320/222/320/232/320/220.md +42 -0
- package/plugins/dsh-profile-transfer/bootstrap/install-on-clean-machine.ps1 +119 -0
- package/plugins/dsh-profile-transfer/bootstrap//320/243/320/241/320/242/320/220/320/235/320/236/320/222/320/230/320/242/320/254.cmd +5 -0
- package/plugins/dsh-profile-transfer/client.js +806 -0
- package/plugins/dsh-profile-transfer/cordis.patch.yml +3 -0
- package/plugins/dsh-profile-transfer/icon.svg +13 -0
- package/plugins/dsh-profile-transfer/index.js +375 -0
- package/plugins/dsh-profile-transfer/locale/en.json +6 -0
- package/plugins/dsh-profile-transfer/locale/ru.json +6 -0
- package/plugins/dsh-profile-transfer/locale/zh.json +6 -0
- package/plugins/dsh-profile-transfer/package.json +36 -0
- package/plugins/dsh-profile-transfer/screenshots/01-settings-transfer-1440-light.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/02-settings-transfer-preview-1440-light.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/03-settings-transfer-1440-dark.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/04-settings-transfer-390-light.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/05-settings-transfer-768-light.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/06-settings-transfer-390-dark.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/07-settings-transfer-export-result.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/08-settings-transfer-workspaces-1440-light.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/09-settings-transfer-workspaces-1440-dark.png +0 -0
- package/plugins/dsh-profile-transfer/screenshots/10-settings-transfer-workspaces-390-light.png +0 -0
- package/plugins/dsh-profile-transfer/transfer.js +1004 -0
- package/plugins/dsh-project-memory/README.md +71 -0
- package/plugins/dsh-project-memory/cordis.patch.yml +4 -0
- package/plugins/dsh-project-memory/icon.svg +12 -0
- package/plugins/dsh-project-memory/index.js +1240 -0
- package/plugins/dsh-project-memory/locale/en.json +6 -0
- package/plugins/dsh-project-memory/locale/ru.json +6 -0
- package/plugins/dsh-project-memory/locale/zh.json +6 -0
- package/plugins/dsh-project-memory/package.json +26 -0
- package/plugins/dsh-session-move/README.md +67 -0
- package/plugins/dsh-session-move/client.js +719 -0
- package/plugins/dsh-session-move/cordis.patch.yml +5 -0
- package/plugins/dsh-session-move/icon.svg +14 -0
- package/plugins/dsh-session-move/index.js +497 -0
- package/plugins/dsh-session-move/locale/en.json +6 -0
- package/plugins/dsh-session-move/locale/ru.json +6 -0
- package/plugins/dsh-session-move/locale/zh.json +6 -0
- package/plugins/dsh-session-move/package.json +31 -0
- package/plugins/dsh-session-move/screenshots/01-row-menu-1440-light.png +0 -0
- package/plugins/dsh-session-move/screenshots/02-dialog-1440-light.png +0 -0
- package/plugins/dsh-session-move/screenshots/03-dialog-390-light.png +0 -0
- package/plugins/dsh-session-move/screenshots/04-dialog-1440-dark.png +0 -0
- package/plugins/dsh-session-move/screenshots/05-drag-highlight-1440-light.png +0 -0
- package/plugins/dsh-session-move/screenshots/06-drop-ungrouped-highlight.png +0 -0
- package/plugins/dsh-session-move/screenshots/07-after-drop-ungrouped.png +0 -0
- package/plugins/dsh-session-move/screenshots/08-move-dialog.png +0 -0
- package/plugins/dsh-session-move/screenshots/09-moved-to-second-workspace.png +0 -0
- package/plugins/dsh-session-move/screenshots/qa-report.json +62 -0
- package/plugins/dsh-skill-autopilot/cordis.patch.yml +3 -0
- package/plugins/dsh-skill-autopilot/index.js +444 -0
- package/plugins/dsh-skill-autopilot/package.json +19 -0
- package/plugins/dsh-token-lab/cordis.patch.yml +3 -0
- package/plugins/dsh-token-lab/lib/client.js +504 -0
- package/plugins/dsh-token-lab/lib/index.js +275 -0
- package/plugins/dsh-token-lab/package.json +26 -0
- package/plugins/dsh-token-lab/screenshots/01-token-lab-1440-light.png +0 -0
- package/plugins/dsh-token-lab/screenshots/02-token-lab-1440-dark.png +0 -0
- package/skills/code-review-checklist/SKILL.md +55 -0
- package/skills/content-writing/README.md +87 -0
- package/skills/content-writing/SKILL.md +85 -0
- package/skills/content-writing/assets/checklists/fact-check.md +53 -0
- package/skills/content-writing/assets/checklists/publish.md +65 -0
- package/skills/content-writing/assets/checklists/social.md +40 -0
- package/skills/content-writing/assets/templates/article.md +47 -0
- package/skills/content-writing/assets/templates/brief.md +44 -0
- package/skills/content-writing/assets/templates/doctor-card.md +41 -0
- package/skills/content-writing/assets/templates/image-prompts.md +128 -0
- package/skills/content-writing/assets/templates/post-telegram.md +36 -0
- package/skills/content-writing/assets/templates/post-vk.md +42 -0
- package/skills/content-writing/assets/templates/press-release.md +56 -0
- package/skills/content-writing/assets/templates/science-pop-note.md +55 -0
- package/skills/content-writing/assets/templates/service-card.md +46 -0
- package/skills/content-writing/references/anti-ai-style.md +248 -0
- package/skills/content-writing/references/editing.md +185 -0
- package/skills/content-writing/references/fact-checking.md +205 -0
- package/skills/content-writing/references/government-medical.md +246 -0
- package/skills/content-writing/references/images.md +212 -0
- package/skills/content-writing/references/journalism.md +252 -0
- package/skills/content-writing/references/process.md +123 -0
- package/skills/content-writing/references/quick-recipes.md +99 -0
- package/skills/content-writing/references/rules.md +85 -0
- package/skills/content-writing/references/science-popular.md +218 -0
- package/skills/content-writing/references/seo-content.md +172 -0
- package/skills/content-writing/references/social-media.md +253 -0
- package/skills/content-writing/references/sources.md +49 -0
- package/skills/content-writing/references/templates.md +291 -0
- package/skills/context-economy/SKILL.md +60 -0
- package/skills/context-economy/references/long-session.md +35 -0
- package/skills/context-economy/references/token-math.md +42 -0
- package/skills/context-economy/references/tool-recipes.md +34 -0
- package/skills/database-safety/SKILL.md +47 -0
- package/skills/debugging-playbook/SKILL.md +42 -0
- package/skills/design-critique/SKILL.md +65 -0
- package/skills/design-critique/references/a11y.md +25 -0
- package/skills/design-critique/references/diagnoses.md +33 -0
- package/skills/design-critique/references/quick-tests.md +30 -0
- package/skills/design-critique/references/report-template.md +63 -0
- package/skills/design-critique/references/rubric-fast.md +73 -0
- package/skills/dev-workflow/SKILL.md +48 -0
- package/skills/dev-workflow/references/definition-of-done.md +44 -0
- package/skills/dev-workflow/references/memory-and-boundaries.md +31 -0
- package/skills/dev-workflow/references/stages.md +67 -0
- package/skills/git-and-ci/SKILL.md +60 -0
- package/skills/pg-upgrade-verify/SKILL.md +67 -0
- package/skills/project-deep-dive/SKILL.md +45 -0
- package/skills/project-deep-dive/references/recon-commands.md +90 -0
- package/skills/project-deep-dive/references/section-templates.md +104 -0
- package/skills/project-deep-dive/references/tool-and-process.md +86 -0
- package/skills/project-memory-maintenance/SKILL.md +55 -0
- package/skills/project-memory-maintenance/references/api-and-checklist.md +99 -0
- package/skills/project-memory-maintenance/references/journal-template.md +50 -0
- package/skills/project-memory-maintenance/references/section-rules.md +59 -0
- package/skills/release-and-deploy/SKILL.md +53 -0
- package/skills/requirements-and-planning/SKILL.md +49 -0
- package/skills/requirements-and-planning/references/antipatterns-and-checklist.md +20 -0
- package/skills/requirements-and-planning/references/process-steps.md +52 -0
- package/skills/requirements-and-planning/references/templates-and-estimates.md +29 -0
- package/skills/security-review/SKILL.md +40 -0
- package/skills/seo/README.md +60 -0
- package/skills/seo/SKILL.md +77 -0
- package/skills/seo/assets/README.md +66 -0
- package/skills/seo/assets/scripts/LICENSE-playwright-core.txt +202 -0
- package/skills/seo/assets/scripts/README.md +179 -0
- package/skills/seo/assets/scripts/lib/args.mjs +105 -0
- package/skills/seo/assets/scripts/lib/browser.mjs +620 -0
- package/skills/seo/assets/scripts/lib/zip.mjs +191 -0
- package/skills/seo/assets/scripts/seo-audit.mjs +1675 -0
- package/skills/seo/assets/snippets/jsonld-breadcrumb.json +30 -0
- package/skills/seo/assets/snippets/jsonld-faq.json +39 -0
- package/skills/seo/assets/snippets/jsonld-medical-clinic.json +49 -0
- package/skills/seo/assets/snippets/jsonld-medical-webpage.json +33 -0
- package/skills/seo/assets/snippets/jsonld-organization.json +74 -0
- package/skills/seo/assets/snippets/jsonld-physician.json +46 -0
- package/skills/seo/assets/snippets/meta.blade.php +61 -0
- package/skills/seo/assets/snippets/robots.txt +61 -0
- package/skills/seo/assets/snippets/sitemap-urlset-example.xml +72 -0
- package/skills/seo/assets/snippets/sitemap.xml +36 -0
- package/skills/seo/references/antipatterns.md +66 -0
- package/skills/seo/references/audit-checklist.md +319 -0
- package/skills/seo/references/content-seo.md +204 -0
- package/skills/seo/references/eeat-medical.md +219 -0
- package/skills/seo/references/measurement.md +250 -0
- package/skills/seo/references/on-page.md +214 -0
- package/skills/seo/references/page-templates.md +56 -0
- package/skills/seo/references/stack-recipes.md +695 -0
- package/skills/seo/references/structured-data.md +487 -0
- package/skills/seo/references/technical-seo.md +296 -0
- package/skills/service-desk-conventions/SKILL.md +52 -0
- package/skills/service-desk-db-safety/SKILL.md +63 -0
- package/skills/service-desk-release/SKILL.md +61 -0
- package/skills/service-desk-testing/SKILL.md +61 -0
- package/skills/service-desk-ui/SKILL.md +52 -0
- package/skills/skills-router/SKILL.md +53 -0
- package/skills/skills-router/references/applying-skills.md +25 -0
- package/skills/skills-router/references/routing-matrix.md +52 -0
- package/skills/testing-strategy/SKILL.md +52 -0
- package/skills/ui-design-system/SKILL.md +50 -0
- package/skills/ui-design-system/references/accessibility-and-responsive.md +50 -0
- package/skills/ui-design-system/references/tokens-and-components.md +67 -0
- package/skills/ui-design-system/references/visual-qa.md +44 -0
- package/skills/web-research/SKILL.md +47 -0
- package/skills/web-research/references/answer-and-citations.md +60 -0
- package/skills/web-research/references/query-recipes.md +44 -0
- package/skills/wow-design/SKILL.md +89 -0
- package/skills/wow-design/assets/kit/README.md +195 -0
- package/skills/wow-design/assets/kit/assets/css/base.css +158 -0
- package/skills/wow-design/assets/kit/assets/css/components.css +1001 -0
- package/skills/wow-design/assets/kit/assets/css/fonts.css +73 -0
- package/skills/wow-design/assets/kit/assets/css/pages.css +737 -0
- package/skills/wow-design/assets/kit/assets/css/tokens.css +218 -0
- package/skills/wow-design/assets/kit/assets/fonts/LICENSE-golos-text.txt +93 -0
- package/skills/wow-design/assets/kit/assets/fonts/LICENSE-lora.txt +93 -0
- package/skills/wow-design/assets/kit/assets/fonts/LICENSE-unbounded.txt +93 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-cyrillic-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-cyrillic-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-cyrillic-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-cyrillic-700-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-latin-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-latin-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-latin-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/golos-text-latin-700-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-cyrillic-400-italic.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-cyrillic-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-cyrillic-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-cyrillic-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-latin-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-latin-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/lora-latin-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-cyrillic-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-cyrillic-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-cyrillic-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-latin-400-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-latin-500-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/fonts/unbounded-latin-600-normal.woff2 +0 -0
- package/skills/wow-design/assets/kit/assets/js/kit.js +550 -0
- package/skills/wow-design/assets/kit/pages/dashboard.html +539 -0
- package/skills/wow-design/assets/kit/pages/hospital.html +430 -0
- package/skills/wow-design/assets/kit/showcase.html +1164 -0
- package/skills/wow-design/assets/scripts/LICENSE-axe-core.txt +362 -0
- package/skills/wow-design/assets/scripts/LICENSE-playwright-core.txt +202 -0
- package/skills/wow-design/assets/scripts/README.md +312 -0
- package/skills/wow-design/assets/scripts/audit.mjs +1200 -0
- package/skills/wow-design/assets/scripts/capture.mjs +337 -0
- package/skills/wow-design/assets/scripts/package.json +30 -0
- package/skills/wow-design/references/anti-patterns.md +252 -0
- package/skills/wow-design/references/critique-rubric.md +262 -0
- package/skills/wow-design/references/design-brief-template.md +48 -0
- package/skills/wow-design/references/inspiration.md +203 -0
- package/skills/wow-design/references/presets.md +99 -0
- package/skills/wow-design/references/principles.md +371 -0
- package/skills/wow-design/references/quick-presets.md +50 -0
- package/skills/wow-design/references/report-template.md +21 -0
- package/skills/wow-design/references/stack-recipes.md +96 -0
- package/skills/wow-design/references/visual-qa.md +82 -0
- package/skills/wow-design/references/wow-levers.md +43 -0
- package/tools/skill-cost.mjs +76 -0
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-profile-transfer — browser half.
|
|
3
|
+
*
|
|
4
|
+
* Adds the “Перенос и резервные копии” page to Settings: choose what to export,
|
|
5
|
+
* build one archive, inspect and restore an archive on another machine.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
window.__ModuleLoader__.load({
|
|
9
|
+
id: "dsh-profile-transfer",
|
|
10
|
+
factory: (require) => {
|
|
11
|
+
var module = { exports: {} };
|
|
12
|
+
var exports = module.exports;
|
|
13
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
14
|
+
const React = require("react");
|
|
15
|
+
const h = React.createElement;
|
|
16
|
+
const useEffect = React.useEffect;
|
|
17
|
+
const useMemo = React.useMemo;
|
|
18
|
+
const useState = React.useState;
|
|
19
|
+
|
|
20
|
+
const NS = "profile-transfer";
|
|
21
|
+
const RPC_NS = "dsh-profile-transfer";
|
|
22
|
+
|
|
23
|
+
const EN = {
|
|
24
|
+
nav: "Transfer and backups",
|
|
25
|
+
title: "Transfer and backups",
|
|
26
|
+
subtitle: "Pack your DSH setup into one archive and restore it on another machine — from a fresh install too.",
|
|
27
|
+
step1: "Choose",
|
|
28
|
+
step2: "Pack",
|
|
29
|
+
step3: "Restore",
|
|
30
|
+
exportTitle: "Export",
|
|
31
|
+
exportSubtitle: "Tick what should go into the archive. The size is measured on this machine.",
|
|
32
|
+
destinationLabel: "Save archive to",
|
|
33
|
+
destinationHint: "Folder on this machine. The archive keeps relative paths and restores them on the other machine.",
|
|
34
|
+
groupsTitle: "What to include",
|
|
35
|
+
exportButton: "Build archive",
|
|
36
|
+
exporting: "Packing…",
|
|
37
|
+
exportDone: "Archive is ready",
|
|
38
|
+
openFolder: "Show in folder",
|
|
39
|
+
copyPath: "Copy path",
|
|
40
|
+
copied: "Copied",
|
|
41
|
+
archiveSize: "Archive size",
|
|
42
|
+
importTitle: "Import",
|
|
43
|
+
importSubtitle: "Restore an archive made by this plugin. The current profile is backed up first.",
|
|
44
|
+
archivePathLabel: "Archive path",
|
|
45
|
+
archivePathPlaceholder: "C:\\Users\\…\\dsh-profile-….tar.gz",
|
|
46
|
+
inspectButton: "Check archive",
|
|
47
|
+
inspecting: "Checking…",
|
|
48
|
+
previewTitle: "Archive contents",
|
|
49
|
+
previewCreated: "Created",
|
|
50
|
+
previewHost: "From machine",
|
|
51
|
+
previewTotals: "Contents",
|
|
52
|
+
previewPlugins: "Local plugins in archive",
|
|
53
|
+
importButton: "Restore archive",
|
|
54
|
+
importing: "Restoring…",
|
|
55
|
+
importConfirm: "I understand that the current profile, skills, memory and local plugins will be replaced. A backup is created automatically.",
|
|
56
|
+
backupNote: "Backup folder",
|
|
57
|
+
restartNote: "After restore, restart DSH (or reload the app) so the restored profile and plugins are loaded.",
|
|
58
|
+
installNote: "Dependencies of local plugins are not installed yet.",
|
|
59
|
+
installButton: "Install dependencies",
|
|
60
|
+
installing: "Installing…",
|
|
61
|
+
installDone: "Dependencies installed",
|
|
62
|
+
installFailed: "pnpm install failed",
|
|
63
|
+
importDone: "Archive restored",
|
|
64
|
+
restoredTitle: "Restored",
|
|
65
|
+
optionsLoading: "Reading the current setup…",
|
|
66
|
+
errorPrefix: "Could not complete:",
|
|
67
|
+
missingArchive: "Enter the archive path first",
|
|
68
|
+
confirmRequired: "Confirm the replacement checkbox first",
|
|
69
|
+
selectAtLeastOne: "Tick at least one item to export",
|
|
70
|
+
groupProfile: "Profile and configs",
|
|
71
|
+
groupProfileDesc: "package.json, cordis.patch.yml, cordis.yml, pnpm-lock.yaml (no node_modules)",
|
|
72
|
+
groupLocalPlugins: "Local plugins",
|
|
73
|
+
groupLocalPluginsDesc: "Sources of plugins installed from local folders (link:)",
|
|
74
|
+
groupWorkspaces: "Workspaces",
|
|
75
|
+
groupWorkspacesDesc: "Workspace registry: names, folders, pinned and grouped chats",
|
|
76
|
+
groupWorkspaceFolders: "Workspace folders",
|
|
77
|
+
groupWorkspaceFoldersDesc: "Project code and artifacts from workspace folders (without node_modules/pgruntime/tmp) — can be many gigabytes",
|
|
78
|
+
groupSkills: "Skills",
|
|
79
|
+
groupSkillsDesc: "All file-based skills (without node_modules)",
|
|
80
|
+
groupMemory: "Memory",
|
|
81
|
+
groupMemoryDesc: "memory/ — session log, project dossiers, environment facts",
|
|
82
|
+
groupProjectsMemory: "Project memory",
|
|
83
|
+
groupProjectsMemoryDesc: "projects-memory/ — dossiers and journals",
|
|
84
|
+
groupConfig: "Global configs",
|
|
85
|
+
groupConfigDesc: "AGENTS.md, dream-skin.json",
|
|
86
|
+
groupSessions: "Session history",
|
|
87
|
+
groupSessionsDesc: "sessions/ — can be very large",
|
|
88
|
+
groupAttachments: "Attachments",
|
|
89
|
+
groupAttachmentsDesc: "attachments/ — images and files from chats",
|
|
90
|
+
groupCredentials: "Secrets",
|
|
91
|
+
groupCredentialsDesc: ".credentials.yaml — tokens and API keys. Transfer only to a trusted machine",
|
|
92
|
+
groupEmpty: "not found",
|
|
93
|
+
lastImport: "Last import",
|
|
94
|
+
restartRequired: "Restart required",
|
|
95
|
+
showBackup: "Show backup",
|
|
96
|
+
noteLabel: "Note",
|
|
97
|
+
copiedPath: "Path copied",
|
|
98
|
+
archivePathHint: "Use the path shown after export, or type the archive path from a USB drive / cloud folder.",
|
|
99
|
+
};
|
|
100
|
+
const RU = {
|
|
101
|
+
nav: "Перенос и резервные копии",
|
|
102
|
+
title: "Перенос и резервные копии",
|
|
103
|
+
subtitle: "Соберите всю настройку DSH в один архив и разверните её на другой машине — в том числе на чистой установке.",
|
|
104
|
+
step1: "Выбрать",
|
|
105
|
+
step2: "Упаковать",
|
|
106
|
+
step3: "Развернуть",
|
|
107
|
+
exportTitle: "Экспорт",
|
|
108
|
+
exportSubtitle: "Отметьте, что должно попасть в архив. Размер измеряется на этой машине.",
|
|
109
|
+
destinationLabel: "Куда сохранить архив",
|
|
110
|
+
destinationHint: "Папка на этой машине. В архиве хранятся относительные пути — на другой машине они восстановятся автоматически.",
|
|
111
|
+
groupsTitle: "Что включить",
|
|
112
|
+
exportButton: "Собрать архив",
|
|
113
|
+
exporting: "Упаковываю…",
|
|
114
|
+
exportDone: "Архив готов",
|
|
115
|
+
openFolder: "Показать в папке",
|
|
116
|
+
copyPath: "Скопировать путь",
|
|
117
|
+
copied: "Скопировано",
|
|
118
|
+
archiveSize: "Размер архива",
|
|
119
|
+
importTitle: "Импорт",
|
|
120
|
+
importSubtitle: "Разверните архив, созданный этим плагином. Текущий профиль сначала резервируется.",
|
|
121
|
+
archivePathLabel: "Путь к архиву",
|
|
122
|
+
archivePathPlaceholder: "C:\\Users\\…\\dsh-profile-….tar.gz",
|
|
123
|
+
inspectButton: "Проверить архив",
|
|
124
|
+
inspecting: "Проверяю…",
|
|
125
|
+
previewTitle: "Содержимое архива",
|
|
126
|
+
previewCreated: "Создан",
|
|
127
|
+
previewHost: "С машины",
|
|
128
|
+
previewTotals: "Состав",
|
|
129
|
+
previewPlugins: "Локальные плагины в архиве",
|
|
130
|
+
importButton: "Развернуть архив",
|
|
131
|
+
importing: "Разворачиваю…",
|
|
132
|
+
importConfirm: "Я понимаю, что текущий профиль, навыки, память и локальные плагины будут заменены. Бэкап создаётся автоматически.",
|
|
133
|
+
backupNote: "Папка бэкапа",
|
|
134
|
+
restartNote: "После восстановления перезапустите DSH (или перезагрузите приложение), чтобы загрузились восстановленный профиль и плагины.",
|
|
135
|
+
installNote: "Зависимости локальных плагинов ещё не установлены.",
|
|
136
|
+
installButton: "Установить зависимости",
|
|
137
|
+
installing: "Устанавливаю…",
|
|
138
|
+
installDone: "Зависимости установлены",
|
|
139
|
+
installFailed: "pnpm install завершился с ошибкой",
|
|
140
|
+
importDone: "Архив развёрнут",
|
|
141
|
+
restoredTitle: "Восстановлено",
|
|
142
|
+
optionsLoading: "Читаю текущую настройку…",
|
|
143
|
+
errorPrefix: "Не удалось выполнить:",
|
|
144
|
+
missingArchive: "Сначала укажите путь к архиву",
|
|
145
|
+
confirmRequired: "Сначала подтвердите замену текущего профиля",
|
|
146
|
+
selectAtLeastOne: "Отметьте хотя бы один пункт для экспорта",
|
|
147
|
+
groupProfile: "Профиль и конфиги",
|
|
148
|
+
groupProfileDesc: "package.json, cordis.patch.yml, cordis.yml, pnpm-lock.yaml (без node_modules)",
|
|
149
|
+
groupLocalPlugins: "Локальные плагины",
|
|
150
|
+
groupLocalPluginsDesc: "Исходники плагинов, установленных из папок (link:)",
|
|
151
|
+
groupWorkspaces: "Рабочие области",
|
|
152
|
+
groupWorkspacesDesc: "реестр рабочих областей: названия, папки, закрепление и группировка чатов",
|
|
153
|
+
groupWorkspaceFolders: "Папки рабочих областей",
|
|
154
|
+
groupWorkspaceFoldersDesc: "код и артефакты папок рабочих областей (без node_modules/pgruntime/tmp) — может быть много гигабайт",
|
|
155
|
+
groupSkills: "Навыки",
|
|
156
|
+
groupSkillsDesc: "Все файловые навыки (без node_modules)",
|
|
157
|
+
groupMemory: "Память",
|
|
158
|
+
groupMemoryDesc: "memory/ — журнал сессий, досье проектов, факты окружения",
|
|
159
|
+
groupProjectsMemory: "Память проектов",
|
|
160
|
+
groupProjectsMemoryDesc: "projects-memory/ — досье и журналы",
|
|
161
|
+
groupConfig: "Глобальные конфиги",
|
|
162
|
+
groupConfigDesc: "AGENTS.md, dream-skin.json",
|
|
163
|
+
groupSessions: "История сессий",
|
|
164
|
+
groupSessionsDesc: "sessions/ — может быть очень большим",
|
|
165
|
+
groupAttachments: "Вложения",
|
|
166
|
+
groupAttachmentsDesc: "attachments/ — картинки и файлы из чатов",
|
|
167
|
+
groupCredentials: "Секреты",
|
|
168
|
+
groupCredentialsDesc: ".credentials.yaml — токены и ключи API. Переносите только на доверенную машину",
|
|
169
|
+
groupEmpty: "не найдено",
|
|
170
|
+
lastImport: "Последний импорт",
|
|
171
|
+
restartRequired: "Требуется перезапуск",
|
|
172
|
+
showBackup: "Показать бэкап",
|
|
173
|
+
noteLabel: "Примечание",
|
|
174
|
+
copiedPath: "Путь скопирован",
|
|
175
|
+
archivePathHint: "Используйте путь из результата экспорта или впишите путь к архиву с флешки / из облака.",
|
|
176
|
+
};
|
|
177
|
+
const ZH = {
|
|
178
|
+
nav: "迁移与备份",
|
|
179
|
+
title: "迁移与备份",
|
|
180
|
+
subtitle: "把整套 DSH 配置打包成一个归档,并在另一台机器上恢复(包括全新安装)。",
|
|
181
|
+
step1: "选择",
|
|
182
|
+
step2: "打包",
|
|
183
|
+
step3: "恢复",
|
|
184
|
+
exportTitle: "导出",
|
|
185
|
+
exportSubtitle: "勾选要放入归档的内容。大小按本机计算。",
|
|
186
|
+
destinationLabel: "归档保存位置",
|
|
187
|
+
destinationHint: "本机文件夹。归档保存相对路径,在另一台机器上会自动恢复。",
|
|
188
|
+
groupsTitle: "包含内容",
|
|
189
|
+
exportButton: "生成归档",
|
|
190
|
+
exporting: "打包中…",
|
|
191
|
+
exportDone: "归档已生成",
|
|
192
|
+
openFolder: "在文件夹中显示",
|
|
193
|
+
copyPath: "复制路径",
|
|
194
|
+
copied: "已复制",
|
|
195
|
+
archiveSize: "归档大小",
|
|
196
|
+
importTitle: "导入",
|
|
197
|
+
importSubtitle: "恢复由本插件生成的归档。恢复前会自动备份当前配置。",
|
|
198
|
+
archivePathLabel: "归档路径",
|
|
199
|
+
archivePathPlaceholder: "C:\\Users\\…\\dsh-profile-….tar.gz",
|
|
200
|
+
inspectButton: "检查归档",
|
|
201
|
+
inspecting: "检查中…",
|
|
202
|
+
previewTitle: "归档内容",
|
|
203
|
+
previewCreated: "创建时间",
|
|
204
|
+
previewHost: "来自机器",
|
|
205
|
+
previewTotals: "内容",
|
|
206
|
+
previewPlugins: "归档中的本地插件",
|
|
207
|
+
importButton: "恢复归档",
|
|
208
|
+
importing: "恢复中…",
|
|
209
|
+
importConfirm: "我明白当前配置、技能、记忆和本地插件将被替换,备份会自动创建。",
|
|
210
|
+
backupNote: "备份文件夹",
|
|
211
|
+
restartNote: "恢复后请重启 DSH(或刷新应用),以加载恢复的配置和插件。",
|
|
212
|
+
installNote: "本地插件的依赖尚未安装。",
|
|
213
|
+
installButton: "安装依赖",
|
|
214
|
+
installing: "安装中…",
|
|
215
|
+
installDone: "依赖已安装",
|
|
216
|
+
installFailed: "pnpm install 失败",
|
|
217
|
+
importDone: "归档已恢复",
|
|
218
|
+
restoredTitle: "已恢复",
|
|
219
|
+
optionsLoading: "正在读取当前配置…",
|
|
220
|
+
errorPrefix: "无法完成:",
|
|
221
|
+
missingArchive: "请先输入归档路径",
|
|
222
|
+
confirmRequired: "请先勾选确认替换当前配置",
|
|
223
|
+
selectAtLeastOne: "请至少勾选一项导出内容",
|
|
224
|
+
groupProfile: "配置与档案",
|
|
225
|
+
groupProfileDesc: "package.json、cordis.patch.yml、cordis.yml、pnpm-lock.yaml(不含 node_modules)",
|
|
226
|
+
groupLocalPlugins: "本地插件",
|
|
227
|
+
groupLocalPluginsDesc: "从本地文件夹安装的插件源码(link:)",
|
|
228
|
+
groupWorkspaces: "工作区",
|
|
229
|
+
groupWorkspacesDesc: "工作区注册表:名称、文件夹、置顶与聊天分组",
|
|
230
|
+
groupWorkspaceFolders: "工作区文件夹",
|
|
231
|
+
groupWorkspaceFoldersDesc: "工作区文件夹中的项目代码与产物(不含 node_modules/pgruntime/tmp)——可能非常大",
|
|
232
|
+
groupSkills: "技能",
|
|
233
|
+
groupSkillsDesc: "全部文件型技能(不含 node_modules)",
|
|
234
|
+
groupMemory: "记忆",
|
|
235
|
+
groupMemoryDesc: "memory/ — 会话日志、项目档案、环境事实",
|
|
236
|
+
groupProjectsMemory: "项目记忆",
|
|
237
|
+
groupProjectsMemoryDesc: "projects-memory/ — 档案与日志",
|
|
238
|
+
groupConfig: "全局配置",
|
|
239
|
+
groupConfigDesc: "AGENTS.md、dream-skin.json",
|
|
240
|
+
groupSessions: "会话历史",
|
|
241
|
+
groupSessionsDesc: "sessions/ — 可能非常大",
|
|
242
|
+
groupAttachments: "附件",
|
|
243
|
+
groupAttachmentsDesc: "attachments/ — 聊天中的图片和文件",
|
|
244
|
+
groupCredentials: "密钥",
|
|
245
|
+
groupCredentialsDesc: ".credentials.yaml — 令牌与 API 密钥。仅迁移到可信机器",
|
|
246
|
+
groupEmpty: "未找到",
|
|
247
|
+
lastImport: "上次导入",
|
|
248
|
+
restartRequired: "需要重启",
|
|
249
|
+
showBackup: "显示备份",
|
|
250
|
+
noteLabel: "说明",
|
|
251
|
+
copiedPath: "路径已复制",
|
|
252
|
+
archivePathHint: "使用导出结果中的路径,或输入 U 盘 / 云盘中的归档路径。",
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const inject = ["slots", "locale", "connection"];
|
|
256
|
+
|
|
257
|
+
const GROUP_ORDER = ["profile", "localPlugins", "workspaces", "workspaceFolders", "skills", "memory", "projectsMemory", "config", "sessions", "attachments", "credentials"];
|
|
258
|
+
const GROUP_KEY = {
|
|
259
|
+
profile: ["groupProfile", "groupProfileDesc"],
|
|
260
|
+
localPlugins: ["groupLocalPlugins", "groupLocalPluginsDesc"],
|
|
261
|
+
workspaces: ["groupWorkspaces", "groupWorkspacesDesc"],
|
|
262
|
+
workspaceFolders: ["groupWorkspaceFolders", "groupWorkspaceFoldersDesc"],
|
|
263
|
+
skills: ["groupSkills", "groupSkillsDesc"],
|
|
264
|
+
memory: ["groupMemory", "groupMemoryDesc"],
|
|
265
|
+
projectsMemory: ["groupProjectsMemory", "groupProjectsMemoryDesc"],
|
|
266
|
+
config: ["groupConfig", "groupConfigDesc"],
|
|
267
|
+
sessions: ["groupSessions", "groupSessionsDesc"],
|
|
268
|
+
attachments: ["groupAttachments", "groupAttachmentsDesc"],
|
|
269
|
+
credentials: ["groupCredentials", "groupCredentialsDesc"],
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
function apply(ctx) {
|
|
273
|
+
const t = ctx.locale.bind(NS);
|
|
274
|
+
const callbacks = {
|
|
275
|
+
call: async (operation, payload) => {
|
|
276
|
+
let signal;
|
|
277
|
+
try {
|
|
278
|
+
signal = AbortSignal.timeout(180000);
|
|
279
|
+
} catch {
|
|
280
|
+
signal = undefined;
|
|
281
|
+
}
|
|
282
|
+
return await ctx.connection.rpc.call("/api", `${RPC_NS}/${operation}`, payload ?? {}, signal);
|
|
283
|
+
},
|
|
284
|
+
copyText: async (text) => {
|
|
285
|
+
try {
|
|
286
|
+
await navigator.clipboard.writeText(text);
|
|
287
|
+
return true;
|
|
288
|
+
} catch {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
ctx.effect(() => ctx.locale.register(NS, { en: EN, zh: ZH }), "profile-transfer: dictionaries");
|
|
295
|
+
ctx.effect(() => {
|
|
296
|
+
try {
|
|
297
|
+
return ctx.locale.register(NS, "ru", RU);
|
|
298
|
+
} catch {
|
|
299
|
+
return () => {};
|
|
300
|
+
}
|
|
301
|
+
}, "profile-transfer: ru dictionary");
|
|
302
|
+
|
|
303
|
+
ctx.effect(() => {
|
|
304
|
+
const style = document.createElement("style");
|
|
305
|
+
style.id = "dsh-profile-transfer-style";
|
|
306
|
+
style.textContent = `
|
|
307
|
+
.dpt-page{display:flex;flex-direction:column;gap:20px;max-width:760px;padding:2px 0 24px}
|
|
308
|
+
.dpt-head{display:flex;flex-direction:column;gap:6px}
|
|
309
|
+
.dpt-kicker{display:flex;align-items:center;gap:10px;font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--dsw-alias-label-secondary,#6b7280)}
|
|
310
|
+
.dpt-kicker::before{content:"";width:28px;height:1px;background:var(--dsw-alias-border-l2,rgba(0,0,0,.18))}
|
|
311
|
+
.dpt-title{font-size:22px;line-height:28px;font-weight:650;color:var(--dsw-alias-label-primary,#111)}
|
|
312
|
+
.dpt-sub{font-size:13px;line-height:20px;color:var(--dsw-alias-label-secondary,#5b6472);max-width:64ch}
|
|
313
|
+
.dpt-steps{display:flex;gap:0;border-top:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.08));border-bottom:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.08))}
|
|
314
|
+
.dpt-step{flex:1;display:flex;align-items:baseline;gap:10px;padding:10px 0}
|
|
315
|
+
.dpt-step + .dpt-step{border-left:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.08));padding-left:16px}
|
|
316
|
+
.dpt-step-num{font-variant-numeric:tabular-nums;font-size:11px;font-weight:700;letter-spacing:.08em;color:var(--dsw-alias-brand-primary,#2f7df6)}
|
|
317
|
+
.dpt-step-label{font-size:12px;font-weight:600;letter-spacing:.04em;color:var(--dsw-alias-label-secondary,#5b6472);text-transform:uppercase}
|
|
318
|
+
.dpt-card{display:flex;flex-direction:column;gap:14px;padding:18px 18px 16px;border:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.1));border-radius:14px;background:var(--dsw-alias-bg-layer-1,rgba(0,0,0,.02))}
|
|
319
|
+
.dpt-card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
|
|
320
|
+
.dpt-card-title{font-size:15px;line-height:20px;font-weight:650;color:var(--dsw-alias-label-primary,#111)}
|
|
321
|
+
.dpt-card-sub{font-size:12.5px;line-height:18px;color:var(--dsw-alias-label-secondary,#5b6472);margin-top:3px;max-width:62ch}
|
|
322
|
+
.dpt-chip{flex:none;font-size:11px;font-weight:600;letter-spacing:.04em;padding:3px 8px;border-radius:999px;background:var(--dsw-alias-bg-layer-2,rgba(0,0,0,.06));color:var(--dsw-alias-label-secondary,#4b5563);font-variant-numeric:tabular-nums;white-space:nowrap}
|
|
323
|
+
.dpt-list{display:flex;flex-direction:column;border-top:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.07))}
|
|
324
|
+
.dpt-row{display:flex;align-items:flex-start;gap:12px;padding:10px 2px;border-bottom:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.07));cursor:pointer}
|
|
325
|
+
.dpt-row:last-child{border-bottom:none}
|
|
326
|
+
.dpt-row[data-available="false"]{opacity:.5;cursor:default}
|
|
327
|
+
.dpt-row input{margin-top:2px;accent-color:var(--dsw-alias-brand-primary,#2f7df6);width:15px;height:15px;flex:none}
|
|
328
|
+
.dpt-row-text{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
|
|
329
|
+
.dpt-row-title{font-size:13px;line-height:18px;font-weight:600;color:var(--dsw-alias-label-primary,#111)}
|
|
330
|
+
.dpt-row-desc{font-size:11.5px;line-height:16px;color:var(--dsw-alias-label-secondary,#6b7280)}
|
|
331
|
+
.dpt-row-size{flex:none;font-size:11px;line-height:18px;color:var(--dsw-alias-label-secondary,#6b7280);font-variant-numeric:tabular-nums;white-space:nowrap}
|
|
332
|
+
.dpt-field{display:flex;flex-direction:column;gap:6px}
|
|
333
|
+
.dpt-label{font-size:11.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--dsw-alias-label-secondary,#6b7280)}
|
|
334
|
+
.dpt-input{width:100%;box-sizing:border-box;padding:9px 11px;border-radius:9px;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.16));background:var(--dsw-alias-bg-base,#fff);color:var(--dsw-alias-label-primary,#111);font:inherit;font-size:13px;line-height:18px}
|
|
335
|
+
.dpt-input--path{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:17px}
|
|
336
|
+
.dpt-input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#2f7df6);outline-offset:1px}
|
|
337
|
+
.dpt-hint{font-size:11.5px;line-height:16px;color:var(--dsw-alias-label-secondary,#6b7280)}
|
|
338
|
+
.dpt-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
|
|
339
|
+
.dpt-btn{border-radius:10px;border:1px solid var(--dsw-alias-border-l2,rgba(0,0,0,.16));background:transparent;color:var(--dsw-alias-label-primary,#111);font:inherit;font-size:13px;font-weight:600;line-height:18px;padding:8px 14px;cursor:pointer;display:inline-flex;align-items:center;gap:8px;min-height:36px}
|
|
340
|
+
.dpt-btn:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.05))}
|
|
341
|
+
.dpt-btn:focus-visible{outline:2px solid var(--dsw-alias-brand-primary,#2f7df6);outline-offset:1px}
|
|
342
|
+
.dpt-btn[data-tone="primary"]{background:var(--dsw-alias-label-primary,#111);border-color:transparent;color:var(--dsw-alias-bg-base,#fff)}
|
|
343
|
+
.dpt-btn[data-tone="primary"]:hover{filter:brightness(1.06)}
|
|
344
|
+
.dpt-btn[disabled]{opacity:.55;cursor:default}
|
|
345
|
+
.dpt-spinner{width:13px;height:13px;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;animation:dpt-spin .8s linear infinite}
|
|
346
|
+
@keyframes dpt-spin{to{transform:rotate(360deg)}}
|
|
347
|
+
.dpt-status{display:flex;align-items:flex-start;gap:8px;font-size:12.5px;line-height:18px;padding:10px 12px;border-radius:10px;border:1px solid transparent}
|
|
348
|
+
.dpt-status[data-tone="ok"]{background:color-mix(in srgb,var(--dsw-alias-state-success-primary,#2e9e5b) 10%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary,#2e9e5b) 30%,transparent);color:var(--dsw-alias-label-primary,#111)}
|
|
349
|
+
.dpt-status[data-tone="error"]{background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#d64545) 10%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary,#d64545) 30%,transparent);color:var(--dsw-alias-label-primary,#111)}
|
|
350
|
+
.dpt-status[data-tone="warn"]{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary,#b45309) 10%,transparent);border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary,#b45309) 30%,transparent);color:var(--dsw-alias-label-primary,#111)}
|
|
351
|
+
.dpt-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:17px;word-break:break-all;color:var(--dsw-alias-label-primary,#111)}
|
|
352
|
+
.dpt-check{display:flex;align-items:flex-start;gap:10px;font-size:12.5px;line-height:18px;color:var(--dsw-alias-label-primary,#111);cursor:pointer}
|
|
353
|
+
.dpt-check input{margin-top:1px;accent-color:var(--dsw-alias-brand-primary,#2f7df6);width:15px;height:15px;flex:none}
|
|
354
|
+
.dpt-preview{display:flex;flex-direction:column;gap:8px;padding:12px;border-radius:12px;border:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.1));background:var(--dsw-alias-bg-base,#fff)}
|
|
355
|
+
.dpt-kv{display:flex;justify-content:space-between;gap:16px;font-size:12px;line-height:18px}
|
|
356
|
+
.dpt-kv span:first-child{color:var(--dsw-alias-label-secondary,#6b7280)}
|
|
357
|
+
.dpt-kv span:last-child{color:var(--dsw-alias-label-primary,#111);font-variant-numeric:tabular-nums;text-align:right}
|
|
358
|
+
.dpt-divider{height:1px;background:var(--dsw-alias-border-l1,rgba(0,0,0,.08));margin:2px 0}
|
|
359
|
+
.dpt-grid2{display:grid;grid-template-columns:1fr 1fr;gap:10px}
|
|
360
|
+
@media (max-width:560px){.dpt-grid2{grid-template-columns:1fr}.dpt-steps{flex-direction:column}.dpt-step + .dpt-step{border-left:none;border-top:1px solid var(--dsw-alias-border-l1,rgba(0,0,0,.08));padding-left:0}}
|
|
361
|
+
@media (prefers-reduced-motion:reduce){.dpt-spinner{animation-duration:2.4s}}
|
|
362
|
+
`;
|
|
363
|
+
document.head.appendChild(style);
|
|
364
|
+
return () => style.remove();
|
|
365
|
+
}, "profile-transfer: styles");
|
|
366
|
+
|
|
367
|
+
function humanBytes(bytes) {
|
|
368
|
+
const value = Number(bytes) || 0;
|
|
369
|
+
if (value < 1024) return `${value} Б`;
|
|
370
|
+
if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)} КБ`;
|
|
371
|
+
if (value < 1024 * 1024 * 1024) return `${(value / (1024 * 1024)).toFixed(1)} МБ`;
|
|
372
|
+
return `${(value / (1024 * 1024 * 1024)).toFixed(2)} ГБ`;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function Spinner() {
|
|
376
|
+
return h("span", { className: "dpt-spinner", "aria-hidden": "true" });
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function Status({ tone, children }) {
|
|
380
|
+
return h("div", { className: "dpt-status", "data-tone": tone ?? "ok", role: tone === "error" ? "alert" : "status" }, children);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function StepBar() {
|
|
384
|
+
return h(
|
|
385
|
+
"div",
|
|
386
|
+
{ className: "dpt-steps", "aria-hidden": "true" },
|
|
387
|
+
[[ "01", t("step1") ], [ "02", t("step2") ], [ "03", t("step3") ]].map(([number, label]) =>
|
|
388
|
+
h("div", { className: "dpt-step", key: number }, h("span", { className: "dpt-step-num" }, number), h("span", { className: "dpt-step-label" }, label)),
|
|
389
|
+
),
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function GroupRow({ group, checked, onToggle, t }) {
|
|
394
|
+
const [titleKey, descKey] = GROUP_KEY[group.id] ?? [group.id, ""];
|
|
395
|
+
const available = group.available === true;
|
|
396
|
+
return h(
|
|
397
|
+
"label",
|
|
398
|
+
{ className: "dpt-row", "data-available": available ? "true" : "false" },
|
|
399
|
+
h("input", {
|
|
400
|
+
type: "checkbox",
|
|
401
|
+
checked: checked === true,
|
|
402
|
+
disabled: !available,
|
|
403
|
+
onChange: () => onToggle(group.id, !checked),
|
|
404
|
+
}),
|
|
405
|
+
h(
|
|
406
|
+
"span",
|
|
407
|
+
{ className: "dpt-row-text" },
|
|
408
|
+
h("span", { className: "dpt-row-title" }, t(titleKey)),
|
|
409
|
+
h("span", { className: "dpt-row-desc" }, t(descKey)),
|
|
410
|
+
),
|
|
411
|
+
h("span", { className: "dpt-row-size" }, available ? (group.files > 0 ? `${group.capped === true ? "≥ " : ""}${group.files} · ${group.capped === true ? "≥ " : ""}${group.human ?? humanBytes(group.bytes)}` : t("groupEmpty")) : t("groupEmpty")),
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function TransferSection(props) {
|
|
416
|
+
const call = props.call;
|
|
417
|
+
const copyText = props.copyText;
|
|
418
|
+
const [phase, setPhase] = useState("loading");
|
|
419
|
+
const [options, setOptions] = useState(null);
|
|
420
|
+
const [selected, setSelected] = useState({});
|
|
421
|
+
const [destination, setDestination] = useState("");
|
|
422
|
+
const [busy, setBusy] = useState(null);
|
|
423
|
+
const [message, setMessage] = useState(null);
|
|
424
|
+
const [exported, setExported] = useState(null);
|
|
425
|
+
const [archivePath, setArchivePath] = useState("");
|
|
426
|
+
const [preview, setPreview] = useState(null);
|
|
427
|
+
const [confirmed, setConfirmed] = useState(false);
|
|
428
|
+
const [imported, setImported] = useState(null);
|
|
429
|
+
const [copied, setCopied] = useState(false);
|
|
430
|
+
|
|
431
|
+
useEffect(() => {
|
|
432
|
+
let alive = true;
|
|
433
|
+
call("options", {})
|
|
434
|
+
.then((result) => {
|
|
435
|
+
if (!alive) return;
|
|
436
|
+
if (!result?.ok) {
|
|
437
|
+
setPhase("error");
|
|
438
|
+
setMessage({ tone: "error", text: `${t("errorPrefix")} ${result?.error?.message ?? "unknown"}` });
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
const value = result.value;
|
|
442
|
+
setOptions(value);
|
|
443
|
+
setSelected({ ...value.selection });
|
|
444
|
+
setDestination(value.destination ?? "");
|
|
445
|
+
setPhase("ready");
|
|
446
|
+
})
|
|
447
|
+
.catch((error) => {
|
|
448
|
+
if (!alive) return;
|
|
449
|
+
setPhase("error");
|
|
450
|
+
setMessage({ tone: "error", text: `${t("errorPrefix")} ${String(error?.message ?? error)}` });
|
|
451
|
+
});
|
|
452
|
+
return () => {
|
|
453
|
+
alive = false;
|
|
454
|
+
};
|
|
455
|
+
}, []);
|
|
456
|
+
|
|
457
|
+
const groups = useMemo(() => {
|
|
458
|
+
const rows = options?.groups ?? [];
|
|
459
|
+
return GROUP_ORDER
|
|
460
|
+
.map((id) => rows.find((row) => row.id === id))
|
|
461
|
+
.filter((row) => row !== undefined);
|
|
462
|
+
}, [options]);
|
|
463
|
+
|
|
464
|
+
const selectedCount = Object.values(selected).filter(Boolean).length;
|
|
465
|
+
|
|
466
|
+
function toggle(id, value) {
|
|
467
|
+
setSelected((current) => ({ ...current, [id]: value }));
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
async function doExport() {
|
|
471
|
+
if (busy !== null) return;
|
|
472
|
+
if (selectedCount === 0) {
|
|
473
|
+
setMessage({ tone: "error", text: t("selectAtLeastOne") });
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
setBusy("export");
|
|
477
|
+
setMessage(null);
|
|
478
|
+
setExported(null);
|
|
479
|
+
try {
|
|
480
|
+
const result = await call("export", { selection: selected, destinationDirectory: destination });
|
|
481
|
+
if (!result?.ok) {
|
|
482
|
+
setMessage({ tone: "error", text: `${t("errorPrefix")} ${result?.error?.message ?? "unknown"}` });
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
setExported(result.value);
|
|
486
|
+
setMessage({ tone: "ok", text: t("exportDone") });
|
|
487
|
+
} catch (error) {
|
|
488
|
+
setMessage({ tone: "error", text: `${t("errorPrefix")} ${String(error?.message ?? error)}` });
|
|
489
|
+
} finally {
|
|
490
|
+
setBusy(null);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
async function doInspect() {
|
|
495
|
+
if (busy !== null) return;
|
|
496
|
+
if (archivePath.trim().length === 0) {
|
|
497
|
+
setMessage({ tone: "error", text: t("missingArchive") });
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
setBusy("inspect");
|
|
501
|
+
setMessage(null);
|
|
502
|
+
setPreview(null);
|
|
503
|
+
setImported(null);
|
|
504
|
+
try {
|
|
505
|
+
const result = await call("inspect", { archivePath: archivePath.trim() });
|
|
506
|
+
if (!result?.ok) {
|
|
507
|
+
setMessage({ tone: "error", text: `${t("errorPrefix")} ${result?.error?.message ?? "unknown"}` });
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
setPreview(result.value);
|
|
511
|
+
} catch (error) {
|
|
512
|
+
setMessage({ tone: "error", text: `${t("errorPrefix")} ${String(error?.message ?? error)}` });
|
|
513
|
+
} finally {
|
|
514
|
+
setBusy(null);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
async function doImport() {
|
|
519
|
+
if (busy !== null) return;
|
|
520
|
+
if (!confirmed) {
|
|
521
|
+
setMessage({ tone: "error", text: t("confirmRequired") });
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
setBusy("import");
|
|
525
|
+
setMessage(null);
|
|
526
|
+
try {
|
|
527
|
+
const result = await call("import", { archivePath: archivePath.trim(), backup: true, installDependencies: true });
|
|
528
|
+
if (!result?.ok) {
|
|
529
|
+
setMessage({ tone: "error", text: `${t("errorPrefix")} ${result?.error?.message ?? "unknown"}` });
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
setImported(result.value);
|
|
533
|
+
setMessage({ tone: "ok", text: t("importDone") });
|
|
534
|
+
} catch (error) {
|
|
535
|
+
setMessage({ tone: "error", text: `${t("errorPrefix")} ${String(error?.message ?? error)}` });
|
|
536
|
+
} finally {
|
|
537
|
+
setBusy(null);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
async function doInstall() {
|
|
542
|
+
if (busy !== null) return;
|
|
543
|
+
setBusy("install");
|
|
544
|
+
try {
|
|
545
|
+
const result = await call("install", {});
|
|
546
|
+
if (result?.ok && result.value?.ok) setMessage({ tone: "ok", text: t("installDone") });
|
|
547
|
+
else setMessage({ tone: "error", text: `${t("installFailed")}: ${result?.error?.message ?? result?.value?.output ?? "unknown"}` });
|
|
548
|
+
} catch (error) {
|
|
549
|
+
setMessage({ tone: "error", text: `${t("installFailed")}: ${String(error?.message ?? error)}` });
|
|
550
|
+
} finally {
|
|
551
|
+
setBusy(null);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
async function reveal(pathValue) {
|
|
556
|
+
try {
|
|
557
|
+
await call("reveal", { path: pathValue });
|
|
558
|
+
} catch {
|
|
559
|
+
/* the OS opener is best effort */
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
async function copy(value) {
|
|
564
|
+
const ok = await copyText(value);
|
|
565
|
+
if (ok) {
|
|
566
|
+
setCopied(true);
|
|
567
|
+
setTimeout(() => setCopied(false), 1800);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
const stepOneGroups = h(
|
|
572
|
+
"div",
|
|
573
|
+
{ className: "dpt-list" },
|
|
574
|
+
groups.map((group) => h(GroupRow, {
|
|
575
|
+
key: group.id,
|
|
576
|
+
group,
|
|
577
|
+
checked: selected[group.id] === true,
|
|
578
|
+
onToggle: toggle,
|
|
579
|
+
t,
|
|
580
|
+
})),
|
|
581
|
+
);
|
|
582
|
+
|
|
583
|
+
return h(
|
|
584
|
+
"div",
|
|
585
|
+
{ className: "dpt-page" },
|
|
586
|
+
h(
|
|
587
|
+
"div",
|
|
588
|
+
{ className: "dpt-head" },
|
|
589
|
+
h("div", { className: "dpt-kicker" }, "DeepSeek Harness"),
|
|
590
|
+
h("div", { className: "dpt-title" }, t("title")),
|
|
591
|
+
h("div", { className: "dpt-sub" }, t("subtitle")),
|
|
592
|
+
),
|
|
593
|
+
h(StepBar),
|
|
594
|
+
|
|
595
|
+
/* ---------------- export ---------------- */
|
|
596
|
+
h(
|
|
597
|
+
"section",
|
|
598
|
+
{ className: "dpt-card", "aria-labelledby": "dpt-export-title" },
|
|
599
|
+
h(
|
|
600
|
+
"div",
|
|
601
|
+
{ className: "dpt-card-head" },
|
|
602
|
+
h("div", null,
|
|
603
|
+
h("div", { className: "dpt-card-title", id: "dpt-export-title" }, t("exportTitle")),
|
|
604
|
+
h("div", { className: "dpt-card-sub" }, t("exportSubtitle")),
|
|
605
|
+
),
|
|
606
|
+
h("span", { className: "dpt-chip" }, phase === "loading" ? "…" : `${selectedCount} / ${groups.length}`),
|
|
607
|
+
),
|
|
608
|
+
phase === "loading" && h("div", { className: "dpt-hint" }, t("optionsLoading")),
|
|
609
|
+
phase !== "loading" && stepOneGroups,
|
|
610
|
+
h(
|
|
611
|
+
"div",
|
|
612
|
+
{ className: "dpt-field" },
|
|
613
|
+
h("label", { className: "dpt-label", htmlFor: "dpt-destination" }, t("destinationLabel")),
|
|
614
|
+
h("input", {
|
|
615
|
+
id: "dpt-destination",
|
|
616
|
+
className: "dpt-input dpt-input--path",
|
|
617
|
+
type: "text",
|
|
618
|
+
value: destination,
|
|
619
|
+
spellCheck: false,
|
|
620
|
+
onChange: (event) => setDestination(event.target.value),
|
|
621
|
+
}),
|
|
622
|
+
h("div", { className: "dpt-hint" }, t("destinationHint")),
|
|
623
|
+
),
|
|
624
|
+
h(
|
|
625
|
+
"div",
|
|
626
|
+
{ className: "dpt-actions" },
|
|
627
|
+
h(
|
|
628
|
+
"button",
|
|
629
|
+
{ type: "button", className: "dpt-btn", "data-tone": "primary", disabled: busy !== null || phase !== "ready", onClick: doExport },
|
|
630
|
+
busy === "export" ? h(Spinner) : null,
|
|
631
|
+
busy === "export" ? t("exporting") : t("exportButton"),
|
|
632
|
+
),
|
|
633
|
+
exported !== null
|
|
634
|
+
? h(
|
|
635
|
+
"button",
|
|
636
|
+
{ type: "button", className: "dpt-btn", onClick: () => reveal(exported.archivePath) },
|
|
637
|
+
t("openFolder"),
|
|
638
|
+
)
|
|
639
|
+
: null,
|
|
640
|
+
),
|
|
641
|
+
exported !== null
|
|
642
|
+
? h(
|
|
643
|
+
"div",
|
|
644
|
+
{ className: "dpt-preview" },
|
|
645
|
+
h("div", { className: "dpt-kv" }, h("span", null, t("archiveSize")), h("span", null, exported.human)),
|
|
646
|
+
h("div", { className: "dpt-mono" }, exported.archivePath),
|
|
647
|
+
h(
|
|
648
|
+
"div",
|
|
649
|
+
{ className: "dpt-actions" },
|
|
650
|
+
h("button", { type: "button", className: "dpt-btn", onClick: () => copy(exported.archivePath) }, copied ? t("copied") : t("copyPath")),
|
|
651
|
+
),
|
|
652
|
+
)
|
|
653
|
+
: null,
|
|
654
|
+
),
|
|
655
|
+
|
|
656
|
+
/* ---------------- import ---------------- */
|
|
657
|
+
h(
|
|
658
|
+
"section",
|
|
659
|
+
{ className: "dpt-card", "aria-labelledby": "dpt-import-title" },
|
|
660
|
+
h(
|
|
661
|
+
"div",
|
|
662
|
+
{ className: "dpt-card-head" },
|
|
663
|
+
h("div", null,
|
|
664
|
+
h("div", { className: "dpt-card-title", id: "dpt-import-title" }, t("importTitle")),
|
|
665
|
+
h("div", { className: "dpt-card-sub" }, t("importSubtitle")),
|
|
666
|
+
),
|
|
667
|
+
h("span", { className: "dpt-chip" }, "03"),
|
|
668
|
+
),
|
|
669
|
+
h(
|
|
670
|
+
"div",
|
|
671
|
+
{ className: "dpt-field" },
|
|
672
|
+
h("label", { className: "dpt-label", htmlFor: "dpt-archive" }, t("archivePathLabel")),
|
|
673
|
+
h("input", {
|
|
674
|
+
id: "dpt-archive",
|
|
675
|
+
className: "dpt-input dpt-input--path",
|
|
676
|
+
type: "text",
|
|
677
|
+
value: archivePath,
|
|
678
|
+
placeholder: t("archivePathPlaceholder"),
|
|
679
|
+
spellCheck: false,
|
|
680
|
+
onChange: (event) => {
|
|
681
|
+
setArchivePath(event.target.value);
|
|
682
|
+
setPreview(null);
|
|
683
|
+
setImported(null);
|
|
684
|
+
},
|
|
685
|
+
}),
|
|
686
|
+
h("div", { className: "dpt-hint" }, t("archivePathHint")),
|
|
687
|
+
),
|
|
688
|
+
h(
|
|
689
|
+
"div",
|
|
690
|
+
{ className: "dpt-actions" },
|
|
691
|
+
h(
|
|
692
|
+
"button",
|
|
693
|
+
{ type: "button", className: "dpt-btn", disabled: busy !== null, onClick: doInspect },
|
|
694
|
+
busy === "inspect" ? h(Spinner) : null,
|
|
695
|
+
busy === "inspect" ? t("inspecting") : t("inspectButton"),
|
|
696
|
+
),
|
|
697
|
+
),
|
|
698
|
+
preview !== null
|
|
699
|
+
? h(
|
|
700
|
+
"div",
|
|
701
|
+
{ className: "dpt-preview" },
|
|
702
|
+
h("div", { className: "dpt-kv" }, h("span", null, t("previewCreated")), h("span", null, preview.manifest.createdAt)),
|
|
703
|
+
h("div", { className: "dpt-kv" }, h("span", null, t("previewHost")), h("span", null, `${preview.manifest.host} · ${preview.manifest.platform ?? ""}`)),
|
|
704
|
+
h("div", { className: "dpt-kv" }, h("span", null, t("previewTotals")), h("span", null, `${preview.manifest.totals?.files ?? "?"} · ${preview.manifest.totals?.human ?? preview.human}`)),
|
|
705
|
+
Array.isArray(preview.manifest.localPlugins) && preview.manifest.localPlugins.length > 0
|
|
706
|
+
? h("div", { className: "dpt-kv" }, h("span", null, t("previewPlugins")), h("span", null, preview.manifest.localPlugins.map((plugin) => plugin.packageName).join(", ")))
|
|
707
|
+
: null,
|
|
708
|
+
h("div", { className: "dpt-divider" }),
|
|
709
|
+
h(
|
|
710
|
+
"label",
|
|
711
|
+
{ className: "dpt-check" },
|
|
712
|
+
h("input", { type: "checkbox", checked: confirmed, onChange: (event) => setConfirmed(event.target.checked) }),
|
|
713
|
+
h("span", null, t("importConfirm")),
|
|
714
|
+
),
|
|
715
|
+
h(
|
|
716
|
+
"div",
|
|
717
|
+
{ className: "dpt-actions" },
|
|
718
|
+
h(
|
|
719
|
+
"button",
|
|
720
|
+
{ type: "button", className: "dpt-btn", "data-tone": "primary", disabled: busy !== null || !confirmed, onClick: doImport },
|
|
721
|
+
busy === "import" ? h(Spinner) : null,
|
|
722
|
+
busy === "import" ? t("importing") : t("importButton"),
|
|
723
|
+
),
|
|
724
|
+
),
|
|
725
|
+
)
|
|
726
|
+
: null,
|
|
727
|
+
imported !== null
|
|
728
|
+
? h(
|
|
729
|
+
"div",
|
|
730
|
+
{ className: "dpt-preview" },
|
|
731
|
+
h("div", { className: "dpt-card-title" }, t("importDone")),
|
|
732
|
+
h("div", { className: "dpt-divider" }),
|
|
733
|
+
h("div", { className: "dpt-grid2" },
|
|
734
|
+
Object.entries(imported.restored ?? {}).map(([key, count]) =>
|
|
735
|
+
count > 0
|
|
736
|
+
? h("div", { className: "dpt-kv", key }, h("span", null, key), h("span", null, String(count)))
|
|
737
|
+
: null,
|
|
738
|
+
),
|
|
739
|
+
),
|
|
740
|
+
imported.backupDir
|
|
741
|
+
? h(
|
|
742
|
+
"div",
|
|
743
|
+
{ className: "dpt-field" },
|
|
744
|
+
h("div", { className: "dpt-kv" }, h("span", null, t("backupNote")), h("span", { className: "dpt-mono" }, imported.backupDir)),
|
|
745
|
+
h("div", { className: "dpt-actions" },
|
|
746
|
+
h("button", { type: "button", className: "dpt-btn", onClick: () => reveal(imported.backupDir) }, t("showBackup")),
|
|
747
|
+
),
|
|
748
|
+
)
|
|
749
|
+
: null,
|
|
750
|
+
h("div", { className: "dpt-status", "data-tone": "warn" }, imported.restartRequired === true ? t("restartNote") : t("noteLabel")),
|
|
751
|
+
imported.install && imported.install.ok === false
|
|
752
|
+
? h("div", { className: "dpt-status", "data-tone": "error" }, `${t("installFailed")}: ${String(imported.install.output ?? "").slice(-400)}`)
|
|
753
|
+
: null,
|
|
754
|
+
imported.needsPnpm === true
|
|
755
|
+
? h(
|
|
756
|
+
"div",
|
|
757
|
+
{ className: "dpt-actions" },
|
|
758
|
+
h("div", { className: "dpt-hint" }, t("installNote")),
|
|
759
|
+
h(
|
|
760
|
+
"button",
|
|
761
|
+
{ type: "button", className: "dpt-btn", disabled: busy !== null, onClick: doInstall },
|
|
762
|
+
busy === "install" ? h(Spinner) : null,
|
|
763
|
+
busy === "install" ? t("installing") : t("installButton"),
|
|
764
|
+
),
|
|
765
|
+
)
|
|
766
|
+
: null,
|
|
767
|
+
)
|
|
768
|
+
: null,
|
|
769
|
+
),
|
|
770
|
+
|
|
771
|
+
message !== null
|
|
772
|
+
? h(Status, { tone: message.tone }, message.text)
|
|
773
|
+
: null,
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
ctx.effect(() => ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
778
|
+
name: "settings.section",
|
|
779
|
+
id: "profile-transfer",
|
|
780
|
+
order: 30,
|
|
781
|
+
label: () => t("nav"),
|
|
782
|
+
locale: NS,
|
|
783
|
+
inject: () => ({ call: callbacks.call, copyText: callbacks.copyText }),
|
|
784
|
+
}, TransferSection)), "profile-transfer: settings section");
|
|
785
|
+
|
|
786
|
+
try {
|
|
787
|
+
window.__DSH_PROFILE_TRANSFER__ = {
|
|
788
|
+
call: callbacks.call,
|
|
789
|
+
open: () => {
|
|
790
|
+
// The settings shell is opened by the user through the sidebar; this
|
|
791
|
+
// hook only exists for diagnostics and automated QA.
|
|
792
|
+
return true;
|
|
793
|
+
},
|
|
794
|
+
};
|
|
795
|
+
} catch {
|
|
796
|
+
/* hardened page */
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
console.info("[profile-transfer] ready");
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
exports.apply = apply;
|
|
803
|
+
exports.inject = inject;
|
|
804
|
+
return module.exports;
|
|
805
|
+
},
|
|
806
|
+
});
|