From a57234de1442ae58823a56ffe7590e3e36e730ae Mon Sep 17 00:00:00 2001 From: nekomona Date: Thu, 20 Aug 2026 18:41:36 +0800 Subject: [PATCH] fix: keep the stock directoryPicker seam active in the desktop composition DSH Desktop disabled the stock directory-picker row (the Koffi-based worker can exit before reporting a result inside packaged Electron) and inserted a standalone client surface. That removed ctx.directoryPicker from the host, so every host-side consumer failed: host.pickDirectory returned directory-picker-unavailable, and community plugins reading the seam broke (observed with dsh-remote 0.5.10: its local-pick endpoint surfaced "cannot get property \"directoryPicker\" without inject"). The premise does not hold: verified on a packaged Windows v0.3.0 build, the native dialog worker spawns, reports, and services aborts correctly from inside the Harness child (a real pick through pickNativeDirectory() resolved the selected path). Keep the composition stock instead of re-implementing the seam: - build/dsh-desktop.patch.yml: drop the disable row and the client-surface insert. The stock auto row from dsh-web-app mounts the native backend and its client surface, so host.pickDirectory, plugins reading the seam, and the stock flow all work unmodified. - The Electron-dialog preload bridge and the client-ui patch stay unchanged: the client surface keeps using the parented Electron dialog. Verified: full suite 153 passing, typecheck and build clean, and the native pick channel confirmed live on an installed v0.3.0 build. --- build/dsh-desktop.patch.yml | 13 ++++--------- test/directory-picker.test.ts | 7 ++++--- test/release.test.ts | 4 ++-- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/build/dsh-desktop.patch.yml b/build/dsh-desktop.patch.yml index 34c24083..b3af2e59 100644 --- a/build/dsh-desktop.patch.yml +++ b/build/dsh-desktop.patch.yml @@ -1,13 +1,8 @@ -# DSH Desktop delegates directory selection to Electron's system dialog. Keep -# the renderless client surface, but do not load the Koffi-based Host worker: -# on Windows it can exit before reporting a result inside packaged Electron. -- id: directory-picker - disabled: true - +# Keep the stock directory-picker (auto) row active: the native backend +# serves ctx.directoryPicker, so host-side consumers (host.pickDirectory, +# plugins reading the seam) work unmodified. The client surface keeps its +# Electron-dialog bridge via the client-ui patch in patches/. - insert: - - id: directory-picker-electron-desktop-surface - name: '@deepseek-ai/dsh-client-ui-directory-picker-native' - # DSH Desktop owns the fixed-target dsh-market installer and its lightweight # settings entry. After dshmarket is installed and Harness restarts, the # community plugin replaces the placeholder with its complete market UI. diff --git a/test/directory-picker.test.ts b/test/directory-picker.test.ts index a545f5c4..e4b1075e 100644 --- a/test/directory-picker.test.ts +++ b/test/directory-picker.test.ts @@ -26,11 +26,12 @@ describe('desktop Electron directory picker', () => { ) }) - it('keeps only the client surface and removes the crashing Host worker', async () => { + it('keeps the stock picker composition: the seam comes from the stock auto row', async () => { const desktopPatch = await readFile('build/dsh-desktop.patch.yml', 'utf8') - expect(desktopPatch).toContain("name: '@deepseek-ai/dsh-client-ui-directory-picker-native'") - expect(desktopPatch).not.toContain("name: '@deepseek-ai/dsh-host-directory-picker-native'") + // No picker rows at all - the stock auto row mounts the native backend. + expect(desktopPatch).not.toMatch(/id:\s*directory-picker/) + expect(desktopPatch).not.toContain('dsh-client-ui-directory-picker-native') }) it('captures the client bridge as a reproducible dependency patch', async () => { diff --git a/test/release.test.ts b/test/release.test.ts index feb37b80..8e8a4e0a 100644 --- a/test/release.test.ts +++ b/test/release.test.ts @@ -114,9 +114,9 @@ describe('GitHub release contract', () => { expect(splash).toContain('Starting DSH Desktop') expect(splash).toContain('src="dsh-loader.gif"') expect(splash).not.toContain('class="track"') - expect(patch).toMatch(/id: directory-picker\r?\n disabled: true/) + expect(patch).not.toMatch(/id:\s*directory-picker/) expect(patch).not.toContain("name: '@deepseek-ai/dsh-host-directory-picker-native'") - expect(patch).toContain("name: '@deepseek-ai/dsh-client-ui-directory-picker-native'") + expect(patch).not.toContain("name: '@deepseek-ai/dsh-client-ui-directory-picker-native'") }) it('routes manual restarts through the active plugin recovery flow', async () => {