picoaide/picoaide-harness--packages-host-desktop ↗★ 9

dsh-plugin-desktop

PicoAide Harness: an Electron shell composed as a DeepSeek Harness Cordis plugin 适合希望以桌面应用方式运行 DSH 的用户,需 Electron 环境与本地构建。

패키지
dsh-plugin-desktop
호환성
미검증
버전
2.7.5-beta.2
라이선스
MIT
최근 업데이트
2026. 9. 16.

같은 패키지 이름의 다른 저장소

설치

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:picoaide/picoaide-harness#517bf0c6b000c32de0f459fe78770c4fb9720c13&path:packages/host/desktop

PicoAide Harness

English | 中文

dsh-plugin-desktop runs DSH in Electron while remaining part of the ordinary Cordis composition. The installed application is named PicoAide Harness. The package provides the dsh-plugin-desktop executable and the dsh-desktop alias; the registered npm package name is the reliable npx entry.

Architecture

The Electron executable is minimal bootstrap code. It acquires the single-instance lock, loads the fixed desktop profile, provides the native runtime capability, and boots the Host Cordis root in the Electron main process. The desktop-shell Host plugin owns the BrowserWindow, navigation policy, settings namespace, and close-versus-quit lifecycle through Cordis effects. The native runtime owns the physical tray, while desktop-shell, desktop-diagnostics, and desktop-updates contribute effect-scoped commands through its ordered item registry. desktop-loop-notify raises native system notifications after an agent loop completes, when the model asks a question, or when a permission approval is pending; clicking a session-bearing notification focuses the window and opens that session.

The product runs the fixed advanced presentation over the existing loopback Web carrier. The profile mounts the ordinary dsh-base and dsh-web-app bundles, the Host binds its HTTP and WebSocket surface to 127.0.0.1 on an ephemeral port, and Electron loads that same-origin page in a sandboxed renderer. There is no Electron-owned plugin roster, preload bridge, or raw Electron API in the renderer.

The desktop package has normal Host and Web Client faces. Its Client face validates the Host-supplied platform markers and installs the advanced layout service and root presentation described below. Third-party Web clients continue to use the ordinary DSH module graph.

The launcher manages exactly one profile, desktop. Its installation-owned prefix is repaired while third-party bundle order is preserved. The launcher inserts its own desktop layer after dsh-web-app for the active generation and never persists that layer in the bundle list. There is no profile selector in the tray and no web profile default; bundled third-party plugins run against the fixed desktop profile.

Bare Cordis plugin imports resolve from the persistent profile. A narrow Node resolve hook applies only to imports issued by @deepseek-ai/cordis-plugin-loader, so profile-local third-party packages and the healed launcher fallback use the same resolution path even when packaged Electron does not expose Node's internal ESM loader.

Before profile preparation and Cordis boot, a packaged macOS or Linux launch runs the configured account shell in interactive login mode and recovers its exported PATH. This repairs the minimal PATH commonly supplied by Finder, LaunchServices, and other graphical launchers. It also fills only missing locale, toolchain, package-manager, and virtual-environment exports from a fixed allowlist; PATH alone always uses the shell value. Recovery supports absolute zsh, bash, and fish paths. Bash follows its standard login behavior, so .bashrc contributes only when a login profile sources it. Windows and unpackaged or development launches skip recovery. An unavailable or unsupported shell, timeout, capture failure, or missing PATH silently retains the inherited process environment.

The capture starts from @deepseek-ai/dsh-subprocess's scrubbedParentEnv(), and captured names pass the same SENSITIVE_ENV_PATTERN and DSH_ENV_PREFIX checks before the fixed allowlist is applied. Credentials, DSH_* values, proxy and SSH-agent settings, and process startup hooks learned only from shell rc files are therefore not imported into Electron. This recovery does not erase values already present in Electron's explicit launch environment. Ordinary DSH subprocesses apply the official scrub again; an explicit child environment may still deliberately add a value.

Plugin authors should use the supported contract imports, lifecycle rules, and adaptation patterns in the Desktop plugin service architecture.

Mode setting and restart boundary

dsh-desktop.mode is fixed to advanced; the setting is accepted for backward compatibility and always reports advanced. The launcher reads the same file resolved by the active @deepseek-ai/dsh-settings-file row before composing a generation. The Host registers the dsh-desktop namespace with the standard settings service. There is no parallel mode value in the profile manifest and no mode switch in the tray.

A committed dsh-desktop.port change requests one orderly restart: the current Cordis tree disposes first, then Electron relaunches only after a successful zero-code shutdown. The application never hot-swaps root slots, native window materials, or Loader rows inside a live renderer generation.

Advanced mode (fixed presentation)

The desktop shell always uses the advanced presentation on every supported platform. After all user patches have been read, the launcher disables the official ui-layout Loader row, keeps the official ui-sidebar and ui-conversation rows enabled, and applies advanced to desktop-shell.

The Cordis row registers native window values during profile activation. The launcher creates the window only after app-boot settles and audits the complete profile, so the first renderer manifest includes the active official, desktop, and third-party client plugins without a Loader-wide wait inside the plugin itself.

On Windows, the launcher pins the browse directory-picker backend and keeps the full in-app directory panel. The desktop build patches that panel with a small system-folder icon whose same-origin route calls Electron's dialog.showOpenDialog; a selected path returns to the panel's existing workspace-adoption flow, while cancellation leaves the panel open. Ordinary browser and remote launches do not receive the desktop bridge. macOS and Linux retain the upstream adaptive chooser.

Windows PowerShell keeps the upstream pwsh-sandbox behavior and Windows ACL confinement in both presentation modes. The launcher generation replaces only that Host provider with the dsh-plugin-desktop/windows-pwsh-sandbox subpath from this same package. For the exact upstream ACL-runner argv, the adapter launches the packaged Electron executable in Node mode through a private trampoline, removes the Node-mode variable before the restricted PowerShell process is created, and delegates all policy and failure handling back to the upstream runner. The desktop deploy root also pins a Yarn patch that combines STARTF_USESHOWWINDOW with the existing STARTF_USESTDHANDLES and SW_HIDE on both native restricted-process paths. This preserves captured stdio without suppressing console allocation and requests a hidden initial show state when Windows creates the GUI-hosted PowerShell process's first console window. It does not use the upstream-incompatible CREATE_NO_WINDOW or CREATE_NEW_CONSOLE flags. Direct danger-full-access PowerShell, macOS, and Linux execution are unchanged; there is no automatic unrestricted fallback when Windows confinement fails.

Advanced mode details

Advanced mode is the fixed desktop presentation for macOS and Windows. After all user patches have been read, the launcher disables the official ui-layout Loader row, keeps the official ui-sidebar and ui-conversation rows enabled, and applies advanced to desktop-shell.

The desktop Client then provides the layout service for its own Cordis-fiber lifetime and registers only the root slot occupant. Its root declares the 0.1.5 child slots — sidebar, the keyed main panel set, rightbar, and the frame-wide shell.overlay list — so the unchanged upstream sidebar, conversation, right-sidebar, and overlay contributions keep their seats. The official sidebar remains the sidebar occupant and continues to declare the workspace browser, settings shell, and additive footer-action seats. The rightbar column is occupied by the official @deepseek-ai/dsh-client-ui-sidebar-right plugin (the vendored third-party sidebar is gone) while the official ui-layout row stays disabled. This preserves its component behavior, collapse animation, and third-party extension points while the desktop package owns only frame geometry and native material.

The advanced theme presenter projects the active upstream theme snapshot onto the document, including color scheme, resolved token values, dark-mode marker, and theme-color metadata. It subscribes to ordinary theme changes and removes only its own projected state when the generation disposes.

For an advanced generation, the Electron adapter also reads the registered ui-theme.preference after Host boot and mirrors its built-in light, dark, or system value into Electron's native appearance before constructing the window. Committed preference changes update the native material while the window is active, and disposal restores the preceding Electron appearance. Client-only third-party theme ids do not change this Host preference.

The desktop sidebar surface scopes the upstream sidebar-fill token to transparent, so the official sidebar and session-list fade reveal the native material without changing their component styles.

On macOS the advanced window uses a transparent hidden-inset title bar, positioned traffic lights, and native sidebar vibrancy. Its 90 CSS-pixel collapsed column centers the official 56-pixel rail below a desktop-owned traffic-light inset. The sidebar surface itself is non-draggable; a desktop-owned transparent 32 CSS-pixel strip to the right of the traffic lights supplies its window drag target. A separate caption row reserves 20 CSS pixels above the complete main and rightbar surfaces while exposing another transparent 32 CSS-pixel drag target. Buttons, links, inputs, dialogs, and contributions that explicitly declare app-region: no-drag remain interactive; a custom pointer target placed within the top 32 pixels must declare the same exclusion. On Windows the official sidebar keeps compatibility geometry: 56 pixels collapsed, 280 pixels by default when expanded, and the same upstream transition behavior, while its transparent surface reveals Mica. The window uses a hidden title bar with native controls, transparent overlay, Mica background material, shadow, rounded corners, and a thick resizable frame. Electron exposes the system-drawn Mica material on Windows 11 22H2 and later. A desktop-owned 32 CSS-pixel caption row spans the Windows main and rightbar columns; the complete upstream slot surfaces start below that row, so official and third-party header contributions keep their ordinary relative layout without element-specific caption offsets. The right Sidebar panel is positioned against the frame (push) or the viewport (fullscreen) rather than its own column, so the desktop shell applies that band to the panel directly: the panel strip carries the surface's own controls, which would otherwise render inside the band and under the native window buttons. On Linux the same advanced client layout runs, but the window uses the standard system frame because there is no platform-native Mica or hidden-inset chrome.

Development

This package is managed by the Yarn workspace at the repository root. The sibling deepseek-harness/ checkout remains an independent upstream pnpm project and is not part of the Yarn workspace. Install and verify PicoAide Harness from the repository root:

yarn install
yarn check

The check verifies that every required first-party peer in the production graph is declared by the desktop deploy root. Headless Loader smokes activate the launcher-owned desktop row and a profile-local third-party row, then boot the published Web profile and inspect its loopback root and client manifest. Unit and type tests cover the fixed desktop composition, restart fencing, client environment validation, desktop layout state, and platform-native window options.

Start the desktop application explicitly when a graphical session is available:

yarn dev

dev builds before launching. It does not require a separate manual build.

The headless-safe launcher surfaces can be exercised without importing or starting Electron:

node lib/bin.js --help
node lib/bin.js --version

Plugin workflow

Manage any profile with the ordinary DSH command:

dsh plugin --profile desktop add third-party-plugin
dsh plugin --profile desktop remove third-party-plugin
dsh plugin --profile desktop update

The application runs the fixed desktop profile. There is no profile selector in the tray, so the forms below always target that profile; an explicit --profile remains authoritative when invoking dsh from an external shell.

dshmarket@1.2.3 is not preinstalled and is not a dependency of PicoAide Harness. That release still resolves a profile from config/argv and starts dsh plugin through private child-process code; its package exports no runner injection seam. A later compatible release must retain its existing CLI fallback under ordinary DSH. In addition, the 1.2.3 source repository and npm tarball contain no complete MIT license text or copyright notice, so that version does not pass the bundled-redistribution gate. User-directed installation of a third-party package is separate from Desktop embedding it in the application archive or installer.

See Plugin services for authors for required injection, optional Desktop adaptation, TypeScript examples, cancellation, and fallback guidance.

The package can then be launched from npm with:

npx dsh-plugin-desktop

Launching from the command line

The package installs two equivalent commands, dsh-desktop and dsh-plugin-desktop. Both launch the packaged Electron launcher (lib/main.js) when invoked without arguments.

  • Global install — npm install -g dsh-plugin-desktop installs the electron peer automatically, and dsh-desktop then starts the application against the default DSH home:
    dsh-desktop
    
  • Inside a profile — after dsh plugin --profile add dsh-plugin-desktop, the command lives in the profile's node_modules/.bin. pnpm does not install the electron peer automatically; add it when you want the command to launch:
    dsh plugin --profile  add electron
    
    Native build approvals (node-pty, koffi, electron, and others) follow pnpm's usual allowBuilds rules.
  • Electron missing — the command prints a short installation guide instead of failing with a module error.

Booting a profile that is composed with the desktop shell under an ordinary dsh invocation (without the launcher's desktopRuntime service) prints a reminder telling you to start it with dsh-desktop or from the packaged application; the shell registers nothing in that case.

A third-party Host plugin only needs its normal dsh.bundle patch. A plugin with browser UI also publishes the normal dsh.client metadata with platform: "web" and an exported ./client artifact. The upstream Web client module graph discovers it; Electron does not require a separate client build or a desktop-specific registration API. Advanced-mode contributions must target services and slots that exist in that explicit composition rather than assuming the official layout or sidebar occupant owns them.

Desktop operations

Packaged macOS and Windows applications query the GitHub Releases API 60 seconds after startup and every six hours after a completed check. Each no-cache request has a 15-second deadline and shares one in-flight operation with the Check for Updates… tray command. The response is accepted only when it contains canonical stable Semantic Versioning. Background network, HTTP, timeout, invalid-response, equal-version, and older-version outcomes