DSH Desktop development guide
August 27, 2026 ยท View on GitHub
This guide covers local development, validation, patch maintenance, and target-native packaging. For the runtime design, see Architecture. For formal releases, see the release runbook.
Prerequisites
- Node.js 22 or later
- npm
- macOS on Apple Silicon or Intel, or Windows x64
DSH Desktop currently pins @deepseek-ai/dsh@0.1.1-rc.2. Windows packages bundle a target-native Node.js runtime for Harness, while macOS uses an Electron UtilityProcess. Both are independent of the Node.js version used to run development commands.
Local setup
git clone https://github.com/dataelement/dsh-desktop.git
cd dsh-desktop
npm ci
npm run dev
npm ci runs the repository's postinstall hook. It reapplies the tracked patch-package patches, installs DSH brand assets into the pinned Harness frontend, and installs Electron.
Development builds use the separate application name DSH Desktop Dev and the separate user-data directory dsh-desktop-dev, so they do not reuse production DSH Desktop data. Multiple development worktrees still share that development profile by default; avoid running them at the same time when testing profile, plugin, migration, or recovery changes.
Validation
Run the core checks before submitting a change:
npm test
npm run typecheck
npm run build
Static checks are not a substitute for runtime verification. Changes that affect startup, profiles, plugins, native dialogs, updates, mobile access, or packaging should also be exercised through the corresponding real application flow.
To exercise the Cloudflare-to-Pinggy fallback without disrupting the machine's network, start the development app with Cloudflare failure simulation enabled:
DSH_TUNNEL_FORCE_PINGGY=1 npm run dev
Then enable the temporary public tunnel from the phone connection screen. The tunnel status should report pinggy, and the generated URL should use a Pinggy hostname. This variable affects only the process started from that command; omit it on the next launch to restore the normal Cloudflare-first behavior.
Project map
src/main/ Electron main process and application orchestration
src/main/runtime/ Harness process lifecycle and diagnostics
src/main/state/ Profile consistency, repair, recovery, and Safe Mode
src/main/mobile/ Paired phone bridge and optional Cloudflare tunnel
src/main/update/ Installed-build update state and lifecycle
src/preload/ Narrow renderer-to-main IPC and desktop UI seams
src/shared/ Shared contracts and desktop menu definitions
packages/ Bundled desktop support packages
patches/ Reproducible patches for the pinned Harness packages
build/ Packaged HTML, icons, loaders, and Harness entry files
scripts/ Build, signing, metadata, and target verification tools
test/ Unit and source-contract regression coverage
.github/workflows/ Native CI, signing, release, and publication workflows
Maintaining upstream patches
The desktop product intentionally reuses the upstream Harness UI. Desktop-specific provider onboarding, preset transfer, model selection, workspace, branding, and layout changes are captured under patches/ rather than stored as untracked edits in node_modules.
When upgrading Harness:
- Install the intended upstream version.
- Verify the current Settings, Credentials, Provider Directory, workspace, and preset contracts.
- Reapply or rewrite each desktop customization.
- Regenerate the relevant
patch-packagepatches. - Run the full automated suite.
- Start the real app and exercise every affected user flow.
Packaging
Harness includes architecture-specific native dependencies. Build each installer on the operating system and architecture where it will run.
# macOS Apple Silicon, on an Apple Silicon Mac or runner
npm run package:mac:arm64
# macOS Intel, on an Intel Mac or runner
npm run package:mac:x64
# Windows x64 NSIS installer, on a Windows x64 machine or runner
npm run package:win
Do not invoke electron-builder --win from macOS or Linux for a distributable Windows package. The target verification scripts intentionally reject host/target mismatches.
For local unsigned development packages, use the corresponding package:dev:* command. Before handing off a Windows installer, verify that resources/app/node_modules/node/bin/node.exe exists in win-unpacked and require the packaged Windows Harness smoke test to pass.
Formal release artifacts are built, signed, and published by the tag workflow. A local build or pull-request check is not formal release evidence.
Contribution hygiene
- Never include real API keys in issues, logs, screenshots, fixtures, or test data.
- Preserve unrelated worktree changes.
- Keep temporary research, local reports, and internal working documents under the ignored
doc/directory. - Update all localized README files when changing user-visible facts.