diff --git a/apps/desktop/README.i18n.yaml b/apps/desktop/README.i18n.yaml index f39ddd9f5a..257e3d74d7 100644 --- a/apps/desktop/README.i18n.yaml +++ b/apps/desktop/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write apps/desktop/README.md -README.md: 27988b195c6b3611cda3d5fc04b8a33a4e67a951 -README.zh.md: d3bf48afc9ccfc7b10d90f1e96df5f8a83aedff4 +README.md: 139af236e8be8bcb3dfc1a27f58cd168fd9d3af1 +README.zh.md: 287fe08a1f3e8bf1ae41d00805a485972b2f795f diff --git a/apps/desktop/README.md b/apps/desktop/README.md index 27988b195c..139af236e8 100644 --- a/apps/desktop/README.md +++ b/apps/desktop/README.md @@ -6,6 +6,10 @@ The desktop application is an Electron shell around the complete dsh Web applica ## Key technical decisions +The original artwork lives in `resources/icon.png` and `resources/icon.svg`; platform adaptations retain the whale and gradients in `resources/icon-windows.*` and `resources/icon-macos.*`. Export each platform SVG as a transparent 1024×1024 PNG. Electron-builder generates the multi-size ICO for the Windows application, installer, and uninstaller ([Windows icon requirements](https://learn.microsoft.com/en-us/windows/apps/design/iconography/app-icon-construction)). The installation pages use matching artwork in both themes; the uninstaller's welcome and finish pages share `installer/assets/uninstaller-sidebar.png`, converted to a 164×314 BMP during preparation. + +The macOS PNG uses an inset rounded background for legacy ICNS packaging, with representations up to 1024 pixels. It is a flattened icon, not an Icon Composer document. Apple's [app icon guidance](https://developer.apple.com/design/human-interface-guidelines/app-icons) describes unmasked layers for Icon Composer; those inputs require a separate macOS export and must not reuse the rounded ICNS artwork. Verify Finder and Dock appearance on supported macOS versions before release. + | Decision | Why | Direct consequence | |---|---|---| | Release identity | The shell API, Web client, backend, and plugin graph are qualified as one combination; independent versions would create untested combinations and ambiguous update availability. | Electron and `@deepseek-ai/dsh` always have the same exact version. A dsh upgrade is a Desktop release, even when the shell code is unchanged. | diff --git a/apps/desktop/README.zh.md b/apps/desktop/README.zh.md index d3bf48afc9..287fe08a1f 100644 --- a/apps/desktop/README.zh.md +++ b/apps/desktop/README.zh.md @@ -6,6 +6,10 @@ ## 关键技术决策 +设计师原稿位于 `resources/icon.png` 和 `resources/icon.svg`;平台适配保留鲸鱼与渐变,分别位于 `resources/icon-windows.*` 和 `resources/icon-macos.*`。将各平台 SVG 导出为透明的 1024×1024 PNG。electron-builder 为 Windows 应用、安装程序和卸载程序生成多尺寸 ICO([Windows 图标要求](https://learn.microsoft.com/en-us/windows/apps/design/iconography/app-icon-construction))。安装页面在两种主题下使用匹配的图案;卸载程序的欢迎和完成页共用 `installer/assets/uninstaller-sidebar.png`,准备阶段将其转换为 164×314 BMP。 + +macOS PNG 使用带留白的圆角底板,供传统 ICNS 打包使用,包含最高 1024 像素的表示。它是扁平图标,并非 Icon Composer 文档。Apple 的[应用图标指南](https://developer.apple.com/design/human-interface-guidelines/app-icons)要求向 Icon Composer 提供未遮罩的图层;这些输入需要在 macOS 上单独导出,不能复用已做圆角的 ICNS 图案。发布前须在支持的 macOS 版本中验收 Finder 和 Dock 的显示效果。 + | 决策 | 原因 | 直接结果 | |---|---|---| | 发布身份 | 桌面壳 API、Web 客户端、后端与插件依赖图作为一个组合完成验证;独立版本会产生未经验证的组合,并让更新可用性含糊不清。 | Electron 与 `@deepseek-ai/dsh` 始终使用同一精确版本。即使桌面壳代码不变,升级 dsh 也必须发布新 Desktop 版本。 | diff --git a/apps/desktop/electron-builder.config.mjs b/apps/desktop/electron-builder.config.mjs index 7f08bd22d0..f5266fb7f6 100644 --- a/apps/desktop/electron-builder.config.mjs +++ b/apps/desktop/electron-builder.config.mjs @@ -91,6 +91,7 @@ export function createElectronBuilderConfig( { from: join(buildPaths.dsh, 'node_modules'), to: 'dsh/node_modules' }, ], mac: { + icon: fileURLToPath(new URL('./resources/icon-macos.png', import.meta.url)), category: 'public.app-category.developer-tools', identity: macOSSigning?.signingIdentity, forceCodeSigning: true, @@ -133,6 +134,7 @@ export function createElectronBuilderConfig( ) }, win: { + icon: fileURLToPath(new URL('./resources/icon-windows.png', import.meta.url)), forceCodeSigning: !unsigned, signtoolOptions: { sign: windowsSigner, @@ -145,6 +147,8 @@ export function createElectronBuilderConfig( target: ['AppImage'], }, nsis: { + installerSidebar: join(buildPaths.root, 'installer-ui', 'uninstaller-sidebar.bmp'), + uninstallerSidebar: join(buildPaths.root, 'installer-ui', 'uninstaller-sidebar.bmp'), include: fileURLToPath(new URL('./scripts/installer.nsh', import.meta.url)), oneClick: false, perMachine: false, diff --git a/apps/desktop/installer/assets/brand-2x.png b/apps/desktop/installer/assets/brand-2x.png index 7499a5074d..7cf467d766 100644 Binary files a/apps/desktop/installer/assets/brand-2x.png and b/apps/desktop/installer/assets/brand-2x.png differ diff --git a/apps/desktop/installer/assets/brand-dark-2x.png b/apps/desktop/installer/assets/brand-dark-2x.png index 80634a78ca..35c7648644 100644 Binary files a/apps/desktop/installer/assets/brand-dark-2x.png and b/apps/desktop/installer/assets/brand-dark-2x.png differ diff --git a/apps/desktop/installer/assets/brand-dark.png b/apps/desktop/installer/assets/brand-dark.png index 8adc1439bc..bb0bf87883 100644 Binary files a/apps/desktop/installer/assets/brand-dark.png and b/apps/desktop/installer/assets/brand-dark.png differ diff --git a/apps/desktop/installer/assets/brand.png b/apps/desktop/installer/assets/brand.png index 98d1d9796c..e8b64ca003 100644 Binary files a/apps/desktop/installer/assets/brand.png and b/apps/desktop/installer/assets/brand.png differ diff --git a/apps/desktop/installer/assets/uninstaller-sidebar.png b/apps/desktop/installer/assets/uninstaller-sidebar.png new file mode 100644 index 0000000000..6546dfb014 Binary files /dev/null and b/apps/desktop/installer/assets/uninstaller-sidebar.png differ diff --git a/apps/desktop/resources/icon-macos.png b/apps/desktop/resources/icon-macos.png new file mode 100644 index 0000000000..f96a4f3c60 Binary files /dev/null and b/apps/desktop/resources/icon-macos.png differ diff --git a/apps/desktop/resources/icon-macos.svg b/apps/desktop/resources/icon-macos.svg new file mode 100644 index 0000000000..36d9068cc7 --- /dev/null +++ b/apps/desktop/resources/icon-macos.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/desktop/resources/icon-windows.png b/apps/desktop/resources/icon-windows.png new file mode 100644 index 0000000000..02bc5931d3 Binary files /dev/null and b/apps/desktop/resources/icon-windows.png differ diff --git a/apps/desktop/resources/icon-windows.svg b/apps/desktop/resources/icon-windows.svg new file mode 100644 index 0000000000..4ab25b9e70 --- /dev/null +++ b/apps/desktop/resources/icon-windows.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/desktop/resources/icon.png b/apps/desktop/resources/icon.png new file mode 100644 index 0000000000..d7b136f2bd Binary files /dev/null and b/apps/desktop/resources/icon.png differ diff --git a/apps/desktop/resources/icon.svg b/apps/desktop/resources/icon.svg new file mode 100644 index 0000000000..ae3e8c2c2c --- /dev/null +++ b/apps/desktop/resources/icon.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/desktop/scripts/prepare-windows-installer.ps1 b/apps/desktop/scripts/prepare-windows-installer.ps1 index 39ea55b9ad..43584ddc8e 100644 --- a/apps/desktop/scripts/prepare-windows-installer.ps1 +++ b/apps/desktop/scripts/prepare-windows-installer.ps1 @@ -29,7 +29,7 @@ if ($TestProgress) { if ($LASTEXITCODE -ne 0) { throw 'Progress timeline regression failed.' } } Add-Type -AssemblyName System.Drawing -foreach ($asset in @('brand', 'brand-2x', 'brand-dark', 'brand-dark-2x')) { +foreach ($asset in @('brand', 'brand-2x', 'brand-dark', 'brand-dark-2x', 'uninstaller-sidebar')) { $image = [Drawing.Image]::FromFile((Join-Path $installerRoot "assets/$asset.png")) try { $bitmap = [Drawing.Bitmap]::new($image.Width, $image.Height, [Drawing.Imaging.PixelFormat]::Format24bppRgb)